2012-02-20 4 views
2

DirectoryServices을 사용하여 사용자를 인증 할 인트라넷 웹 응용 프로그램에 대한 메서드를 만들어야합니다.이 메서드는 기본 도메인이나 사용자가 지정한 것으로 가정합니다. 사용자가 웹 서버와 같은 도메인에와있을 때DirectoryServices를 사용한 도메인 간 인증

내 로그인 폼에

사용자가 "username""password "또는 "domain\username""password" 첫 번째 케이스의 형태가 자격 증명을 줄 중 하나를 할 수 사용할 수 있습니다 . 아주 straightfoward 내가 사용하는 코드는 다음과 같습니다

string domain = ""; 
// Code to check if the username is in form of "domain\user" or "user" 
string username = ParseUsername(username, out domain); 
if(domain == "") 
    domain = defaultDomain; 

PrincipalContext context = new PrincipalContext(ContextType.Domain, domain, username, password); 
bool IsAuthenticated = context.ValidateCredentials(username, password) 

은 내가 다른 도메인에 액세스하려고 할 경우에 전화를 결합하기 위해 PrincipalContext 생성자에 사용자 이름과 암호를 전달 로컬 도메인에 대한

. 그만큼 코드가 잘 작동합니다. 그러나 사용자 이름을 통해 지정된 다른 도메인에 대해 확인하려고하면 "서버에 연결할 수 없습니다."오류가 발생합니다.

다른 ContextOptions (예 : ContextOptions.SimpleBind 또는 ContextOptions.Negotiate)을 사용해 보았지만 항상 같은 결과가 나타나는 것 같습니다.

응용 프로그램이 단일 도메인 또는 다중 도메인 환경에서 다양한 고객에게 제공되기 때문에이를 구현해야합니다. "원격"도메인의 경우에 지정해야 할 것이 있습니까? 코드는 다양한 환경에 배치되므로 유연해야합니다.

감사

편집 : 나는 순서대로뿐만 아니라 제공하는 다른 기능을 활용 DirectoryServices.AccountManagementPrincipalContext를 사용하여 할 선호, 지적해야합니다.

또한 내 테스트를 위해 내 Dev 컴퓨터는 10.0.0. * 네트워크에 있고 테스트 대상인 두 번째 도메인은 10.0.1. *입니다. 나는 경로가 있고 모두가 있고 succesfuly ldap 클라이언트를 사용하여 연결할 수 있습니다. 그래서 질문을 왜 내 asp.net 응용 프로그램을 통해 도메인에 연결할 수 없습니다.

답변

3

나는이 문제에 대한 해결책을 내놓았다.

트러스트 관계 또는 격리 된 네트워크에서 여러 도메인을 지원하려면 우선 web.config에 NameValueCollection을 추가하여 도메인과 도메인 컨트롤러를 나열하십시오.

<domains> 
    <add key="domain1" value="10.0.0.1"/> 
    <add key="domain2" value="10.0.1.11"/> 
    </domains> 

(this so question의 구성 추가에 대한 자세한 정보는)

그런 다음 다음 단계는 내가 질문에 언급 방법으로 사용자의 자격 증명에서 도메인을 읽을 수 있었다.도메인을 얻은 후에 적절한 LDAP 연결 문자열을 얻기 위해 구성 값에서 해당 도메인 컨트롤러를 조회하려고합니다. 내가 적절한 연결 문자열을 다시 일단 내가 순서대로 새로운 통화를

private string GetLDAPConnection(string a_Domain, string a_Username, string a_Password) 
{ 
    // Get the domain controller server for the specified domain 
    NameValueCollection domains = (NameValueCollection)ConfigurationManager.GetSection("domains"); 
    string domainController = domains[a_Domain.ToLower()]; 

    string ldapConn = string.Format("LDAP://{0}/rootDSE", domainController); 

    DirectoryEntry root = new DirectoryEntry(ldapConn, a_Username, a_Password); 
    string serverName = root.Properties["defaultNamingContext"].Value.ToString(); 
    return string.Format("LDAP://{0}/{1}", domainController, serverName); 
} 

