C#/ASP.NET/AD - "The specified directory service attribute or value does not exist."

标签 c# asp.net authentication active-directory

通过 ASP.NET Web 表单向 Active Directory 提交有效凭据时,返回以下错误消息:“指定的目录服务属性或值不存在。”

LDAP 身份验证代码:

using System;
using System.Text;
using System.Collections;
using System.DirectoryServices;

namespace FormsAuth
{
    public class LdapAuthentication
    {
        private string _path;
        private string _filterAttribute;

        public LdapAuthentication(string path)
        {
            _path = path;
        }

        public bool IsAuthenticated(string domain, string username, string pwd)
        {
            string domainAndUsername = "CBHC" + @"\" + username;
            DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, pwd);

            try
            {
                //Bind to the native AdsObject to force authentication.
                object obj = entry.NativeObject;

                DirectorySearcher search = new DirectorySearcher(entry);

                search.Filter = "(SAMAccountName=" + username + ")";
                search.PropertiesToLoad.Add("cn");
                SearchResult result = search.FindOne();

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

                //Update the new path to the user in the directory.
                _path = result.Path;
                _filterAttribute = (string)result.Properties["cn"][0];
            }
            catch (Exception ex)
            {
                throw new Exception("Error authenticating user. " + ex.Message);
            }

            return true;
        }

        public string GetGroups()
        {
            DirectorySearcher search = new DirectorySearcher(_path);
            search.Filter = "(cn=" + _filterAttribute + ")";
            search.PropertiesToLoad.Add("memberOf");
            StringBuilder groupNames = new StringBuilder();

            try
            {
                SearchResult result = search.FindOne();
                int propertyCount = result.Properties["memberOf"].Count;
                string dn;
                int equalsIndex, commaIndex;

                for (int propertyCounter = 0; propertyCounter < propertyCount; propertyCounter++)
                {
                    dn = (string)result.Properties["memberOf"][propertyCounter];
                    equalsIndex = dn.IndexOf("=", 1);
                    commaIndex = dn.IndexOf(",", 1);
                    if (-1 == equalsIndex)
                    {
                        return null;
                    }
                    groupNames.Append(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1));
                    groupNames.Append("|");
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Error obtaining group names. " + ex.Message);
            }
            return groupNames.ToString();
        }
    } 
}

登录页面代码:

<script runat=server>
void Login_Click(object sender, EventArgs e)
{
    string adPath = "LDAP://server/DC=domain,DC=loc"; //Path to your LDAP directory server
  LdapAuthentication adAuth = new LdapAuthentication(adPath);
  try
  {
    if(true == adAuth.IsAuthenticated("CBHC",txtUsername.Text, txtPassword.Text))
    {
      string groups = adAuth.GetGroups();

      //Create the ticket, and add the groups.
      bool isCookiePersistent = chkPersist.Checked;
      FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, 
                txtUsername.Text,DateTime.Now, DateTime.Now.AddMinutes(60), isCookiePersistent, groups);

      //Encrypt the ticket.
      string encryptedTicket = FormsAuthentication.Encrypt(authTicket);

      //Create a cookie, and then add the encrypted ticket to the cookie as data.
      HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);

      if(true == isCookiePersistent)
      authCookie.Expires = authTicket.Expiration;

      //Add the cookie to the outgoing cookies collection.
      Response.Cookies.Add(authCookie);

      //You can redirect now.

      Response.Redirect(FormsAuthentication.GetRedirectUrl(txtUsername.Text, false));
    }
    else
    {
      errorLabel.Text = "Authentication did not succeed. Check user name and password.";
    }
  }
  catch(Exception ex)
  {
    errorLabel.Text = "Error authenticating. " + ex.Message;
  }
}
</script>

IIS 上表单的 Web.config 上的身份验证设置:

<authentication mode="Windows">
      <forms loginUrl="logon.aspx" name="adAuthCookie" timeout="10" path="/" />
    </authentication>
    <authorization>
      <deny users="?" />
      <allow users="*" />
    </authorization>
    <identity impersonate="true" />

值得注意的是:在 Debug模式下运行站点时不会发生这种情况;在这种情况下,它会完美地进行身份验证并移至默认页面。仅当联系 IIS 服务器上的实时页面时才会发生这种情况。

最佳答案

我曾经遇到过这样的问题。这可能是因为您无法检索 LDAP NativeObject 属性进行身份验证。如果在 object obj =entry.NativeObject; 调用之后立即引发异常,请检查用户是否具有该域的权限。

调试代码以查看是否确实是 NativeObject 绑定(bind)失败。或者在 IsAuthenticated() 函数中的绑定(bind)周围放置一个 try/catch block ,如下所示。如果自定义错误是由我所描述的问题引起的,您应该会看到抛出的自定义错误。

try
{   //Bind to the native AdsObject to force authentication.         
    Object obj = entry.NativeObject;
}
catch (System.Runtime.InteropServices.COMException e)
{
    if (e.ErrorCode == -2147016694) // -2147016694 - The specified directory service attribute or value does not exist.
    {
        throw new Exception("Can't retrieve LDAP NativeObject property");
    }
    throw;
}

关于C#/ASP.NET/AD - "The specified directory service attribute or value does not exist.",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19985471/

相关文章:

javascript - 为什么注入(inject) JavaScript 代码是个坏主意

asp.net - Html 表达式作为 razor 中的 lambda - 允许什么,记录在哪里

php - 如何在 WooCommerce 中仅使用电子邮件和密码登录

javascript - JavaFX WebEngine 和 Pushbullet 身份验证

c# - 方向取决于数据时的 OrderByWithDirection

c# - 将 UTF-8 字符串放入字符串类型的变量中

c# - 找不到指定的过程。 (来自 HRESULT : 0x8007007F) 的异常

c# - 如何更改字典中KeyPairValue的值?

asp.net - session 过期时如何重定向到登录页面(ASP.NET 3.5 FormsAuthen)

database - 使用 Hibernate 的 Spring Security 3 数据库身份验证