Skip To Content

使用 ASP.NET 设置自定义标识存储

ArcGIS Server 可通过自定义标识存储中的用户和角色获得安全保护。为此,ArcGIS Server 支持 ASP.NET 成员资格和角色提供程序。

要使用 ASP.NET 配置自定义标识存储,请执行以下步骤:

配置自定义 ASP.NET 提供程序后,可以在管理器中查看其内容,并使用自定义存储中的角色来设置 Web 服务上的权限。

为 ArcGIS Server 实施一个自定义的 ASP.NET 提供程序

要通过自定义标识存储中的用户来确保 ArcGIS Server 的安全性,必须开发一个实施以下方法的 .NET framework 4.5.1 ASP.NET 成员提供程序:

  • FindUsersByName
  • GetAllUsers
  • GetUser
  • ValidateUser

要通过自定义标识存储中的角色来确保 ArcGIS Server 的安全性,必须开发一个实施以下方法的 .NET framework 4.5.1 ASP.NET 角色提供程序:

  • GetAllRoles
  • GetRolesForUser
  • GetUsersInRole

注:

实施自定义 ASP.NET 提供程序时,建议的方法是将其在 ArcGIS Server 中以只读的标识存储形式进行显示。如果您希望通过 ArcGIS Server 创建和修改用户/角色信息,则需要在自定义的 ASP.NET 提供程序中实施其他方法,正如以下实现示例所示。

在 ArcGIS Server 上部署自定义提供程序

  1. 在 .dll 文件中构建自定义提供程序,并将其复制到托管 ArcGIS Server 的计算机中。
  2. 在 GAC 中安装自定义提供程序 .dll。

    示例:gacutil /i MyCustomProvider.dll

配置 ArcGIS Server 以使用自定义提供程序

要将 ArcGIS Server 配置为使用自定义 ASP.NET 提供程序,必须指定 ASP.NET 提供程序的类型属性。作为可选项,还可指定提供程序所需的任意运行时属性,例如用户凭据等。

  1. 打开“ArcGIS Server 管理员目录”并登录。
  2. 单击安全性 > 配置 > 更新标识存储
  3. 以 JSON 格式输入用户存储配置。该语法为:
    {
    	"type": "ASP_NET",
    	"class": "{Membership provider's type attribute value}",
    	"properties": {
    		"Property One": "value",
       ....
    		"Property X": "value"
    	}
    }
  4. 以 JSON 格式输入角色存储配置。该语法为:
    {
    	"type": "ASP_NET",	"class": "{Role provider's type attribute value}",	"properties": {
    		"Property One": "value",   ....		"Property X": "value"
    	}
    }
  5. 单击更新保存配置。

实现示例

以下是使用 C# 语言的 ArcGIS Server 的 ASP.NET 成员和角色提供程序的实现示例。示例使用的是可修改的 ASP.NET 提供程序。建议的方法是将提供程序在 ArcGIS Server 中以只读的标识存储形式进行显示。

