【问题标题】:Active Directory group authentication performanceActive Directory 组身份验证性能
【发布时间】:2010-11-03 06:47:30
【问题描述】:

我正在开发一个基于 Web 的项目,用户在通过 Active Directory 的身份验证后可以访问该项目。我的老板控制对 Active Directory 的访问,并希望使用组来处理对我正在编写的应用程序的身份验证。他还为我提供了一个连接类以从 AD 中提取我需要的信息(登录名和活动目录组),所以这不是问题。

这是我的问题:大多数用户属于 20 多个 AD 组。我以前从未使用过 AD,所以我不知道这是否异常高,但我知道 AD 需要 5-6 秒才能响应我对用户组列表的请求,所以我真的 想要尽量减少我必须请求群组的次数,特别是因为高峰使用将涉及大约 200-300 名用户在几个小时内访问该页面。

此应用程序具有三个独立的控制组:用户、审阅者和管理员。每个组在各自的网站文件夹中都有自己的页面集合。每个文件夹都有一个入口点页面(即,如果在 Session 中没有找到相关数据,其他文件夹将重定向到该页面)。此页面仅在 IsPostback == false 时检查有效的 AD 组,并从 Session 对象中的条目中读取以确保用户具有正确的访问权限。

所以(最后),这是我的问题:我是在以最有效的方式处理这个问题,还是在这里忽略了一些简单的替代方案?

【问题讨论】:

    标签: asp.net active-directory


    【解决方案1】:

    对于您上面的问题,是的,AD 有时会有点慢取决于负载,但与其专注于为什么不更改逻辑而不是枚举所有用户组,为什么不检查用户是否是组成员。在这里实现它是代码

    /// <summary>
    /// Checks if user is a member of a given group
    /// </summary>
    /// <param name="sUserName">The user you want to validate</param>
    /// <param name="sGroupName">The group you want to check the membership of the user</param>
    /// <returns>Returns true if user is a group member</returns>
    public bool IsUserGroupMember(string sUserName, string sGroupName)
    {
        UserPrincipal oUserPrincipal = GetUser(sUserName);
        GroupPrincipal oGroupPrincipal = GetGroup(sGroupName);
    
        if (oUserPrincipal == null || oGroupPrincipal == null)
        {
            return oGroupPrincipal.Members.Contains(oUserPrincipal);
        }
        else
        {
            return false;
        }
    }
    

    如果您仍然希望使用枚举部分,甚至更好,为什么不只枚举特定 OU 上的组而不是像这样的整个目录

    /// <summary>
    /// Gets a list of the users group memberships
    /// </summary>
    /// <param name="sUserName">The user you want to get the group memberships</param>
    /// <param name="sOU">The OU you want to search user groups from</param>
    /// <returns>Returns an arraylist of group memberships</returns>
    public ArrayList GetUserGroups(string sUserName, string sOU)
    {
    
        ArrayList myItems = new ArrayList();
        UserPrincipal oUserPrincipal = GetUser(sUserName);
    
        PrincipalSearchResult<Principal> oPrincipalSearchResult = oUserPrincipal.GetGroups(GetPrincipalContext(sOU));
    
        foreach (Principal oResult in oPrincipalSearchResult)
        {
            myItems.Add(oResult.Name);
        }
        return myItems;
    
    }
    /// <summary>
    /// Gets the principal context on specified OU
    /// </summary>
    /// <param name="sOU">The OU you want your Principal Context to run on</param>
    /// <returns>Retruns the PrincipalContext object</returns>
    public PrincipalContext GetPrincipalContext(string sOU)
    {
        PrincipalContext oPrincipalContext = new PrincipalContext(ContextType.Domain, sDomain, sOU, ContextOptions.SimpleBind, sServiceUser, sServicePassword);
        return oPrincipalContext;
    }        
    

    最后请注意,如果您更看重安全性而不是速度,那么我不建议使用IsPostback == false,这样如果某个用户的安全组成员身份发生任何更改,那么您将能够在下一次更好地捕获它过程。

    有关 AD 方法的完整实现,请参阅此处 如果您使用的是 .Net 2.0

    http://anyrest.wordpress.com/2010/02/01/active-directory-objects-and-c/

    或者如果您使用的是 .Net 3.5 或 4.0

    http://anyrest.wordpress.com/2010/06/28/active-directory-c/

    【讨论】:

    • 谢谢!这正是我现在正在做的——我的老板重写了他的组成员功能,以通过正确轮询 Active Directory 来加快结果。我不认为我在问题中指定了这一点,但他的组成员功能最初将所有用户的组从 AD 中拉出并遍历它们以检查请求的组,这就是为什么我决定将所有组拉一次,并从他的群组成员功能中分别查看我的三个群组。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-02
    • 2014-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-14
    • 1970-01-01
    相关资源
    最近更新 更多