相关疑难解决方法(0)

如何验证域凭据?

我想针对域控制器验证一组凭据.例如:

Username: STACKOVERFLOW\joel
Password: splotchy
Run Code Online (Sandbox Code Playgroud)

方法1.使用模拟查询Active Directory

很多人建议查询Active Directory.如果抛出异常,那么您知道凭据无效 - 正如此stackoverflow问题中所建议的那样.

然而,这种方法有一些严重的缺点:

  1. 您不仅要对域帐户进行身份验证,还要进行隐式授权检查.也就是说,您正在使用模拟令牌从AD中读取属性.如果其他有效帐户无权从AD读取,该怎么办?默认情况下,所有用户都具有读取权限,但可以将域策略设置为禁用受限帐户(和/或组)的访问权限.

  2. 绑定AD会产生严重的开销,必须在客户端加载AD架构缓存(DirectoryServices使用的ADSI提供程序中的ADSI缓存).这既是网络又是AD服务器,消耗资源 - 而且对于像验证用户帐户这样的简单操作来说太昂贵了.

  3. 您依赖于非例外情况的异常失败,并假设这意味着无效的用户名和密码.然后,其他问题(例如,网络故障,AD连接故障,内存分配错误等)被错误地表示为身份验证失败.

方法2. LogonUser Win32 API

其他人建议使用LogonUser()API函数.这听起来不错,但不幸的是,调用用户有时需要一个权限,通常只给操作系统本身:

调用LogonUser的进程需要SE_TCB_NAME权限.如果调用进程没有此权限,LogonUser将失败,GetLastError将返回ERROR_PRIVILEGE_NOT_HELD.

在某些情况下,调用LogonUser的进程还必须启用SE_CHANGE_NOTIFY_NAME权限; 否则,LogonUser失败,GetLastError返回ERROR_ACCESS_DENIED.作为管理员组成员的本地系统帐户或帐户不需要此权限.默认情况下,为所有用户启用SE_CHANGE_NOTIFY_NAME,但某些管理员可能会为所有用户禁用它.

省高院" 法案作为操作系统的一部分 "特权是不是你想要做无可奈何的东西-作为微软在一份指出知识库文章:

...调用LogonUser的进程必须具有SE_TCB_NAME权限(在用户管理器中,这是" 作为操作系统的一部分 "权限).SE_TCB_NAME权限非常强大, 不应授予任何任意用户,以便他们可以运行需要验证凭据的应用程序.

此外,LogonUser()如果指定了空密码,则调用将失败.


验证一组域凭据的正确方法是什么?


碰巧是从托管代码调用,但这是一个普通的Windows问题.可以假设客户已安装.NET Framework 2.0.

c# windows security authentication

79
推荐指数
3
解决办法
11万
查看次数

ASP.NET MVC - 针对Active Directory对用户进行身份验证,但需要输入用户名和密码

我正在开发一个MVC3应用程序,需要用户对AD进行身份验证.我知道MVC3中有一个选项可以创建一个Intranet应用程序,可以根据AD自动对用户进行身份验证,但它使用Windows身份验证并自动登录.可以在"开放"工作站上访问此应用程序,用户需要输入其域用户名和密码.任何示例或在线教程都会很棒.一个示例项目将是例外.

asp.net-mvc forms-authentication windows-authentication asp.net-mvc-3 asp.net-mvc-2

44
推荐指数
2
解决办法
4万
查看次数

Active Directory - 检查用户名/密码

我在Windows Vista Ultimate SP1上使用以下代码来查询我们的活动目录服务器以检查域上用户的用户名和密码.

