2013-11-14 1 views
1

ASP.NET 웹 양식을 통해 Active Directory에 유효한 자격 증명을 제출할 때 "지정된 디렉터리 서비스 특성 또는 값이 존재하지 않습니다."라는 오류 메시지가 반환됩니다.C#/ASP.NET/AD - "지정한 디렉터리 서비스 특성 또는 값이 없습니다."

코드 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(); 
     } 
    } 
} 

로그인 페이지 코드 : 노트의

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

말씀 : IIS에서 양식의 Web.config에

<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 서버에서 라이브 페이지에 접속할 때만 발생합니다.

+0

오류가 발생하는 정확한 줄을 확인하려면 디버거를 통해 코드를 실행하십시오. –

+0

도메인의 이름이 같은가요? localhost를 사용하여 서버 시스템에서 사이트를 실행하려고하면 어떤 오류가 발생합니까? – CheGueVerra

+0

Che : localhost를 사용하는 IIS 서버에서 문제없이 인증합니다. –

답변

2

한 번 이런 문제가 발생했습니다. 인증을 위해 LDAP NativeObject 속성을 검색 할 수 없기 때문일 수 있습니다. object obj = entry.NativeObject; 호출 직후에 예외가 발생하면 사용자에게 도메인에 대한 사용 권한이 있는지 확인하십시오.

코드를 통해 디버그하여 실제로 NativeObject 바인딩이 실패했는지 확인하십시오. 또는 아래의 IsAuthenticated() 함수에서 바인딩 주위에 try/catch 블록을 놓습니다. 설명하는 문제로 인한 사용자 정의 오류가 표시되어야합니다.

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; 
} 
+0

슬프게도 나는 이것이 우리에게 적용된다고 생각하지 않습니다 ... 우리는 단지 하나의 도메인을 가지고 있으며 여러 곳에서 인증을 시도하지 않습니다. –

+0

여러 도메인에 대한 결론을 얻은 방법에 대해 확신하지 못했습니다. 내가 말하고자하는 것은 인증하려는 사용자가 Active Directory 도메인에 대한 읽기 액세스 권한이없는 경우 예외가 발생한다는 것입니다. -2147016694 지정한 디렉터리 서비스 특성 또는 값이 존재하지 않습니다. – tokafew420

+0

죄송합니다. 제 광고 지식이 최소한이고 도메인 관리자가 아니기 때문에 다른 사람에게 이전 대답을 해석하도록 요청했습니다. 이 사용자 (나)는 도메인의 다른 AD 인증 서버/프로그램/기타에 액세스 할 수 있습니다. –

관련 문제