示例成员提供程序

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration.Provider;
using System.Linq;
using System.Text;
using System.Web.Security;
using System.Web.Hosting;
using System.Web.Management;
using System.Web;
using System.Security.Permissions;
using System.Xml;
using System.IO; 
namespace CustomProvider
{
    public class XmlMembershipProvider : MembershipProvider
    {
        private string _appName = null;
        private string _providerName = null;
        private string _userStore;
        public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
        {
            if (config == null)
                throw new ArgumentNullException("config");
            if (String.IsNullOrEmpty(name))
                name = "CustomProvider.XmlMembershipProvider";
            base.Initialize(name, config);
            _providerName = name;
            string path = config["FileName"];
            if (String.IsNullOrEmpty(path))
                path = "C:\\temp\\IdentityStore.xml";
            else
                _userStore = path;     
            FileIOPermission permission = new FileIOPermission(FileIOPermissionAccess.Write,_userStore);
            
            permission.Demand();
        }
        public override string ApplicationName
        {
            get
            {
                return _appName;
            }
            set
            {
                _appName = value;
            }
        }
        public override bool ChangePassword(string username, string oldPassword, string newPassword)
        {
            throw new NotImplementedException();
        }
        public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
        {
            return true;
        }
        public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
        {
            MembershipUser newUser = new MembershipUser(
                _providerName,
                username,
                null,
                email,
                "Secret Question",
                username,
                true,
                false,
                DateTime.Now,               // creationDate
                DateTime.Now,               // lastLoginDate
                DateTime.Now,               // lastActivityDate
                DateTime.Now,               // lastPasswordChangedDate
                new DateTime(2000, 1, 1)    // lastLockoutDate
                );
            XmlDocument _usersList = ReadUsersFromStore();
            XmlNode newUserNode = _usersList.CreateNode(XmlNodeType.Element, "User", null);
            XmlNode newUserInfoNode = _usersList.CreateElement("UserName");
            newUserInfoNode.InnerText = username;
            newUserNode.AppendChild(newUserInfoNode);
            newUserInfoNode = _usersList.CreateElement("Password");
            newUserInfoNode.InnerText = password;
            newUserNode.AppendChild(newUserInfoNode);
            newUserInfoNode = _usersList.CreateElement("FullName");
            newUserInfoNode.InnerText = username;
            newUserNode.AppendChild(newUserInfoNode);
            newUserInfoNode = _usersList.CreateElement("Email");
            newUserInfoNode.InnerText = email;
            newUserNode.AppendChild(newUserInfoNode);
            newUserInfoNode = _usersList.CreateElement("Roles");
            newUserNode.AppendChild(newUserInfoNode);
            _usersList.DocumentElement.AppendChild(newUserNode);
            _usersList.Save(_userStore);
                  
            status = MembershipCreateStatus.Success;
            return newUser;
            
        }
        public override bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            XmlDocument _usersList = ReadUsersFromStore();
            XmlNode nodeToDelete = _usersList.SelectSingleNode(string.Format("//*[UserName=\"{0}\"]", username));
            if (nodeToDelete != null)
            {
                _usersList.FirstChild.RemoveChild(nodeToDelete);
                _usersList.Save(_userStore);
                return true;
            }
            else
                return false;
        }
        public override bool EnablePasswordReset
        {
            get { return true; }
        }
        public override bool EnablePasswordRetrieval
        {
            get { return true; }
        }
        public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }
        public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            MembershipUserCollection usersColl = new MembershipUserCollection();
            XmlNodeList matchingNodes = null;
            XmlDocument _usersList = ReadUsersFromStore();
            matchingNodes = _usersList.SelectNodes(string.Format("//*[contains(UserName,\"{0}\")]", usernameToMatch));
            totalRecords = 0;
            if (matchingNodes != null && matchingNodes.Count != 0)
            {
                totalRecords = matchingNodes.Count;
                foreach (XmlNode node in matchingNodes)
                {
                    MembershipUser newUser = new MembershipUser(
                        _providerName,
                        node["UserName"].InnerText,
                        null,
                        node["Email"].InnerText,
                        "",
                        node["UserName"].InnerText,
                        true,
                        false,
                        DateTime.Now,               // creationDate
                        DateTime.Now,               // lastLoginDate
                        DateTime.Now,               // lastActivityDate
                        DateTime.Now,               // lastPasswordChangedDate
                        new DateTime(2000, 1, 1)    // lastLockoutDate
                        );
                    usersColl.Add(newUser);
                }
            }
            return usersColl;
        }
        public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
        {
            MembershipUserCollection usersColl = new MembershipUserCollection();
            XmlDocument _usersList = ReadUsersFromStore();
            XmlNodeList userNodes = _usersList.GetElementsByTagName("User");
            foreach (XmlNode node in userNodes)
            {
                MembershipUser newUser = new MembershipUser(
                    _providerName,
                    node["UserName"].InnerText,
                    null,
                    node["Email"].InnerText,
                    "Secret Question",
                    node["UserName"].InnerText,
                    true,
                    false,
                    DateTime.Now,               // creationDate
                    DateTime.Now,               // lastLoginDate
                    DateTime.Now,               // lastActivityDate
                    DateTime.Now,               // lastPasswordChangedDate
                    new DateTime(2000, 1, 1)    // lastLockoutDate
                    );
                usersColl.Add(newUser);                 
            }
            totalRecords = userNodes.Count;
            return usersColl;                  
        }
        public override int GetNumberOfUsersOnline()
        {
            throw new NotImplementedException();
        }
        public override string GetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }
        public override MembershipUser GetUser(string username, bool userIsOnline)
        {
            XmlDocument _usersList = ReadUsersFromStore();
            MembershipUser user = null;
            XmlNode node = _usersList.SelectSingleNode(string.Format("//*[UserName=\"{0}\"]", username));
            if (node != null)
            {
                user = new MembershipUser(
                    _providerName,
                    node["UserName"].InnerText,
                    null,
                    node["Email"].InnerText,
                    "Secret Question",
                    node["UserName"].InnerText,
                    true,
                    false,
                    DateTime.Now,               // creationDate
                    DateTime.Now,               // lastLoginDate
                    DateTime.Now,               // lastActivityDate
                    DateTime.Now,               // lastPasswordChangedDate
                    new DateTime(2000, 1, 1)    // lastLockoutDate
                    );
            }
            return user;
        }
        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {
            throw new NotImplementedException();
        }
        public override string GetUserNameByEmail(string email)
        {
            throw new NotImplementedException();
        }
        public override int MaxInvalidPasswordAttempts
        {
            get { throw new NotImplementedException(); }
        }
        public override int MinRequiredNonAlphanumericCharacters
        {
            get { throw new NotImplementedException(); }
        }
        public override int MinRequiredPasswordLength
        {
            get { throw new NotImplementedException(); }
        }
        public override int PasswordAttemptWindow
        {
            get { throw new NotImplementedException(); }
        }
        public override MembershipPasswordFormat PasswordFormat
        {
            get { throw new NotImplementedException(); }
        }
        public override string PasswordStrengthRegularExpression
        {
            get { throw new NotImplementedException(); }
        }
        public override bool RequiresQuestionAndAnswer
        {
            get { throw new NotImplementedException(); }
        }
        public override bool RequiresUniqueEmail
        {
            get { throw new NotImplementedException(); }
        }
        public override string ResetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }
        public override bool UnlockUser(string userName)
        {
            throw new NotImplementedException();
        }
        public override void UpdateUser(MembershipUser user)
        {
            XmlDocument _usersList = ReadUsersFromStore();
            String username = user.UserName;
            XmlNode nodeToUpdate = _usersList.SelectSingleNode(string.Format("//*[UserName=\"{0}\"]", username));
            if (nodeToUpdate != null)
            {
                nodeToUpdate["Email"].InnerText = user.Email;
                _usersList.Save(_userStore);
            }
            
        }
        public override bool ValidateUser(string username, string password)
        {
            XmlDocument _usersList = ReadUsersFromStore();
            XmlNode node = _usersList.SelectSingleNode(string.Format("//*[UserName=\"{0}\"]", username));
            if (node != null && username.Equals(node["UserName"].InnerText) && password.Equals(node["Password"].InnerText))
                return true;
            else
                return false;
        }
        private XmlDocument ReadUsersFromStore()
        {
            XmlDocument _usersList = new XmlDocument();
            _usersList.Load(_userStore);
            return _usersList;
        }
    } /* XmlFileMembershipProvider */
}

