问题描述
模拟示例一个>
我可以用下一行代码检查用户域管理员:
I can check is user domain administrator with next lines of code:
using (Impersonation im = new Impersonation(UserName, Domain, Password))
{
System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent();
bool isDomainAdmin = identity.IsDomainAdmin(Domain, UserName, Password);
if (!isDomainAdmin)
{
//deny access, for example
}
}
其中 IsDomainAdmin - 是扩展方法
where IsDomainAdmin - is extension method
public static bool IsDomainAdmin(this WindowsIdentity identity, string domain, string userName, string password)
{
Domain d = Domain.GetDomain(new DirectoryContext(DirectoryContextType.Domain, domain, userName, password));
using (DirectoryEntry de = d.GetDirectoryEntry())
{
byte[] domainSIdArray = (byte[])de.Properties["objectSid"].Value;
SecurityIdentifier domainSId = new SecurityIdentifier(domainSIdArray, 0);
SecurityIdentifier domainAdminsSId = new SecurityIdentifier(WellKnownSidType.AccountDomainAdminsSid, domainSId);
WindowsPrincipal wp = new WindowsPrincipal(identity);
return wp.IsInRole(domainAdminsSId);
}
}
但是,当调用 IsDomainAdmin 方法时,它会尝试将一些文件写入 %LOCALAPPDATA% 以供模拟用户使用,如果程序不是以管理员身份运行,则会引发异常
But, when method IsDomainAdmin is called, it is trying to write some files to the %LOCALAPPDATA% for impersonated user, and if program is runnig not as administrator, it throws an exception
无法加载文件或程序集System.DirectoryServices,版本=4.0.0.0,文化=中性,PublicKeyToken=b03f5f7f11d50a3a' 或它的依赖项之一.所需的模拟级别不是提供,或者提供的模拟级别无效.(例外来自 HRESULT: 0x80070542)
Could not load file or assembly 'System.DirectoryServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. Either a required impersonation level was not provided, or the provided impersonation level is invalid. (Exception from HRESULT: 0x80070542)
推荐答案
您当然不需要用户密码来验证用户是否是组的成员.那么为什么不直接使用 DirectoryEntry
或 DirectorySearcher
直接查询 AD 呢?如果您还需要验证提供的密码是否正确,您可以使用 PrincipalContext.ValidateCredentials
在附加步骤中执行此操作.(请参阅 PrincipalContext.ValidateCredentials 方法(字符串、字符串))..>
You certainly don't need a user's password to verify if the user is a member of a group. So why don't you just query AD in a straight-forward manner using DirectoryEntry
or DirectorySearcher
? If you also need to verify that the password supplied is correct you can do that in an additional step using PrincipalContext.ValidateCredentials
. (See PrincipalContext.ValidateCredentials Method (String, String)).
static void Main(string[] args) {
string userDomain = "somedomain";
string userName = "username";
string password = "apassword";
if (IsDomainAdmin(userDomain, userName)) {
string fullUserName = userDomain + @"" + userName;
PrincipalContext context = new PrincipalContext(
ContextType.Domain, userDomain);
if (context.ValidateCredentials(fullUserName, password)) {
Console.WriteLine("Success!");
}
}
}
public static bool IsDomainAdmin(string domain, string userName) {
string adminDn = GetAdminDn(domain);
SearchResult result = (new DirectorySearcher(
new DirectoryEntry("LDAP://" + domain),
"(&(objectCategory=user)(samAccountName=" + userName + "))",
new[] { "memberOf" })).FindOne();
return result.Properties["memberOf"].Contains(adminDn);
}
public static string GetAdminDn(string domain) {
return (string)(new DirectorySearcher(
new DirectoryEntry("LDAP://" + domain),
"(&(objectCategory=group)(cn=Domain Admins))")
.FindOne().Properties["distinguishedname"][0]);
}
这篇关于如何在不冒充的情况下检查具有 [UserName] 和 [Password] 的用户是否是 [DomainName] 的域管理员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!