public Object IsAuthenticated()
{
    String domainAndUsername = strDomain + "\\" + strUser;
    DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, strPass);
    SearchResult result;
    try
    {
        //Bind to the native AdsObject to force authentication.         

        DirectorySearcher search = new DirectorySearcher(entry) { Filter = ("(SAMAccountName=" + strUser + ")") };

        search.PropertiesToLoad.Add("givenName"); // First Name                
        search.PropertiesToLoad.Add("sn"); // Last Name
        search.PropertiesToLoad.Add("cn"); // Last Name

        result = search.FindOne();

        if (null == result)
        {
            return null;
        }

        //Update the new path to the user in …
Run Code Online (Sandbox Code Playgroud)

c# ldap active-directory windows-vista

34
推荐指数
2
解决办法
7万
查看次数

为什么Active Directory验证最后一个密码?

我正在研究一种在Active Directory中更新用户密码的简单解决方案.

我可以成功更新用户密码.更新密码工作正常.假设用户已将密码从MyPass1更新为MyPass2

现在,当我运行自定义代码以验证用户凭据时使用:

using(PrincipalContext pc = new PrincipalContext(ContextType.Domain, "TheDomain"))
{
    // validate the credentials
    bool isValid = pc.ValidateCredentials("myuser", "MyPass2");
}

//returns true - which is good
Run Code Online (Sandbox Code Playgroud)

现在,当我输入一些错误的密码时,它会很好地验证:

using(PrincipalContext pc = new PrincipalContext(ContextType.Domain, "TheDomain"))
{
    // validate the credentials
    bool isValid = pc.ValidateCredentials("myuser", "wrongPass");
}

//returns false - which is good
Run Code Online (Sandbox Code Playgroud)

现在由于一些奇怪的原因,它验证了以前的最后一个密码是MyPass1还记得吗?

using(PrincipalContext pc = new PrincipalContext(ContextType.Domain, "TheDomain"))
{
    // validate the credentials
    bool isValid = pc.ValidateCredentials("myuser", "MyPass1");
}

//returns true - but why? we have updated password to …
Run Code Online (Sandbox Code Playgroud)

c# active-directory

33
推荐指数
2
解决办法
1万
查看次数

.Net的目录服务引发了一个奇怪的例外

我有一个用于检查用户凭据的小型C#解决方案.它适用于我的两个队友,但在我的电脑上我得到了一个例外.

相关代码:

PrincipalContext context = new PrincipalContext(ContextType.Domain);
if (context.ValidateCredentials(System.Environment.UserDomainName + "\\" + usr, pwd))
     return true;
else
     return false;
Run Code Online (Sandbox Code Playgroud)

例外是:

DirectoryOperationException,"服务器无法处理目录请求.".

我尝试使用显式服务器名称和636端口号创建上下文,但这也没有帮助.

有任何想法吗?

.net c# directory service ldap

24
推荐指数
2
解决办法
2万
查看次数

如何在ASP.Net Identity中使用ActiveDirectoryMembershipProvider?

我正在尝试学习如何使用ASP.Net Identity.我的方案是我必须针对Active Directory进行身份验证.为此我想尝试使用ActiveDirecotoryMembershipProvider.我要做的是 -

  1. 针对Active Directory验证用户/密码.
  2. 检查用户是否存在于我自己的数据库中.

我这样做的方式是我在我的配置中web.config使用ActiveDirectoryMembershipProvider默认会员提供程序.然后我覆盖PasswordSignInAsync我的ApplicationSignInManager类(继承SignInManager)中的方法如下 -

public override Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout)
{
    var adok = Membership.Provider.ValidateUser(userName, password);
    if (adok)
    {
        var user = UserManager.FindByName(userName);
        if (user == null)
            return Task.FromResult<SignInStatus>(SignInStatus.Failure);
        else
        {
            base.SignInAsync(user, isPersistent, shouldLockout);
            return Task.FromResult<SignInStatus>(SignInStatus.Success);
        }
    }
    else
        return Task.FromResult<SignInStatus>(SignInStatus.Failure);
}
Run Code Online (Sandbox Code Playgroud)

这似乎有效.但我认为这不是正确的做法.有谁能建议任何更好的方法来实现这一目标?

UPDATE

以下是我如何称呼上述内容