示例角色提供程序

using System;
using System.Collections.Generic;
using System.Collections;
using System.Collections.Specialized;
using System.Configuration.Provider;
using System.Linq;
using System.Text;
using System.Web.Security;
using System.Web.Hosting;
using System.Web.Management;
using System.Web;
using System.Security.Permissions;
using System.Xml;
using System.IO; 
namespace CustomProvider
{
    public class XmlRoleProvider : RoleProvider    {
        private string _appName = null;
        private string _providerName = null;
        private string _roleStore = null;
        XmlDocument _xmlRoleList = null;
        public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)        {
            if (config == null)                throw new ArgumentNullException("config");
            if (String.IsNullOrEmpty(name))                name = "CustomProvider.XmlRoleProvider";
            base.Initialize(name, config);
            _providerName = name;
            string path = config["FileName"];
            if (String.IsNullOrEmpty(path))                path = "C:\\temp\\IdentityStore.xml";
            else                _roleStore = path;
            FileIOPermission permission = new FileIOPermission(FileIOPermissionAccess.Write, _roleStore);
            permission.Demand();
        }
        public override void AddUsersToRoles(string[] usernames, string[] roleNames)        {
            XmlDocument userRoleDoc = ReadUserRolesFromStore();
            foreach (string user in usernames)            {
                XmlNode userRoleNode = userRoleDoc.SelectSingleNode(string.Format("//*[UserName=\"{0}\"]", user));
                String roleList = userRoleNode["Roles"].InnerText;
                foreach (string role in roleNames)                {
                    if(roleList.Equals(""))                        roleList += role;
                    else                        roleList += "," + role;
                }
                userRoleNode.RemoveChild(userRoleNode.LastChild);
                XmlNode newRoleListNode = userRoleDoc.CreateElement("Roles");
                newRoleListNode.InnerText = roleList;
                userRoleNode.AppendChild(newRoleListNode);
            }
            userRoleDoc.Save(_roleStore);
        }
        public override string ApplicationName        {
            get            {
                return _appName;
            }
            set            {
                _appName = value;
            }
        }
        public override void CreateRole(string roleName)        {
            ReadRolesFromStore();
            XmlNode newRoleNode = _xmlRoleList.CreateNode(XmlNodeType.Element, "Role", null);
            XmlNode newUserInfoNode = _xmlRoleList.CreateElement("RoleName");
            newUserInfoNode.InnerText = roleName;
            newRoleNode.AppendChild(newUserInfoNode);
            _xmlRoleList.DocumentElement.AppendChild(newRoleNode);
            _xmlRoleList.Save(_roleStore);
        }
        public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)        {             ReadRolesFromStore();
            XmlNode nodeToDelete = _xmlRoleList.SelectSingleNode(string.Format("//*[RoleName=\"{0}\"]", roleName));
            if (nodeToDelete != null)            {
                _xmlRoleList.FirstChild.RemoveChild(nodeToDelete);
                _xmlRoleList.Save(_roleStore);
                return true;
            }
            else                return false;
        }
        public override string[] FindUsersInRole(string roleName, string usernameToMatch)        {
            throw new NotImplementedException();
        }
        public override string[] GetAllRoles()        {
            ArrayList roleArrayList = ReadRolesFromStore();
            return (string[])roleArrayList.ToArray(typeof(string));
        }
        public override string[] GetRolesForUser(string username)        {
            XmlDocument xmlUserRolesList = ReadUserRolesFromStore();
            XmlNode userRoleNode = xmlUserRolesList.SelectSingleNode(string.Format("//*[UserName=\"{0}\"]", username));
            String[] roleList = userRoleNode["Roles"].InnerText.Split(',');
            if (roleList[0] == "")                return new string[0];
            else                return roleList;
        }
        public override string[] GetUsersInRole(string roleName)        {
            ArrayList userList = new ArrayList();
            XmlDocument xmlUserRolesList = ReadUserRolesFromStore();
            XmlNodeList userRoleNodes = xmlUserRolesList.GetElementsByTagName("User");
            if (userRoleNodes != null)            {
                int numRoles = userRoleNodes.Count;
                foreach(XmlNode node in userRoleNodes) {
                    String[] roleList = node["Roles"].InnerText.Split(',');
                    foreach (string item in roleList)                    {
                        if (item.Equals(roleName))                        {
                            String username = node["UserName"].InnerText;
                            userList.Add(username);
                            break;
                        }
                    }
                }
            }
            return (string[])userList.ToArray(typeof(string));
        }
        public override bool IsUserInRole(string username, string roleName)        {
            throw new NotImplementedException();
        }
        public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)        {
            XmlDocument userRoleDoc = ReadUserRolesFromStore();
            foreach (string user in usernames)            {
                XmlNode userRoleNode = userRoleDoc.SelectSingleNode(string.Format("//*[UserName=\"{0}\"]", user));
                ArrayList roleList = new ArrayList();
                roleList.AddRange(userRoleNode["Roles"].InnerText.Split(','));
                foreach (string role in roleNames)                {
                    if (roleList.Contains(role))                        roleList.Remove(role);
                }
                userRoleNode.RemoveChild(userRoleNode.LastChild);
                XmlNode newRoleListNode = userRoleDoc.CreateElement("Roles");
                if( roleList.Count > 0 )                newRoleListNode.InnerText = string.Join(",", (string[])roleList.ToArray(Type.GetType("System.String")));
                userRoleNode.AppendChild(newRoleListNode);
            }
            userRoleDoc.Save(_roleStore);
        }
        public override bool RoleExists(string roleName)        {
            throw new NotImplementedException();
        }
        private ArrayList ReadRolesFromStore()        {
            _xmlRoleList = new XmlDocument();
            _xmlRoleList.Load(_roleStore);
            XmlNodeList roleNodes = _xmlRoleList.GetElementsByTagName("Role");
            ArrayList roleArrayList = null;
            if (roleNodes != null)            {
                roleArrayList = new ArrayList();
                foreach (XmlNode node in roleNodes)                {
                    roleArrayList.Add( node["RoleName"].InnerText);
                }
            }
            return roleArrayList;
        }
        private XmlDocument ReadUserRolesFromStore()        {
            XmlDocument xmlUserRolesList = new XmlDocument();
            xmlUserRolesList.Load(_roleStore);
            return xmlUserRolesList;
        }
    }
}

示例标识存储配置 JSON

用户存储 JSON

{
  "type": "ASP_NET",  "class": "CustomProvider.XmlMembershipProvider,CustomProvider,Version=1.0.0.0,Culture=Neutral,PublicKeyToken=b02390eb7f2c02c4",  "properties": {
    "FileName": "C:\\arcgisserver\\identitystore\\IdentityStore.xml"
  }
}

角色存储 JSON

{
  "type": "ASP_NET",  "class": "CustomProvider.XmlRoleProvider,CustomProvider,Version=1.0.0.0,Culture=Neutral,PublicKeyToken=b02390eb7f2c02c4",  "properties": {
    "FileName": "C:\\arcgisserver\\identitystore\\IdentityStore.xml"
  }
}

示例标识存储

<IdentityStore>
  <User>
    <UserName>amy</UserName>
    <Password>amy</Password>
    <FullName>amy</FullName>
    <Email>amy@amy.amy</Email>
    <Roles>admins</Roles>
  </User>
  <Role>
    <RoleName>admins</RoleName>
  </Role>
</IdentityStore>