ユーザーが.Net3.5asp.net c#アプリケーションのActiveDirectoryグループの一部であるかどうかを確認する方法が必要です。
msdnの標準のLDAP認証の例を使用していますが、グループに対してチェックする方法がわかりません。
ユーザーが.Net3.5asp.net c#アプリケーションのActiveDirectoryグループの一部であるかどうかを確認する方法が必要です。
msdnの標準のLDAP認証の例を使用していますが、グループに対してチェックする方法がわかりません。
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;
}
Nick Craverのソリューションは、.NET4.0では機能しません。アンロードされたAppDomainに関するエラーが発生します。それを使用する代わりに、これを使用しました(ドメインは1つだけです)。これにより、グループのグループと直接のグループメンバーシップがチェックされます。
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 + "\\", ""));
}
}
以下のコードは .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();
}
最も簡単な解決策
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);
この方法は、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; }
}
ユーザーが AD グループに属しているかどうかは、何を意味するかによって異なります。AD では、グループはセキュリティ グループまたは配布グループにすることができます。セキュリティ グループの場合でも、「ドメイン ユーザー」や「ユーザー」などのグループをメンバーシップ チェックに含める必要があるかどうかによって異なります。
IsUserInSecurityGroup は、セキュリティ グループのみをチェックし、配布グループではなく、「ドメイン ユーザー」や「ユーザー」などのプライマリ グループの種類のグループに対して機能します。また、ネストされたグループの問題も解決します。IsUserInAllGroup も配布グループをチェックしますが、アクセス許可の問題が発生するかどうかはわかりません。その場合は、WAAG にあるサービス アカウントを使用します ( MSDN を参照) 。
私が 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;
}
次のコードを試すことができます。
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)
}
ユーザーの親グループに間接的にリンクされているネストされたグループを含むユーザー グループのメンバーシップを確認する場合は、以下のように「tokenGroups」プロパティを使用してみてください。
System.DirectoryServices の使用 public static bool IsMemberOfGroupsToCheck (文字列 DomainServer、文字列 LoginID、文字列 LoginPassword) { string UserDN = "CN=John.Doe-A,OU=管理アカウント,OU=ユーザー ディレクトリ,DC=ABC,DC=com" string ADGroupsDNToCheck = "CN=ADGroupTocheck,OU=管理グループ,OU=グループ ディレクトリ,DC=ABC,DC=com"; バイト[] sid、parentSID; ブール チェック = false; DirectoryEntry 親エントリ; DirectoryEntry basechildEntry; 文字列 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(basechildEntry.Properties["tokenGroups"] 内のオブジェクト GroupSid) { sid = (byte[])GroupSid; if (ConvertToOctetString(sid,false,false) == octetSID) { チェック = 真; 壊す; } } basechildEntry.Dispose(); parentEntry.Dispose(); 小切手を返します。 }
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);
ブランドン・ジョンソン、気に入りました。私はあなたが持っていたものを使用しましたが、次の変更を加えました:
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();
}