var result = await SignInManager.PasswordSignInAsync(username, password, isPersistent: false, shouldLockout: false);
switch (result)
{ …
Run Code Online (Sandbox Code Playgroud)

c# asp.net asp.net-membership asp.net-identity asp.net-identity-2

18
推荐指数
2
解决办法
5679
查看次数

Win32:如何验证针对Active Directory的凭据?

有人问过,并回答过.NET,但是现在是时候得到原生Win32代码的答案了:

如何验证Windows用户名和密码?

之前问过托管代码这个问题.现在是原生解决方案的时候了.


需要指出一些更常见的解决方案的陷阱:

无效方法1.使用模拟查询Active Directory

很多人建议查询Active Directory.如果抛出异常,那么您知道凭据无效 - 正如此stackoverflow问题中所建议的那样.

然而,这种方法一些严重的缺点:

  • 您不仅要对域帐户进行身份验证,还要进行隐式授权检查.也就是说,您正在使用模拟令牌从AD中读取属性.如果其他有效帐户无权从AD读取,该怎么办?默认情况下,所有用户都具有读取权限,但可以将域策略设置为禁用受限帐户(和/或组)的访问权限.

  • 绑定AD会产生严重的开销,必须在客户端加载AD架构缓存(DirectoryServices使用的ADSI提供程序中的ADSI缓存).这既是网络又是AD服务器,消耗资源 - 而且对于像验证用户帐户这样的简单操作来说太昂贵了.

  • 您依赖于非例外情况的异常失败,并假设这意味着无效的用户名和密码.然后,其他问题(例如,网络故障,AD连接故障,内存分配错误等)被错误地表示为身份验证失败.

使用DirectoryEntry该类是.NET是验证凭据的错误方法的示例:

无效的方法1a - .NET

DirectoryEntry entry = new DirectoryEntry("persuis", "iboyd", "Tr0ub4dor&3");
object nativeObject = entry.NativeObject;
Run Code Online (Sandbox Code Playgroud)

无效的方法1b - .NET#2

public static Boolean CheckADUserCredentials(String accountName, String password, String domain)
{
    Boolean result;

    using (DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain, accountName, password))
    {
        using (DirectorySearcher searcher = new DirectorySearcher(entry))
        { …
Run Code Online (Sandbox Code Playgroud)

windows security authentication winapi active-directory

16
推荐指数
1
解决办法
2万
查看次数

在命令行验证域凭据

是否有一个Windows命令可以让我验证域帐户/密码?

windows dns command-line login credentials

14
推荐指数
1
解决办法
3万
查看次数

验证PowerShell PSCredential

假设我PSCrendential在PowerShell中创建了一个使用的对象Get-Credential.

如何验证针对Active Directory的输入?

到现在为止我找到了这种方式,但我觉得它有点难看:

[void][System.Reflection.Assembly]::LoadWithPartialName("System.DirectoryServices.AccountManagement")


function Validate-Credentials([System.Management.Automation.PSCredential]$credentials)
{
    $pctx = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Domain, "domain")
    $nc = $credentials.GetNetworkCredential()
    return $pctx.ValidateCredentials($nc.UserName, $nc.Password)
}

$credentials = Get-Credential

Validate-Credentials $credentials
Run Code Online (Sandbox Code Playgroud)

[编辑,两年后]对于未来的读者,请注意Test-Credential或者Test-PSCredential是更好的名称,因为Validate它不是有效的powershell动词(请参阅参考资料Get-Verb)

security powershell

10
推荐指数
1
解决办法
1万
查看次数

使用PrincipalContext.ValidateCredentials对本地计算机进行身份验证时出错?

我有一个WCF服务,其中包含一个Login根据本地计算机凭据验证用户名和密码的方法,并且在看似随机的一段时间后,它将停止为某些用户工作.

实际的登录命令如下所示:

public UserModel Login(string username, string password, string ipAddress)
{
    // Verify valid parameters
    if (username == null || password == null)
        return null;

    try
    {
        using (var pContext = new PrincipalContext(ContextType.Machine))
        {
            // Authenticate against local machine
            if (pContext.ValidateCredentials(username, password))
            {
                // Authenticate user against database
                using (var context = new MyEntities(Connections.GetConnectionString()))
                {
                    var user = (from u in context.Users
                                where u.LoginName.ToUpper() == username.ToUpper()
                                      && u.IsActive == true
                                      && (string.IsNullOrEmpty(u.AllowedIpAddresses)
                                        || u.AllowedIpAddresses.Contains(ipAddress))
                                select u).FirstOrDefault();

                    // If …
Run Code Online (Sandbox Code Playgroud)

c# authentication wcf active-directory principalcontext

10
推荐指数
1
解决办法
4245
查看次数