验证远程的Active Directory用户在C#用户、Active、Directory

2023-09-08 12:12:53 作者:不交电费发啥光

我尝试验证从我的机器,这是不相同的域作为当前计算机或用户域属于远程ActiveDirectory的用户。将有我的机器和远程ActiveDirectory中计算机之间没有信任。

首次尝试

我试图验证用户(输入:sAMAccountName赋,机器的ip地址,计算机域中的用户名(管理员)和机器的密码(***)能够得到结果是与sAMAccountName赋用户确实存在于ActiveDirectory中。

我的要求

想象一下,已经是一个用户(QWERTY)在ActiveDirectory中创建

从我的本地机器上,我将准备好以下信息,

一个。远程ActiveDirectory的ip地址

乙。远程ActiveDirectory中机器的用户名和密码。

℃。用户名和密码的用户的QWERTY

我需要检查用户QWERTY是否为present在远程ActiveDirectory中的用户列表,并验证是否密码的进入是同样在ActiveDirectory中的用户列表

code我想:

 的DirectoryEntry条目=新的DirectoryEntry(LDAP:// IP地址/ DC =迪内希,DC = COM,名,密码);
        DirectorySearcher从搜索=新DirectorySearcher从(输入);
        sea​​rcher.Filter =(sAMAccountName赋=+名称+);

        尝试
        {
            信息搜索结果adsSearchResult = adsSearcher.FindOne();
            的isValid = TRUE;
            adsEntry.Close();
        }
        赶上(例外前)
        {
            adsEntry.Close();
        }
 
如何使用Visio2010创建Active Directory

我是否需要验证用户在远程ActiveDirectory中前创建本地计算机和远程ActiveDirectory中机器之间的信任?如果有,请告诉它如何可以做到;

创建信任后,我怎么能验证用户?

=============================================== ============================

我能够使用由赖提出的解决方案,但用一个新的问题。当我创建通过C#code上新建一个用户从不同的机器上,然后一些属性不设置正确。

这是否需要被强制设置在创建用户?

解决方案

首先是一些基础知识(独立于这个问题)的

验证

系统检查,如果Bob是真的鲍勃。在Active Directory环境中,这通常是从工作站域登录完成后,鲍勃输入自己的用户名和密码,他得到一个Kerberos票据。后来,如果他想获得如在远程文件服务器的文件共享,他不需要登陆了,而且可以访问这些文件,而无需输入用户名/密码。

授权

哪些资源鲍伯被允许访问的系统检查。通常鲍勃在域组,一组为ACL(访问控制列表)中的资源。

如果有多个信任域,Bob需要在一个域中登录,并可以访问资源在所有其他领域。 这是使用Active Directory的主要原因之一:单点登录

检查,如果用户/密码是否有效

如果你有一个用户名和密码,并要检查,如果密码是有效的,你必须做一个登录到域。有没有办法只是检查,如果密码正确的。 登录意思:如果有一个安全策略锁定帐户,如果超过3无效登录,该账户将被锁定与密码错误检查,即使你只希望检查用户+密码

使用.NET目录服务功能

我这里假设的过程要么是由一个人的帐户运行作为一个正常的程序,或者该程序是一个Windows服务或在域技术的用户帐户运行计划任务。在这种情况下,您无​​需提供凭证使用AD功能。如果访问其他信任的AD域,也是如此。 如果你想登录到外域,而没有信任,就需要提供用户名+密码(如在code)。

手动验证用户

通常,这不应该被需要的。举例:ASP.NET内部网使用。通过浏览器和IIS用户访问在当前域或信任域的Web应用程序时,进行身份认证在后台(如集成的Windows身份验证上)。所以,你永远需要处理用户密码的应用程序。

我没有看到一个密码由code处理许多用例。

一个可能是你的程序是一个辅助工具,用于存储紧急情况的用户帐户/密码。而你要定期检查,如果这些账户是有效的。

这是一个简单的方法来检查:

 使用System.DirectoryServices.AccountManagement;
...

PrincipalContext principalContext =
     新PrincipalContext(ContextType.Domain,192.168.1.1);

布尔userValid = principalContext.ValidateCredentials(名,密码);
 

你也可以使用旧的,生ADSI功能:

 使用System.DirectoryServices中;
....

布尔userOk = FALSE;
弦真实姓名=的String.Empty;

使用(的DirectoryEntry的DirectoryEntry =
   新的DirectoryEntryLDAP://192.168.1.1/DC=ad,DC=local,名,密码))
{
    使用(DirectorySearcher从搜索=新DirectorySearcher从(的DirectoryEntry))
    {
        sea​​rcher.Filter =(Sam帐户=+名称+);
        sea​​rcher.PropertiesToLoad.Add(显示名称);

        信息搜索结果adsSearchResult = searcher.FindOne();

        如果(adsSearchResult!= NULL)
        {
            如果(adsSearchResult.Properties [显示名。计数== 1)
            {
                实名=(字符串)adsSearchResult.Properties [显示名称] [0];
            }
            userOk =真;
        }
    }
}
 

如果您的实际需求,实际上是用户+密码有效性检查,可以使用以下方法之一做到这一点。

但是,如果它是一个正常的应用程序,它只是想检查,如果输入的凭证是有效的,你应该重新考虑你的逻辑。在这种情况下,你最好应该依赖于AD能力的单点登录。

如果还有其它问题,请评论。

       

乙。远程ActiveDirectory中机器的用户名和密码。

  

这听起来有点不清楚。我假设你的意思是在远程域用户名和对应的密码。

还有一个机器帐户,这是追加$主机名的概念。但是,这是另一个话题。

创建新的用户

选项1

 使用(的DirectoryEntry的DirectoryEntry =新的DirectoryEntry(LDAP://192.168.1.1/CN=Users,DC=ad,DC=local
        名,口令))
{
    使用(的DirectoryEntry新用户= directoryEntry.Children.Add(CN = CharlesBarker,用户))
    {
        newUser.Properties [sAMAccountName赋]值=CharlesBarker。
        newUser.Properties [给定名称]值=查尔斯。
        newUser.Properties [SN]值=巴克。
        newUser.Properties [显示名]值=CharlesBarker。
        newUser.Properties [的UserPrincipalName]值=CharlesBarker。
        newUser.CommitChanges();
    }
}
 

选项2

 使用(PrincipalContext principalContext =新PrincipalContext(ContextType.Domain,192.168.1.1,
    CN =用户​​,DC =广告,DC =本地名,密码))
{
    使用(UserPrincipal userPrincipal =新UserPrincipal(principalContext))
    {
        userPrincipal.Name =CharlesBarker;
        userPrincipal.SamAccountName =CharlesBarker;
        userPrincipal.GivenName =查;
        userPrincipal.Surname =巴克;
        userPrincipal.DisplayName =CharlesBarker;
        userPrincipal.UserPrincipalName =CharlesBarker;
        userPrincipal.Save();
    }
}
 

我留下作为一个练习,你找出哪个属性放在哪个用户对话框中输入字段: - )

I try to authenticate users belonging to remote ActiveDirectory from my machine, which is not the same domain as the current machine or user domain. There will be no trust between my machine and remote ActiveDirectory machine.

Initial Try

I tried to authenticate a user(Input: sAMAccountName, machine's ipaddress, machine's domain username("Administrator") and machine's password(***). Able to get result that the user with 'sAMAccountName' do exist in ActiveDirectory.

My Requirement:

Imagine that already a user("qwerty") is created in ActiveDirectory

From my local machine, I will have the following information,

a. Remote ActiveDirectory ipaddress

b. Remote ActiveDirectory machine's username and password.

c. Username and password of User "qwerty"

I need to check whether User "qwerty" is present in remote ActiveDirectory's users list and validate whether the password entered is same in ActiveDirectory's Users list

Code I tried:

        DirectoryEntry entry = new DirectoryEntry("LDAP://ipaddress/DC=dinesh,DC=com", name, password);
        DirectorySearcher searcher = new DirectorySearcher(entry);
        searcher.Filter = "(sAMAccountName=" + name + ")";

        try
        {
            SearchResult adsSearchResult = adsSearcher.FindOne();
            isValid = true;
            adsEntry.Close();
        }
        catch (Exception ex)
        {
            adsEntry.Close();
        }

Do I need to create a trust between local machine and remote ActiveDirectory machine before validating Users in a remote ActiveDirectory? If yes please tell how it can be done;

After creating trust, how can I validate Users?

===========================================================================

I am able to use the solution suggested by Rainer, but with a new problem. When I create a new user via C# code from a different machine, then some properties do not set properly.

Does this need to be set compulsorily while creating user?

解决方案

First some basics (independent of this question)

Authentication

The system checks if Bob is really Bob. In an Active Directory environment, this is usually done with a domain login from the workstation, Bob enters his username and password, and he gets a Kerberos ticket. Later, if he wants to access e.g. a file share on a remote fileserver, he does not need to login anymore, and can access the files without entering username/password.

Authorization

The system checks which resources Bob is allowed to access. Usually Bob is in domain groups, and a group is in the ACL (access control list) of the resource.

If there are multiple trusting domains, Bob needs to login in one domain, and can access resources in all other domains. This is one of the main reasons using Active Directory: single sign on

Checking if user / password is valid

If you have a username and password and want to check if the password is valid, you have to do a login to the domain. There is no way of just "checking if the password is correct". Login means: if there is a security policy "lock account if more than 3 invalid logins", the account will be locked out checking with wrong password, even if you "only want to check the user+password".

Using .NET Directory Service functions

I assume here that the process is either run by a human account as a normal program, or the program is a Windows service or a scheduled task which runs under a domain "technical user" account. In this case, you do not need to provide credentials for using the AD functions. If accessing other trusting AD domains, this is also true. If you want to login to a "foreign domain", and there is no trust, you need to provide a username+password (as in your code).

"Manually" authenticating a user

Normally, this should not be needed. Example: ASP.NET intranet usage. The user access a web application on the current domain or trusting domain, the authentication is done "in the background" by browser and IIS (if integrated Windows authentication is on). So you never need to handle user passwords in the application.

I don’t see many use cases where a password is handled by code.

One may that your program is a helper tool for storing emergency user accounts/passwords. And you want to check periodically if these accounts are valid.

This is a simple way to check:

using System.DirectoryServices.AccountManagement;
...

PrincipalContext principalContext = 
     new PrincipalContext(ContextType.Domain, "192.168.1.1");

bool userValid = principalContext.ValidateCredentials(name, password);

One can also use the older, raw ADSI functions:

using System.DirectoryServices;
....

bool userOk = false;
string realName = string.Empty;

using (DirectoryEntry directoryEntry = 
   new DirectoryEntry"LDAP://192.168.1.1/DC=ad,DC=local", name, password))
{
    using (DirectorySearcher searcher = new DirectorySearcher(directoryEntry))
    {
        searcher.Filter = "(samaccountname=" + name + ")";
        searcher.PropertiesToLoad.Add("displayname");

        SearchResult adsSearchResult = searcher.FindOne();

        if (adsSearchResult != null)
        {
            if (adsSearchResult.Properties["displayname"].Count == 1)
            {   
                realName = (string)adsSearchResult.Properties["displayname"][0];
            }
            userOk = true;
        }
    }
}   

If your real requirement is actually a validity check of user+password, you can do it in one of these ways.

However, if it is a "normal application", which just wants to check if the entered credentials are valid, you should rethink your logic. In this case, you better should rely on the single sign on capabilities of AD.

If there are further questions, please comment.

b. Remote ActiveDirectory machine's username and password.

This sounds a bit unclear. I assume you mean "a username and corresponding password in the remote domain".

There is also the concept of a machine account, which is the hostname appended with $. But that's another topic.

Creating new user

Option 1

using (DirectoryEntry directoryEntry = new DirectoryEntry("LDAP://192.168.1.1/CN=Users,DC=ad,DC=local", 
        name, password))
{
    using (DirectoryEntry newUser = directoryEntry.Children.Add("CN=CharlesBarker", "user"))
    {
        newUser.Properties["sAMAccountName"].Value = "CharlesBarker";
        newUser.Properties["givenName"].Value = "Charles";
        newUser.Properties["sn"].Value = "Barker";
        newUser.Properties["displayName"].Value = "CharlesBarker";
        newUser.Properties["userPrincipalName"].Value = "CharlesBarker";
        newUser.CommitChanges();
    }
}

Option 2

using (PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, "192.168.1.1", 
    "CN=Users,DC=ad,DC=local", name, password))
{
    using (UserPrincipal userPrincipal = new UserPrincipal(principalContext))
    {
        userPrincipal.Name = "CharlesBarker";
        userPrincipal.SamAccountName = "CharlesBarker";
        userPrincipal.GivenName = "Charles";
        userPrincipal.Surname = "Barker";
        userPrincipal.DisplayName = "CharlesBarker";
        userPrincipal.UserPrincipalName = "CharlesBarker";
        userPrincipal.Save();
    }
}

I leave as an exercise to you to find out which attribute goes into which User dialog entry field :-)