C# 使用Active Directory验证用户,但未在catch块中放置错误的用户名或密码错误

C# 使用Active Directory验证用户,但未在catch块中放置错误的用户名或密码错误,c#,asp.net,active-directory,C#,Asp.net,Active Directory,我正在尝试使用Active Directory进行身份验证。这很好,但是如何在不将不正确的用户名/密码消息放入catch块的情况下进行身份验证?这不是坏习惯吗?我发现很多例子都有这样的建议。这有关系吗 public void ADLogin() { try { DirectoryEntry root = new DirectoryEntry("LDAP://" + "domain", txtUsername.Value, txtPassword.Value);

我正在尝试使用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
    }            
}

如果在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块中记录错误,然后重新抛出;无声失败是一种不好的做法。

捕获异常没有什么错。您无法控制DirectorySearcher中的代码,因此如果出现问题,它会抛出异常,这是情不自禁的。但是,您可能希望区分抛出的异常类型,以便可以区分错误凭据和网络错误

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

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

如果您确实需要从用户帐户中查找信息,那么是的,您需要搜索它。但是你应该使用这个集合。如果不另行指定,
DirectorySearcher
将检索每个结果都有值的属性。这可能是很多您不需要的数据(尤其是如果您的组织在广告中存储用户照片)。相反,您可以告诉DirectorySearcher您需要哪些属性,它只会检索这些属性:

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

我写了一整篇关于针对AD编程时的性能注意事项的文章,您可能会对此感兴趣:

错误的凭据会在
searcher.FindOne()
处引发异常,因为您正在使用用户的凭据搜索AD。