ActiveDirectory和aspnetsqlprovider共用一個provider

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Configuration.Provider;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
using System.Linq;
using System.Web.Security;
using App_Code.DAL;

namespace App_Code.BLL
{
    public class ActiveDirectoryRoleProvider : RoleProvider
    {
        private const string ERROR_ACTIVEDIRECTORY_QUERY = "error query Active Directory.";
        private const string ERROR_ROLE_NOT_FOUND = "role not found.";
        private const string ERROR_CONFIG_NOT_FOUND = "config not find.";
        private const string ERROR_CONNSTR_NOT_FOUND = "can not find 'connectionString'.";

        private const string ALL_GROUPS =
            "(&(objectCategory=group)(|(groupType=-2147483646)(groupType=-2147483644)(groupType=-2147483640)))";

        //private const string GROUPS = "(&(objectClass=group)(cn={0}))";
        private const string GROUPS = "(&(objectClass=group)(cn=*emite*))";
        private const string USERS = "(&(objectClass=user)(sAMAccountName={0}))";
        public override string ApplicationName { get; set; }

        private static string getDomain()
        {
            return ConfigurationManager.ConnectionStrings["ADMembershipProvider"].ConnectionString.Replace("LDAP://", "");
        }

        private static DirectoryEntry getRoot()
        {
            return new DirectoryEntry(ConfigurationManager.ConnectionStrings["ADMembershipProvider"].ConnectionString);
        }

        private static string[] Search(String filter, String field)
        {
            var res = new List<string>();
            var searcher = new DirectorySearcher {SearchRoot = getRoot(), Filter = filter};
            searcher.PropertiesToLoad.Clear();
            searcher.PropertiesToLoad.Add(field);
            searcher.PageSize = 500;
            try
            {
                using (SearchResultCollection results = searcher.FindAll())
                {
                    foreach (SearchResult result in results)
                    {
                        int resultCount = result.Properties[field].Count;
                        for (int c = 0; c < resultCount; c++)
                            res.Add(result.Properties[field][c].ToString());
                    }
                }
            }
            catch (Exception ex)
            {
                throw new ProviderException(ERROR_ACTIVEDIRECTORY_QUERY, ex);
            }
            return res.Count > 0 ? res.ToArray() : new string[0];
        }

        public override void Initialize(string name, NameValueCollection config)
        {
            base.Initialize(name, config);
        }

        public override bool IsUserInRole(string username, string roleName)
        {
            string[] roles = GetRolesForUser(username);
            return roles.Any(role => role.Equals(roleName, StringComparison.OrdinalIgnoreCase));
        }

