问题
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.
I am using the standard ldap authentication example off of msdn but I don't really see how to check against a group.
回答1:
With 3.5 and System.DirectoryServices.AccountManagement this is a bit cleaner:
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;
}
回答2:
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.
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 + "\\", ""));
}
}
回答3:
The code below will work in .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();
}
回答4:
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);
回答5:
This method might be helpful if you're trying to determine if the Windows authenticated current user is in a particular role.
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; }
}
回答6:
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.
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)
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)
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;
}
回答7:
Here is my 2 cents.
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);
}
回答8:
This seems much simpler:
public bool IsInRole(string groupname)
{
var myIdentity = WindowsIdentity.GetCurrent();
if (myIdentity == null) return false;
var myPrincipal = new WindowsPrincipal(myIdentity);
var result = myPrincipal.IsInRole(groupname);
return result;
}
回答9:
How about this
How to write LDAP query to test if user is member of a group?
回答10:
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();
}
回答11:
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)
}
回答12:
var context = new PrincipalContext(ContextType.Domain, {ADDomain}, {ADContainer});
var group = GroupPrincipal.FindByIdentity(context, IdentityType.Name, {AD_GROUP_NAME});
var user = UserPrincipal.FindByIdentity(context, {login});
bool result = user.IsMemberOf(group);
回答13:
If you want to check the user groups membership including the nested groups which is indirectly linked to the user parent group you can try use the "tokenGroups" properties as below:
Using System.DirectoryServices public static bool IsMemberOfGroupsToCheck(string DomainServer, string LoginID, string LoginPassword) { string UserDN = "CN=John.Doe-A,OU=Administration Accounts,OU=User Directory,DC=ABC,DC=com" string ADGroupsDNToCheck = "CN=ADGroupTocheck,OU=Administration Groups,OU=Group Directory,DC=ABC,DC=com"; byte[] sid, parentSID; bool check = false; DirectoryEntry parentEntry; DirectoryEntry basechildEntry; string octetSID; basechildEntry = new DirectoryEntry("LDAP://" + DomainServer + "/" + UserDN, LoginID, LoginPassword); basechildEntry.RefreshCache(new String[] { "tokenGroups" }); parentEntry = new DirectoryEntry("LDAP://" + DomainServer + "/" + ADGroupsDNToCheck, LoginID, LoginPassword); parentSID = (byte[])parentEntry.Properties["objectSID"].Value; octetSID = ConvertToOctetString(parentSID, false, false); foreach(Object GroupSid in basechildEntry.Properties["tokenGroups"]) { sid = (byte[])GroupSid; if (ConvertToOctetString(sid,false,false) == octetSID) { check = true; break; } } basechildEntry.Dispose(); parentEntry.Dispose(); return check; }
来源:https://stackoverflow.com/questions/2188954/see-if-user-is-part-of-active-directory-group-in-c-sharp-asp-net