查看用户是否属于 C# + Asp.net 中的 Active Directory 组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2188954/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
See if user is part of Active Directory group in C# + Asp.net
提问by mike_h
I need a way to see if a user is part of an active directory group from my .Net 3.5 asp.net c# application.
我需要一种方法来查看用户是否属于我的 .Net 3.5 asp.net c# 应用程序中的活动目录组。
I am using the standard ldap authentication example off of msdn but I don't really see how to check against a group.
我正在使用 msdn 的标准 ldap 身份验证示例,但我真的不知道如何检查组。
回答by BC.
回答by Mick Walker
You could try the following code:
你可以试试下面的代码:
public bool Check_If_Member_Of_AD_Group(string username, string grouptoCheck, string domain, string ADlogin, string ADpassword)
{
? ?
? ? try {
? ? ? ?
? ? ? ? string EntryString = null;
? ? ? ? EntryString = "LDAP://" + domain;
? ? ? ?
? ? ? ? DirectoryEntry myDE = default(DirectoryEntry);
? ? ? ?
? ? ? ? grouptoCheck = grouptoCheck.ToLower();
? ? ? ?
? ? ? ?
? ? ? ? myDE = new DirectoryEntry(EntryString, ADlogin, ADpassword);
? ? ? ?
? ? ? ? DirectorySearcher myDirectorySearcher = new DirectorySearcher(myDE);
? ? ? ?
? ? ? ? myDirectorySearcher.Filter = "sAMAccountName=" + username;
? ? ? ?
? ? ? ? myDirectorySearcher.PropertiesToLoad.Add("MemberOf");
? ? ? ?
? ? ? ? SearchResult myresult = myDirectorySearcher.FindOne();
? ? ? ?
? ? ? ? int NumberOfGroups = 0;
? ? ? ?
? ? ? ? NumberOfGroups = myresult.Properties["memberOf"].Count - 1;
? ? ? ?
? ? ? ? string tempString = null;
? ? ? ?
? ? ? ? while ((NumberOfGroups >= 0)) {
? ? ? ? ? ?
? ? ? ? ? ? tempString = myresult.Properties["MemberOf"].Item[NumberOfGroups];
? ? ? ? ? ? tempString = tempString.Substring(0, tempString.IndexOf(",", 0));
? ? ? ? ? ?
? ? ? ? ? ? tempString = tempString.Replace("CN=", "");
? ? ? ? ? ?
? ? ? ? ? ? tempString = tempString.ToLower();
? ? ? ? ? ? tempString = tempString.Trim();
? ? ? ? ? ?
? ? ? ? ? ? if ((grouptoCheck == tempString)) {
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? }
? ? ? ? ? ?
? ? ? ? ? ? ? ?
? ? ? ? ? ? NumberOfGroups = NumberOfGroups - 1;
? ? ? ? }
? ? ? ?
? ? ? ? ? ?
? ? ? ? return false;
? ? }
? ? catch (Exception ex) {
? ? ? ?
? ? ? ? System.Diagnostics.Debugger.Break();
? ? }
? ? //HttpContext.Current.Response.Write("Error: <br><br>" & ex.ToString)
}
回答by Nick Craver
With 3.5 and System.DirectoryServices.AccountManagementthis is a bit cleaner:
使用 3.5 和System.DirectoryServices.AccountManagement这会更干净一点:
public List<string> GetGroupNames(string userName)
{
var pc = new PrincipalContext(ContextType.Domain);
var src = UserPrincipal.FindByIdentity(pc, userName).GetGroups(pc);
var result = new List<string>();
src.ToList().ForEach(sr => result.Add(sr.SamAccountName));
return result;
}
回答by Dave Markle
Nick Craver's solution doesn't work for me in .NET 4.0. I get an error about an unloaded AppDomain. Instead of using that, I used this (we only have one domain). This will check groups of groups as well as direct group membership.
Nick Craver 的解决方案在 .NET 4.0 中对我不起作用。我收到有关卸载的 AppDomain 的错误消息。我没有使用它,而是使用了它(我们只有一个域)。这将检查组组以及直接组成员身份。
using System.DirectoryServices.AccountManagement;
using System.Linq;
...
using (var ctx = new PrincipalContext(ContextType.Domain, yourDomain)) {
using (var grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, yourGroup)) {
bool isInRole = grp != null &&
grp
.GetMembers(true)
.Any(m => m.SamAccountName == me.Identity.Name.Replace(yourDomain + "\", ""));
}
}
回答by Brandon Johnson
The code below will work in .net 4.0
下面的代码将在 .net 4.0 中工作
private static string[] GetGroupNames(string userName)
{
List<string> result = new List<string>();
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "YOURDOMAIN"))
{
using (PrincipalSearchResult<Principal> src = UserPrincipal.FindByIdentity(pc, userName).GetGroups(pc))
{
src.ToList().ForEach(sr => result.Add(sr.SamAccountName));
}
}
return result.ToArray();
}
回答by Bill Daugherty
Brandon Johnson, loved it, I used what you had, but made the following change:
布兰登约翰逊,喜欢它,我使用了你所拥有的,但做了以下更改:
private static string[] GetGroupNames(string domainName, string userName)
{
List<string> result = new List<string>();
using (PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, domainName))
{
using (PrincipalSearchResult<Principal> src = UserPrincipal.FindByIdentity(principalContext, userName).GetGroups(principalContext))
{
src.ToList().ForEach(sr => result.Add(sr.SamAccountName));
}
}
return result.ToArray();
}
回答by Terry Tsay
It depends on what you mean by if a user is in an AD group. In AD, groups can be a Security group or Distribution group. Even for security groups, it depends on if groups like "Domain Users" or "Users" need to be included in the membership check.
如果用户在 AD 组中,这取决于您的意思。在 AD 中,组可以是安全组或通讯组。即使对于安全组,这也取决于是否需要将“域用户”或“用户”等组包含在成员资格检查中。
IsUserInSecurityGroup will only check for security groups and will work for Primary Group kind of groups like "Domain Users" and "Users", and not distribution groups. It will also solve the issue with nested groups. IsUserInAllGroup will also check for Distribution groups, but I am not sure if you would run into permission issues. If you do, use a service account that is in WAAG (See MSDN)
IsUserInSecurityGroup 将只检查安全组,并将适用于“域用户”和“用户”等主要组类型的组,而不是通讯组。它还将解决嵌套组的问题。IsUserInAllGroup 还将检查通讯组,但我不确定您是否会遇到权限问题。如果这样做,请使用 WAAG 中的服务帐户(请参阅 MSDN)
The reason I am not using UserPrincipal.GetAuthorizedGroups() is because it has a lot of issues, such as requiring the calling account to be in WAAG and requiring there isn't an entry in SidHistory (See David Thomas' comment)
我不使用 UserPrincipal.GetAuthorizedGroups() 的原因是因为它有很多问题,例如要求调用帐户在 WAAG 中并且要求 SidHistory 中没有条目(请参阅 David Thomas 的评论)
public bool IsUserInSecurityGroup(string user, string group)
{
return IsUserInGroup(user, group, "tokenGroups");
}
public bool IsUserInAllGroup(string user, string group)
{
return IsUserInGroup(user, group, "tokenGroupsGlobalAndUniversal");
}
private bool IsUserInGroup(string user, string group, string groupType)
{
var userGroups = GetUserGroupIds(user, groupType);
var groupTokens = ParseDomainQualifiedName(group, "group");
using (var groupContext = new PrincipalContext(ContextType.Domain, groupTokens[0]))
{
using (var identity = GroupPrincipal.FindByIdentity(groupContext, IdentityType.SamAccountName, groupTokens[1]))
{
if (identity == null)
return false;
return userGroups.Contains(identity.Sid);
}
}
}
private List<SecurityIdentifier> GetUserGroupIds(string user, string groupType)
{
var userTokens = ParseDomainQualifiedName(user, "user");
using (var userContext = new PrincipalContext(ContextType.Domain, userTokens[0]))
{
using (var identity = UserPrincipal.FindByIdentity(userContext, IdentityType.SamAccountName, userTokens[1]))
{
if (identity == null)
return new List<SecurityIdentifier>();
var userEntry = identity.GetUnderlyingObject() as DirectoryEntry;
userEntry.RefreshCache(new[] { groupType });
return (from byte[] sid in userEntry.Properties[groupType]
select new SecurityIdentifier(sid, 0)).ToList();
}
}
}
private static string[] ParseDomainQualifiedName(string name, string parameterName)
{
var groupTokens = name.Split(new[] {"\"}, StringSplitOptions.RemoveEmptyEntries);
if (groupTokens.Length < 2)
throw new ArgumentException(Resources.Exception_NameNotDomainQualified + name, parameterName);
return groupTokens;
}
回答by Adam
Simplest Solution
最简单的解决方案
PrincipalContext pc = new PrincipalContext((Environment.UserDomainName == Environment.MachineName ? ContextType.Machine : ContextType.Domain), Environment.UserDomainName);
GroupPrincipal gp = GroupPrincipal.FindByIdentity(pc, "{GroupName}");
UserPrincipal up = UserPrincipal.FindByIdentity(pc, Environment.UserName);
up.IsMemberOf(gp);
回答by p.campbell
This method might be helpful if you're trying to determine if the Windows authenticated current user is in a particular role.
如果您尝试确定经过 Windows 身份验证的当前用户是否处于特定角色,则此方法可能会有所帮助。
public static bool CurrentUserIsInRole(string role)
{
try
{
return System.Web.HttpContext.Current.Request
.LogonUserIdentity
.Groups
.Any(x => x.Translate(typeof(NTAccount)).ToString() == role);
}
catch (Exception) { return false; }
}
回答by Leonidius
Here is my 2 cents.
这是我的 2 美分。
static void CheckUserGroup(string userName, string userGroup)
{
var wi = new WindowsIdentity(userName);
var wp = new WindowsPrincipal(wi);
bool inRole = wp.IsInRole(userGroup);
Console.WriteLine("User {0} {1} member of {2} AD group", userName, inRole ? "is" : "is not", userGroup);
}