        public override string[] GetRolesForUser(string username)
        {
            var allRoles = new List<string>();
            var root = new DirectoryEntry(ConfigurationManager.ConnectionStrings["ADMembershipProvider"].ConnectionString);
            var searcher = new DirectorySearcher(root)
                               {
                                   Filter = String.Format("(SAMAccountName={0})", username)
                               };
            searcher.PropertiesToLoad.Add("memberof");
            SearchResult result = searcher.FindOne();
            if (result != null && !string.IsNullOrEmpty(result.Path))
            {
                DirectoryEntry user = result.GetDirectoryEntry();
                PropertyValueCollection groups = user.Properties["memberof"];
                string[] Rgroups = GetAllRoles();
                foreach (string path in groups)
                {
                    string[] parts = path.Split(',');
                    if (parts.Length > 0)
                    {
                        foreach (string part in parts)
                        {
                            string[] p = part.Split('=');
                            if (p[0].Equals("cn", StringComparison.OrdinalIgnoreCase))
                            {
                                foreach (string group in Rgroups)
                                {
                                    if (group == p[1])
                                    {
                                        string[] r = p[1].Split('-');
                                        if (r[1] == "Admin")
                                        {
                                            string isnullRole = "select count(1) from Users where loginname='" + username +
                                                                "' and role is not null";
                                            int confirm = DbConnector.GenerateScalar_Int(isnullRole);
                                            if (confirm == 0)
                                            {
                                                string upd = "update Users set role='admin' where loginname='" + username + "'";
                                                DbConnector.runSql(upd);
                                            }
                                            allRoles.Add("admin");
                                        }
                                        else if (r[1] == "Users")
                                        {
                                            string isnullRole = "select count(1) from Users where loginname='" + username +
                                                                "' and role is not null";
                                            int confirm = DbConnector.GenerateScalar_Int(isnullRole);
                                            if (confirm == 0)
                                            {
                                                string upd = "update Users set role='user' where loginname='" + username + "'";
                                                DbConnector.runSql(upd);
                                                allRoles.Add("user");
                                            }
                                            else
                                            {
                                                string leader = "select count(1) from Users where loginname='" +
                                                                username + "' and role='leader'";
                                                int confleader = DbConnector.GenerateScalar_Int(leader);
                                                if(confleader>0)
                                                    allRoles.Add("leader");
                                                else
                                                    allRoles.Add("user");
                                            }
                                           
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            //if fails to retrieve roles, try from sql db
            string[] userdomains = allRoles.Count == 0 ? EmiteData.GetAllRoles(username) : allRoles.ToArray();
            return userdomains;
        }

        public override void CreateRole(string roleName)
        {
            throw new NotImplementedException();
        }

        public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
        {
            throw new NotImplementedException();
        }

        public override bool RoleExists(string roleName)
        {
            return GetAllRoles().Any(role => roleName == role);
        }

        public override void AddUsersToRoles(string[] usernames, string[] roleNames)
        {
            throw new NotImplementedException();
        }

        public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
        {
            throw new NotImplementedException();
        }

        public override string[] GetUsersInRole(string roleName)
        {
            if (!RoleExists(roleName))
                throw new ProviderException(String.Format(ERROR_ROLE_NOT_FOUND, roleName));

            var results = new List<string>();
            using (var context = new PrincipalContext(ContextType.Domain, null, getDomain()))
            {
                try
                {
                    GroupPrincipal p = GroupPrincipal.FindByIdentity(context, IdentityType.SamAccountName, roleName);
                    PrincipalSearchResult<Principal> users = p.GetMembers(true);
                    foreach (UserPrincipal user in users)
                        results.Add(user.SamAccountName);
                }
                catch (Exception ex)
                {
                    throw new ProviderException(ERROR_ACTIVEDIRECTORY_QUERY, ex);
                }
            }

            return results.ToArray();
        }

        public override string[] GetAllRoles()
        {
            var results = new List<string>();
            string[] roles = Search(GROUPS, "samAccountName");
            foreach (string role in roles)
                results.Add(role);
            return results.ToArray();
        }

        public override string[] FindUsersInRole(string roleName, string usernameToMatch)
        {
            if (!RoleExists(roleName))
                throw new ProviderException(String.Format(ERROR_ROLE_NOT_FOUND, roleName));

            var results = new List<string>();
            using (var context = new PrincipalContext(ContextType.Domain, null, getDomain()))
            {
                try
                {
                    using (
                        GroupPrincipal p = GroupPrincipal.FindByIdentity(context, IdentityType.SamAccountName, roleName)
                        )
                    {
                        PrincipalSearchResult<Principal> users = p.GetMembers(true);
                        foreach (UserPrincipal user in users)
                            if (user.SamAccountName.IndexOf(usernameToMatch) > 0)
                                results.Add(user.SamAccountName);
                    }
                }
                catch (Exception ex)
                {
                    throw new ProviderException(ERROR_ACTIVEDIRECTORY_QUERY, ex);
                }
            }
            return results.ToArray();
        }
    }
}

 

 

在對用戶進行驗證角色的時候,由於存在兩種provider,而且默認的只有一個,所以需要在默認的rolemanager裏寫能共用的provider。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章