如何检查是否用户与[用户名]和[密码]是[域名]域管理员不模仿? [英] How to check if user with [UserName] and [Password] is domain administrator of [DomainName] without impersonation?
问题描述
我可以检查用户是域管理员用code下一行:
使用(模拟IM =新的模拟(用户名,域,密码))
{
System.Security.Principal.WindowsIdentity同一性= System.Security.Principal.WindowsIdentity.GetCurrent();
布尔isDomainAdmin = identity.IsDomainAdmin(域名,用户名,密码);
如果(!isDomainAdmin)
{
//拒绝访问,例如
}
}
在这里IsDomainAdmin - 是扩展方法
公共静态布尔IsDomainAdmin(此的WindowsIdentity身份,串域,用户名字符串,字符串密码)
{
域D = Domain.GetDomain(新DirectoryContext(DirectoryContextType.Domain,域名,用户名,密码));
使用(的DirectoryEntry德= d.GetDirectoryEntry())
{
byte []的domainSIdArray =(字节[])de.Properties [的objectSID]值。
的SecurityIdentifier domainSId =新的SecurityIdentifier(domainSIdArray,0);
的SecurityIdentifier domainAdminsSId =新的SecurityIdentifier(WellKnownSidType.AccountDomainAdminsSid,domainSId);
的WindowsPrincipal WP =新的WindowsPrincipal(身份);
返回wp.IsInRole(domainAdminsSId);
}
}
但是,如果方法IsDomainAdmin被调用时,它正试图写一些文件到%LOCALAPPDATA%用于模拟用户,如果程序运行过程中出现不以管理员身份,它抛出一个异常
无法加载文件或程序集System.DirectoryServices, 版本= 4.0.0.0,文化=中性公钥= b03f5f7f11d50a3a或 它的一个依赖。无论是所需的模拟程度不 提供,或提供的模拟级别无效。 (例外 来自HRESULT:0x80070542)
您肯定不需要用户的密码,以验证用户是否是一个组的成员。那么,为什么你不使用查询AD在一个直截了当的方式的DirectoryEntry
或 DirectorySearcher从
?如果您还需要验证提供的密码正确,你可以用做一个额外的步骤 PrincipalContext.ValidateCredentials
。 (见 PrincipalContext.ValidateCredentials方法(字符串,字符串))。
静态无效的主要(字串[] args){
字符串USERDOMAIN =somedomain;
字符串username =用户名;
字符串密码=apassword;
如果(IsDomainAdmin(USERDOMAIN,用户名)){
字符串fullUserName = USERDOMAIN + @\+用户名;
PrincipalContext上下文=新PrincipalContext(
ContextType.Domain,USERDOMAIN);
如果(context.ValidateCredentials(fullUserName,密码)){
Console.WriteLine(成功!);
}
}
}
公共静态布尔IsDomainAdmin(字符串域,用户名字符串){
字符串adminDn = GetAdminDn(域);
信息搜索结果的结果=(新DirectorySearcher从(
新的DirectoryEntry(LDAP://+域)
(及(objectCategory属性=用户)(的samAccountName =+的userName +)),
新的[] {成员}))FindOne()。
返回result.Properties [成员]包含(adminDn)。
}
公共静态字符串GetAdminDn(字符串域){
返程(串)(新DirectorySearcher从(
新的DirectoryEntry(LDAP://+域)
(及(objectCategory属性=组)(CN =域管理员)))
。.FindOne()属性[的distinguishedName] [0]);
}
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
}
}
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);
}
}
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
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)
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]);
}
这篇关于如何检查是否用户与[用户名]和[密码]是[域名]域管理员不模仿?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!