Tas*_*sto 103 c# asp.net active-directory
我使用此代码来获取当前用户的组.但我想手动给用户,然后得到他的组.我怎样才能做到这一点?
using System.Security.Principal;
public ArrayList Groups()
{
ArrayList groups = new ArrayList();
foreach (IdentityReference group in System.Web.HttpContext.Current.Request.LogonUserIdentity.Groups)
{
groups.Add(group.Translate(typeof(NTAccount)).ToString());
}
return groups;
}
Run Code Online (Sandbox Code Playgroud)
mar*_*c_s 155
如果您使用的是.NET 3.5或更高版本,则可以使用新的System.DirectoryServices.AccountManagement
(S.DS.AM)命名空间,这使得它比以前容易得多.
阅读所有相关内容:在.NET Framework 3.5中管理目录安全性主体
更新:旧的MSDN杂志文章不再在线,不幸的是 - 你需要从微软下载2008年1月的MSDN杂志的CHM并阅读那里的文章.
基本上,您需要拥有"主要上下文"(通常是您的域),用户主体,然后您可以非常轻松地获得其组:
public List<GroupPrincipal> GetGroups(string userName)
{
List<GroupPrincipal> result = new List<GroupPrincipal>();
// establish domain context
PrincipalContext yourDomain = new PrincipalContext(ContextType.Domain);
// find your user
UserPrincipal user = UserPrincipal.FindByIdentity(yourDomain, userName);
// if found - grab its groups
if(user != null)
{
PrincipalSearchResult<Principal> groups = user.GetAuthorizationGroups();
// iterate over all groups
foreach(Principal p in groups)
{
// make sure to add only group principals
if(p is GroupPrincipal)
{
result.Add((GroupPrincipal)p);
}
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
这就是全部!您现在拥有用户所属的授权组的结果(列表) - 迭代它们,打印出它们的名称或您需要做的任何事情.
更新:为了访问未在UserPrincipal
对象上显示的某些属性,您需要深入了解底层DirectoryEntry
:
public string GetDepartment(Principal principal)
{
string result = string.Empty;
DirectoryEntry de = (principal.GetUnderlyingObject() as DirectoryEntry);
if (de != null)
{
if (de.Properties.Contains("department"))
{
result = de.Properties["department"][0].ToString();
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
更新#2:似乎不应该太难将这两段代码放在一起....但是好的 - 这就是:
public string GetDepartment(string username)
{
string result = string.Empty;
// if you do repeated domain access, you might want to do this *once* outside this method,
// and pass it in as a second parameter!
PrincipalContext yourDomain = new PrincipalContext(ContextType.Domain);
// find the user
UserPrincipal user = UserPrincipal.FindByIdentity(yourDomain, username);
// if user is found
if(user != null)
{
// get DirectoryEntry underlying it
DirectoryEntry de = (user.GetUnderlyingObject() as DirectoryEntry);
if (de != null)
{
if (de.Properties.Contains("department"))
{
result = de.Properties["department"][0].ToString();
}
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
Mic*_*use 56
GetAuthorizationGroups()
找不到嵌套组.要真正获取给定用户的所有组是(包括嵌套组)的成员,请尝试以下操作:
using System.Security.Principal
private List<string> GetGroups(string userName)
{
List<string> result = new List<string>();
WindowsIdentity wi = new WindowsIdentity(userName);
foreach (IdentityReference group in wi.Groups)
{
try
{
result.Add(group.Translate(typeof(NTAccount)).ToString());
}
catch (Exception ex) { }
}
result.Sort();
return result;
}
Run Code Online (Sandbox Code Playgroud)
我使用try/catch
是因为我在一个非常大的AD中有200个组中的2个有一些例外,因为一些SID不再可用.(该Translate()
调用执行SID - >名称转换.)
Big*_*jim 16
首先,GetAuthorizationGroups()是一个很棒的函数,但不幸的是有两个缺点:
因此,我编写了一个小函数来替换具有更好性能和错误安全性的GetAuthorizationGroups().它只使用索引字段进行一次LDAP调用.如果您需要的属性多于组名("cn"属性),则可以轻松扩展它.
// Usage: GetAdGroupsForUser2("domain\user") or GetAdGroupsForUser2("user","domain")
public static List<string> GetAdGroupsForUser2(string userName, string domainName = null)
{
var result = new List<string>();
if (userName.Contains('\\') || userName.Contains('/'))
{
domainName = userName.Split(new char[] { '\\', '/' })[0];
userName = userName.Split(new char[] { '\\', '/' })[1];
}
using (PrincipalContext domainContext = new PrincipalContext(ContextType.Domain, domainName))
using (UserPrincipal user = UserPrincipal.FindByIdentity(domainContext, userName))
using (var searcher = new DirectorySearcher(new DirectoryEntry("LDAP://" + domainContext.Name)))
{
searcher.Filter = String.Format("(&(objectCategory=group)(member={0}))", user.DistinguishedName);
searcher.SearchScope = SearchScope.Subtree;
searcher.PropertiesToLoad.Add("cn");
foreach (SearchResult entry in searcher.FindAll())
if (entry.Properties.Contains("cn"))
result.Add(entry.Properties["cn"][0].ToString());
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
Oli*_*ver 10
在AD中,每个用户都有一个属性memberOf
.这包含他所属的所有组的列表.
这是一个小代码示例:
// (replace "part_of_user_name" with some partial user name existing in your AD)
var userNameContains = "part_of_user_name";
var identity = WindowsIdentity.GetCurrent().User;
var allDomains = Forest.GetCurrentForest().Domains.Cast<Domain>();
var allSearcher = allDomains.Select(domain =>
{
var searcher = new DirectorySearcher(new DirectoryEntry("LDAP://" + domain.Name));
// Apply some filter to focus on only some specfic objects
searcher.Filter = String.Format("(&(&(objectCategory=person)(objectClass=user)(name=*{0}*)))", userNameContains);
return searcher;
});
var directoryEntriesFound = allSearcher
.SelectMany(searcher => searcher.FindAll()
.Cast<SearchResult>()
.Select(result => result.GetDirectoryEntry()));
var memberOf = directoryEntriesFound.Select(entry =>
{
using (entry)
{
return new
{
Name = entry.Name,
GroupName = ((object[])entry.Properties["MemberOf"].Value).Select(obj => obj.ToString())
};
}
});
foreach (var item in memberOf)
{
Debug.Print("Name = " + item.Name);
Debug.Print("Member of:");
foreach (var groupName in item.GroupName)
{
Debug.Print(" " + groupName);
}
Debug.Print(String.Empty);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
我的解决方案:
UserPrincipal user = UserPrincipal.FindByIdentity(new PrincipalContext(ContextType.Domain, myDomain), IdentityType.SamAccountName, myUser);
List<string> UserADGroups = new List<string>();
foreach (GroupPrincipal group in user.GetGroups())
{
UserADGroups.Add(group.ToString());
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
179231 次 |
最近记录: |