我正在开发一个基于Web的项目,用户在经过Active Directory身份验证后可以访问该项目。我的老板控制对Active Directory的访问,并希望使用组来处理我正在编写的应用程序的身份验证。他还为我提供了一个连接类,以便从AD(登录名和活动目录组)中提取所需的信息,因此这不是一个问题。
这是我的问题:大多数用户属于20多个AD组。我之前从未使用AD,所以我不知道这是否异常高,但我知道AD需要5-6秒才能响应我对用户组列表的请求,所以我真的< / strong>希望尽量减少我要求群组的次数,特别是因为峰值使用将导致大约200-300名用户在几小时内访问该页面。
此应用程序有三个独立的控制组:用户,审阅者和管理员。每个组在其各自的网站文件夹中都有自己的页面集合。每个文件夹都有一个入口点页面(即,如果在会话中找不到相关数据,其他文件夹将重定向到此页面)。此页面仅在IsPostback == false
时检查AD组的有效性,并从Session对象中的条目读取以确保用户具有适当的访问权限。
所以(最后),这是我的问题:我是否以最有效的方式处理这个问题,或者我在这里忽略了一些简单的替代方案?
答案 0 :(得分: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