2010-10-14 99 views
0

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

这是我的问题:大多数用户属于超过20个AD组。我从来没有与AD合作过,所以我不知道这是否异常高,但我知道AD需要5-6秒才能响应我对用户组列表的请求,所以我真的想要最大限度地减少我不得不请求群组的次数,特别是因为峰值使用将涉及大约200-300个用户在几个小时内点击该页面。

此应用程序有三个独立的控制组:用户,审阅者和管理员。每个组在其各自的网站文件夹中都有自己的页面集合。每个文件夹都有一个入口点页面(即,如果在会话中找不到相关数据,其他文件夹将重定向到此页面)。只有在IsPostback == false的情况下,此页面才会检查有效的AD组,并从Session对象中的条目读取以确保用户具有正确的访问权限。所以(最后),这里是我的问题:我是以最有效的方式处理这个问题,还是忽略了一些简单的选择?

回答

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; 
    } 
} 

或者即使你仍想喜欢使用ennumeration一部分,为什么不ennumerate只能在特定的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/

+0

谢谢!这正是我现在正在做的 - 我的老板重写了他的组员成员函数,通过正确地轮询Active Directory来加快结果。我不认为我在问题中指定了这一点,但他的组员成员函数最初将所有用户的组从AD中移出并遍历它们以检查所请求的组,这就是为什么我决定将所有组拉回一次,并从他的团体成员函数中分别检查我的三个小组。 – jwiscarson 2010-11-02 22:53:22

相关问题