繁体   English   中英

使用Active Directory对用户进行身份验证,而不会在catch块内放置错误的用户名或密码错误

[英]Authenticating user with Active Directory without placing incorrect username or password error inside catch block

我正在尝试使用Active Directory进行身份验证。 这可以正常工作,但是如何在不将错误的用户名/密码消息放入catch块内的情况下进行身份验证? 这不是不好的做法吗? 我发现许多例子都建议这样做。 有关系吗

public void ADLogin()
{
    try
    {
        DirectoryEntry root = new DirectoryEntry("LDAP://" + "domain", txtUsername.Value, txtPassword.Value);
        DirectorySearcher searcher = new DirectorySearcher(root, "(sAMAccountName=" + txtUsername.Value + ")");
        SearchResult result = searcher.FindOne();
        if (result.Properties["sAMAccountName"] != null)
        {
            //AD Login Success        
            FormsAuthentication.RedirectFromLoginPage(txtUsername.Value, Login1.RememberMeSet);
        }
    }
    catch (Exception)
    {
            //AD Login failed         
            //Display Error Message
    }            
}

我尝试将catch块放置在此if语句中,但是在到达它之前会引发异常:

public void ADLogin()
{
    DirectoryEntry root = new DirectoryEntry("LDAP://" + "domain", txtUsername.Value, txtPassword.Value);
    DirectorySearcher searcher = new DirectorySearcher(root, "(sAMAccountName=" + txtUsername.Value + ")");
    SearchResult result = searcher.FindOne();
    if (result.Properties["sAMAccountName"] != null)
    {
        //AD Login Success        
        FormsAuthentication.RedirectFromLoginPage(txtUsername.Value, Login1.RememberMeSet);
    }
    if (result.Properties["sAMAccountName"] == null)
    {
        //AD Login failed         
        //Display Error Message
    }            
}

捕获异常没有错。 您无法控制DirectorySearcher内的代码,因此如果出现问题,就无法帮助它引发异常。 但是,您可能想要区分抛出的异常的类型,因此,例如,您可以分辨出不良凭证和网络错误之间的区别。

请注意,如果凭据不正确,则将使用searcher.FindOne()引发异常,因为您正在使用用户的凭据连接到AD。

这不是验证凭据的最快方法。 如果您想要更好的性能,可以在此处使用LdapConnection解决方案。 它仅使用用户的凭据执行LDAP绑定,而无需像您的代码那样进行搜索。 如答案所描述的,它还有一个额外的好处,就是能够告诉您身份验证失败的原因

如果确实需要从用户帐户中查找信息,那么可以,您需要进行搜索。 但是您应该使用DirectorySearcher.PropertiesToLoad集合。 如果没有另外指定, DirectorySearcher将检索每个结果都有值的每个属性 那可能是您不需要的大量数据(尤其是如果您的组织在AD中存储用户照片)。 相反,您可以告诉DirectorySearcher所需的属性,它将仅检索以下属性:

DirectorySearcher searcher = new DirectorySearcher(root, "(sAMAccountName=" + txtUsername.Value + ")");
searcher.PropertiesToLoad.Add("sAMAccountName");
result = searcher.FindOne();

我写了整篇有关针对AD进行编程时性能注意事项的文章,您可能会发现它很有趣: Active Directory:更好的性能

如果您在try / catch块之外声明了SearchResult怎么办?

public void ADLogin()
{
    SearchResult result = null;
    try
    {
        DirectoryEntry root = new DirectoryEntry("LDAP://" + "domain", txtUsername.Value, txtPassword.Value);
        DirectorySearcher searcher = new DirectorySearcher(root, "(sAMAccountName=" + txtUsername.Value + ")");
        result = searcher.FindOne();
    }
    catch (Exception)
    {
    }

    if (result != null && result.Properties["sAMAccountName"] != null)
    {
        //AD Login Success        
        FormsAuthentication.RedirectFromLoginPage(txtUsername.Value, Login1.RememberMeSet);
    }
    else
    {
        //AD Login failed         
        //Display Error Message
    }
}

不知道为什么您会以这样的方式认为这是不好的做法。 最佳实践(没有更多关于此代码所在位置的上下文)可能是在catch块中记录您的错误,然后将其重新抛出。 静默失败是一个坏习惯。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM