PrincipalContext.ValidateCredentials始终返回FALSE

Bil*_*gan 15 c# asp.net-mvc active-directory activedirectorymembership

我有一个MVC应用程序需要登录并验证用户对Active Directory.我正在使用该PrincipalContext.ValidateCredentials方法,但始终获得身份验证false.

连接到服务器很好.问题似乎发生在ValidateCredentials.

这是我的代码:

public static bool IsAuthenticated(string domain, string username, string pwd) {
    bool IsAuthenticated = false;

    try {
        PrincipalContext insPrincipalContext = 
            new PrincipalContext(ContextType.Domain, domain, "DC=c1w,DC=com");

        username = "c1w\\" + username;

        IsAuthenticated = insPrincipalContext.ValidateCredentials(username, pwd);
    }
    catch (Exception ex)
    {
        // Rethrow this exception
        ExceptionPolicy.HandleException(ex, "Exception Policy");
    }

    return IsAuthenticated;
}
Run Code Online (Sandbox Code Playgroud)

任何人都知道为什么会发生这种情况?

Rob*_*los 14

下面是如何ValidateCredentials(string, string)工作的:首先,它会尝试与验证Negotiate,Signing以及Sealing上下文选项.如果失败,它会再次尝试SimpleBindSecureSocketLayer.

问题是NT4(AKA"遗留",AKA"低级名称")格式(DOMAIN\UserName或更准确地说NetBiosName\SamAccountName)不适用于Negotiate.但它确实适用于SimpleBind.

所以在调用2参数ValidateCredentials()方法时可能发生的事情是它首先使用Negotiate失败,因为它不喜欢NT4格式,然后在使用简单绑定时再次失败.

在我自己的测试中,我发现即使在回归使用简单绑定之后它失败的原因是它不仅使用SimpleBind.它正在使用SimpleBind加号SecureSocketLayer.这意味着如果未正确设置Active Directory服务器以使用SSL(测试环境的常见方案),它仍将失败.

正如其中一条评论中所提到的,你永远不要自己使用SimpleBind(没有SecureSocketLayer),否则你的密码将通过网络以纯文本形式发送.

在野外,我已经看到一些Active Directory系统根本不允许使用简单的绑定,所以你必须使它与Negotiate一起使用.

我找到了两种方法来解决这个问题:

1)如果所有内容都发生在同一个域中,您应该ValidateCredentials只能使用用户名(SAM帐户名称)进行呼叫,而忽略"DOMAIN"部分.然后,第一次与Negotiate一起正常工作.

2)如果因为有可能会涉及到多个域(即域部分是重要的Domain1\UserADomain2\UserA是不同的人),那么它变得有点复杂.在这种情况下,我最终做的是将NT4名称(DOMAIN\User)转换为"用户主体名称"格式(例如LogonName@domain.com).有几种不同的方法可以做到这一点.最简单的可能是使用3参数重载UserPrincipal.FindByIdentity(),然后UserPrincipalName在结果上获取属性的值.另一种方法是使用a DirectorySearcher和查询具有匹配值的用户LDAP://domainuserPrincipalName属性sAMAccountName.注意:此解决方案仅在涉及的所有域位于同一林中时才有效.


fed*_*ves 9

我没有看到你初始化"pwd"变量的位置也许你应该在这个方法中使用ContextOption来准确指定所需的行为.很抱歉,回复过于宽泛,但您的问题中没有太多详细信息

  • B-Rain,ContextOption参考指出了我正确的方向.在验证凭据上调用AD和ContextOptions.SimpleBind时使用ContextOptions.Negotiate结束.Simple Bind对我有用,因为该站点将是SSL安全的.谢谢你的帮助. (5认同)
  • 如果您使用ContextOptions.Simplebind,请注意密码可以通过网络以明文形式发送. (2认同)