起初我认为下面的代码可以工作,因为如果我将组设置为“IT”,它就能正常工作,因为我的用户名位于活动目录中的 IT 组中。我了解到的是,无论我的用户名是否在 IT 组中,它总是返回 true,如果我将其更改为我所在的任何其他组,它总是返回 false。任何帮助将不胜感激。
private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
{
// tab control security for admin tab
bool admin = checkGroup("IT");
if ((admin == true) && (tabControl1.SelectedTab == tpHistory))
{
tabControl1.SelectedTab = tpHistory;
}
else if ((admin == false) && (tabControl1.SelectedTab == tpHistory))
{
tabControl1.SelectedTab = tpRequests;
MessageBox.Show("Unable to load tab. You have insufficient privileges.",
"Access Denied", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
}
// check active directory to see if user is in Marketing department group
private static bool checkGroup(string group)
{
WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
return principal.IsInRole(group);
}
由于您使用的是 .NET 3.5 及更高版本,因此您应该检查
System.DirectoryServices.AccountManagement
(S.DS.AM) 命名空间。在这里阅读所有相关内容:
基本上,您可以定义域上下文并轻松在 AD 中查找用户和/或组:
// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "DOMAINNAME");
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
// find the group in question
GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, "YourGroupNameHere");
if(user != null)
{
// check if user is member of that group
if (user.IsMemberOf(group))
{
// do something.....
}
}
新的 S.DS.AM 让 AD 中的用户和组变得非常容易!
与@marc_s示例略有偏差,在
static void Main()
中的Program
方法中实现:
DomainCtx = new PrincipalContext( ContextType.Domain , Environment.UserDomainName );
if ( DomainCtx != null ) {
User = UserPrincipal.FindByIdentity( DomainCtx , Environment.UserName );
}
DomainCtx
和 User
都是在 Program
下声明的静态属性
然后在其他形式中我只是做这样的事情:
if ( Program.User.IsMemberOf(GroupPrincipal.FindByIdentity(Program.DomainCtx, "IT-All") )) {
//Enable certain Form Buttons and objects for IT Users
}
检查当前用户是否在组中
public bool AuthenticateGroup(string groupfind)
{
var p = new Process();
StringBuilder stringbd = new StringBuilder();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = @"/c gpresult /V";
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = false;
p.StartInfo.UseShellExecute = false;
p.OutputDataReceived += (a, b) => stringbd.AppendLine(b.Data);
p.ErrorDataReceived += (a, b) => stringbd.AppendLine(b.Data);
p.Start();
p.BeginErrorReadLine();
p.BeginOutputReadLine();
p.WaitForExit();
var textfind = stringbd.ToString();
int findpoint = textfind.IndexOf("The user is a part of");
string findgroup = "";
if (findpoint > 0)
{
findgroup = textfind.Substring(findpoint, textfind.Length - findpoint);
}
return findgroup.Split('\n').ToList().Any(r=>r.Trim().ToLower()==groupfind.Trim().ToLower());
}
你不能用这种方式做到这一点。 您应该查询活动目录。 您可以使用 AD 包装器。查看 http://www.codeproject.com/Articles/10301/Wrapper-API-for-using-Microsoft-Active-Directory-S
为什么不:
bool isUserInGroup = HttpContext.User.IsInRole(".nameOfAdGroup");
我有一个完美的错误处理解决方案,它还可以自动处理子组,而无需循环扫描所有子组。 IsMemberOf 不适用于子组:
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
public static bool IsUserInGroup(string userName, string groupName)
{
try
{
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain))
{
var gp = GroupPrincipal.FindByIdentity(pc, groupName);
var up = UserPrincipal.FindByIdentity(pc, userName);
if (gp == null) throw new ApplicationException($"Group '{groupName}' not found in Active Directory");
if (up == null) throw new ApplicationException($"User '{userName}' not found in Active Directory");
DirectoryEntry user = new DirectoryEntry($"LDAP://{up.DistinguishedName}");
DirectorySearcher mySearcher = new DirectorySearcher(user)
{
SearchScope = SearchScope.Subtree,
Filter = $"(memberOf:1.2.840.113556.1.4.1941:={gp.DistinguishedName})" // takes also subgroups
};
return !(mySearcher.FindOne() is null);
}
}
catch (Exception)
{
throw;
}
}
public static bool IsComputerInGroup(string computerName, string groupName)
{
try
{
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain))
{
var gp = GroupPrincipal.FindByIdentity(pc, groupName);
var cp = ComputerPrincipal.FindByIdentity(pc, computerName);
if (gp == null) throw new ApplicationException($"Group '{groupName}' not found in Active Directory");
if (cp == null) throw new ApplicationException($"Computer '{userName}' not found in Active Directory");
DirectoryEntry computer = new DirectoryEntry($"LDAP://{cp.DistinguishedName}");
DirectorySearcher mySearcher = new DirectorySearcher(computer)
{
SearchScope = SearchScope.Subtree,
Filter = $"(memberOf:1.2.840.113556.1.4.1941:={gp.DistinguishedName})"
};
return !(mySearcher.FindOne() is null);
}
}
catch (Exception)
{
throw;
}
}