如何检查是否用户与[用户名]和[密码]是[域名]域管理员不模仿? [英] How to check if user with [UserName] and [Password] is domain administrator of [DomainName] without impersonation?

查看:149
本文介绍了如何检查是否用户与[用户名]和[密码]是[域名]域管理员不模仿?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

模拟例如

我可以检查用户是域管理员用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]);
}
 

Impersonation example

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