내가이 시점에서 적절한 LDAP

... 
    string ldapConn = GetLDAPConnection(domain, username, a_Password);        
    DirectoryEntry entry = new DirectoryEntry(ldapConn, username, a_Password);   

    try 
    { 
     try 
     { 
      object obj = entry.NativeObject; 
     } 
     catch(DirectoryServicesCOMException comExc) 
     { 
      LogException(comExc); 
      return false; 
     } 

     DirectorySearcher search = new DirectorySearcher(entry); 
     search.Filter = string.Format("(SAMAccountName={0})", username); 
     search.PropertiesToLoad.Add("cn"); 
     SearchResult result = search.FindOne(); 

를 해결함으로써, 사용자를 인증 : 그래서 내 방법이있다 또한 사용자의 그룹 구성원 등 원하는 모든 다른 쿼리를 수행 할 수 있습니다.

원격 도메인에 대한 호출을 사용자에게 바인딩해야하므로 "호출하는"사용자 자격 증명을 사용합니다. 이렇게하면 사용자가 인증되고 통화가 특정 사용자에게 바인드됩니다. 또한 사용자가 도메인을 지정하지 않고 자격 증명을 제공하는 경우 "기본"도메인을 지정합니다.

필자는 원하는대로 PrincipalContext를 사용하여 관리하지는 않았지만 밝은면에서이 솔루션은 이전 .NET 2.0 응용 프로그램에도 적용됩니다.

이것이 문제의 최선의 해결책이라고 확신하지는 않지만 지금까지 수행 한 테스트에서 작동하는 것으로 보입니다.

1

내가 왜 downvoted를 얻었는지 모르겠지만 여기서 잘못된 것이라고 생각합니다. 코드가 호스팅 된 서버/도메인과 당신이 접촉하려는 도메인 사이의 신뢰 수준이 설정되지 않았을 수 있습니다. . 왜 그런 일이 일어날 지 이유를 알려 드릴 수 없습니다.

[EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)] 

당신은 당신의 기능 이상이 추가 시도하고 당신이 통과하는 데 도움이,하지만 떨어져 나는 가능한 모든 사용자에 대한 Winnt는 도메인에서 검색 할 잘못된 이유를 참조하지 않는에서하면 볼 수 있습니다. 희망이 도움이

+0

보안 제한 사항은 내 첫 번째 추측입니다. 그러나이 메서드의 이전 구현에서는 이전 .NET 2.0 라이브러리의 DirectoryEntry 및 DirectorySearcher를 사용했습니다. 이 경우 호출을 바인드하기 위해 사용자 이름과 암호를 전달해야하므로 이중 홉 문제가 해결됩니다. 이제는 전혀 연결하지 않는 것 같습니다. 가장 큰 차이점은 이제 사용자가 자신이 속한 도메인을 지정할 수 있도록해야한다는 점입니다. –

+0

내가 일한 곳이 새 도메인으로 이전하기로 결정했을 때 비슷한 문제가 발생했습니다. 이전 과정에서 두 도메인을 모두 활성화해야했습니다. 거기에서 나는 신뢰 문제가 있다는 것을 알았지 만 그것에 대한 해결책을 결코 알 수 없었습니다. 대신 WinNT 접근 방식을 사용하여 전체 네트워크에서 userID를 검색하고 해당 객체를 얻은 다음 필요한만큼 조작을 수행했습니다. 또한 WinNT가 실현 가능한지 여부를 확인하기 위해 두 가지 방법 모두에 대한 대기 시간 검사를 수행했으며 괜찮은 선택이라고 판명되었습니다. – gizgok

+0

@NikosSteiakakis 솔루션을 이해하려면 여기에 적어주십시오. – gizgok