【发布时间】:2010-06-02 12:14:27
【问题描述】:
我需要访问 Active Directory 以获取有关客户所属组的信息。我的项目是一个使用 C# 的 ASP.Net MVC 应用程序。我以前从未针对 Active Directory 进行过编程,因此需要一些建议,了解什么是最好的入门方式、使用什么安全模型来访问信息,或许还可以给我一些好的教程。
【问题讨论】:
标签: c# asp.net-mvc security active-directory
我需要访问 Active Directory 以获取有关客户所属组的信息。我的项目是一个使用 C# 的 ASP.Net MVC 应用程序。我以前从未针对 Active Directory 进行过编程,因此需要一些建议,了解什么是最好的入门方式、使用什么安全模型来访问信息,或许还可以给我一些好的教程。
【问题讨论】:
标签: c# asp.net-mvc security active-directory
由于您使用的是 MVC,因此您可以访问 .NET 3.5 中的新 System.DirectoryServices.AccountManagement 命名空间。这些类应该优先于 DirectoryServices 本身中的旧类,因为它们更易于使用。有几个问题在 3.5 中尚未解决(例如,在查询组时限制 1500 个成员),但我确信这些问题已在 .NET 4.0 中得到修复。对于大多数任务,新类都运行良好。
using (var context = new PrincipalContext( ContextType.Domain ))
{
using (var user = UserPrincipal.FindByIdentity( context, "username" ))
{
var groups = user.GetAuthorizationGroups();
...
}
}
【讨论】:
使用System.DirectoryServices 命名空间访问AD。
两个最重要的类是:
假设您的域是:MyIntranet.MyCompany.com
然后,您必须创建DirectoryEntry 类的根实例:
DirectoryEntry root = new DirectoryEntry("LDAP://DC=MyIntranet,DC=MyCompany,DC=com");
在 AD 中搜索特定组或用户的出现时:
DirectorySearcher searcher = new DirectorySearcher();
searcher.SearchRoot = root;
searcher.SearchScope = SearchScope.Subtree;
假设您要查找名为:AnyUser1 的用户名,DirectorySearcher.Filter 应如下所示:
searcher.Filter = string.Format("(&(objectCategory=person)(objectClass=user)(sAMAccountName={0})", "AnyUser1");
然后,通过SearchResult类得到结果如下:
bool userFound = false;
SearchResult foundUser = null;
try {
foundUser = searcher.FindOne(); // You might as well use the FindAll() method if you expect more then one result.
userFound = foundUser != null;
} catch(Exception) {
throw;
}
if (!userFound)
return;
DirectoryEntry user = foundUser.GetDirectoryEntry();
然后,您可以通过 memberOf 属性获取该用户所属的组:
user.Properties("memberOf").Value
如需全面了解,请参阅此 CodeProject 文章:How to (almost) everything in Active Directory。
以及属性列表:Mapping Between IADsUser Properties and Active Directory Attributes。
编辑#1
如果您使用模拟,您可能会考虑为您的应用程序设置一些参数,例如 DefaultRootDomain、DefaultUserName 和 DefaultPassword,然后在实例化你的根 DirectoroEntry 时使用它们。
public static class AdHelper {
public static string DefaultRootDse {
get {
return Properties.Settings.Default.DefaultRootDomain;
}
}
private static string DefaultUserName {
get {
return Properties.Settings.Default.DefaultUserName;
}
}
private static string DefaultPassword {
get {
return Properties.Settings.Default.DefaultPassword;
}
}
public static DirectoryEntry RootDse {
get {
if (_rootDse == null)
_rootDse = new DirectoryEntry(DefaultRootDse, DefaultUserName, DefaultPassword);
return _rootDse;
}
}
private static DirectoryEntry _rootDse;
}
【讨论】:
DirectoryEntry 类和 AD 假定当前连接的用户(假设是 Windows 会话。我不知道如何通过 Web 应用程序使用它)。
如果您拥有 .NET 3.5 或可以升级到它 - 请务必使用 System.DirectoryServices.AccountManagement 中的新功能!
有关详细信息和快速入门,请参阅 MSDN 杂志上的精彩介绍文章 Managing Directory Security Principals in the .NET Framework 3.5。
【讨论】:
为什么不是 System.Web.Security?它也存在于 2.0 框架中
即: http://msdn.microsoft.com/en-us/library/system.web.security.activedirectorymembershipprovider(v=vs.85) 现在在框架 4.0 中: http://msdn.microsoft.com/en-us/library/system.web.security.activedirectorymembershipprovider(v=vs.100)
【讨论】: