복붙노트

[SPRING] LDAP : 연결 세부 정보로 사용자를 인증하는 방법

SPRING

LDAP : 연결 세부 정보로 사용자를 인증하는 방법

LDAP를 사용하여 사용자를 인증 할 수 없습니다. 나는 다음과 같은 세부 사항을 가지고있다.

URL=ldap://10.10.10.10:389 
LDAP BASE:DC=lab2,DC=ins 
LDAP Bind Account: CN=Ldap Bind,OU=Service Accounts,OU=TECH,DC=lab2,DC=ins 
LDAP Bind Account Pw: secret 

위의 세부 정보를 사용하여 sAMAccountName 값을 검색 할 수 있지만 사용자 이름과 암호로 사용자를 인증하는 방법은 무엇입니까? 이전 질문을 수행하면 LDAP 서버에 성공적으로 연결할 수 있지만 인증 할 수 없음을 이해하게됩니다. 인증 할 사용자 :

user: someusername
password: somepwd

'somepwd'라는 LDAP 서버에 연결할 수 없으며 someusername을 어떻게 사용해야합니까? 주어진 사용자를 sAMAccountName으로 검색 할 수 있습니다.

해결법

  1. ==============================

    1.이것은 여러 곳에서 발견 한 것들의 매쉬업입니다. UnboundID SDK를 사용하지 않으려면 올바른 경로를 따라야합니다. 이것은 생산 품질이 아니므로 상점에서 지원하는 경우 여기에 SSL 항목을 추가 할 수 있습니다.

    이것은 여러 곳에서 발견 한 것들의 매쉬업입니다. UnboundID SDK를 사용하지 않으려면 올바른 경로를 따라야합니다. 이것은 생산 품질이 아니므로 상점에서 지원하는 경우 여기에 SSL 항목을 추가 할 수 있습니다.

    public static Boolean validateLogin(String userName, String userPassword) {
        Hashtable<String, String> env = new Hashtable<String, String>();
    
    
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, "ldap://" + LDAP_SERVER + ":" + LDAP_SERVER_PORT + "/" + LDAP_BASE_DN);
    
        // To get rid of the PartialResultException when using Active Directory
        env.put(Context.REFERRAL, "follow");
    
        // Needed for the Bind (User Authorized to Query the LDAP server) 
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, LDAP_BIND_DN);
        env.put(Context.SECURITY_CREDENTIALS, LDAP_BIND_PASSWORD);
    
        DirContext ctx;
        try {
           ctx = new InitialDirContext(env);
        } catch (NamingException e) {
           throw new RuntimeException(e);
        }
    
        NamingEnumeration<SearchResult> results = null;
    
        try {
           SearchControls controls = new SearchControls();
           controls.setSearchScope(SearchControls.SUBTREE_SCOPE); // Search Entire Subtree
           controls.setCountLimit(1);   //Sets the maximum number of entries to be returned as a result of the search
           controls.setTimeLimit(5000); // Sets the time limit of these SearchControls in milliseconds
    
           String searchString = "(&(objectCategory=user)(sAMAccountName=" + userName + "))";
    
           results = ctx.search("", searchString, controls);
    
           if (results.hasMore()) {
    
               SearchResult result = (SearchResult) results.next();
               Attributes attrs = result.getAttributes();
               Attribute dnAttr = attrs.get("distinguishedName");
               String dn = (String) dnAttr.get();
    
               // User Exists, Validate the Password
    
               env.put(Context.SECURITY_PRINCIPAL, dn);
               env.put(Context.SECURITY_CREDENTIALS, userPassword);
    
               new InitialDirContext(env); // Exception will be thrown on Invalid case
               return true;
           } 
           else 
               return false;
    
        } catch (AuthenticationException e) { // Invalid Login
    
            return false;
        } catch (NameNotFoundException e) { // The base context was not found.
    
            return false;
        } catch (SizeLimitExceededException e) {
            throw new RuntimeException("LDAP Query Limit Exceeded, adjust the query to bring back less records", e);
        } catch (NamingException e) {
           throw new RuntimeException(e);
        } finally {
    
           if (results != null) {
              try { results.close(); } catch (Exception e) { /* Do Nothing */ }
           }
    
           if (ctx != null) {
              try { ctx.close(); } catch (Exception e) { /* Do Nothing */ }
           }
        }
    }
    
  2. ==============================

    2.LDAP 연결은 익명으로 시작됩니다. 연결의 권한 부여 상태를 변경하려면 BIND 요청을 사용하십시오. BIND 요청에는 'simple'또는 'SASL'두 가지 형식이 있습니다. '간단한'BIND 요청은 식별 이름과 암호를 사용합니다. BIND 요청은 보안 연결을 통해 전송되거나 StartTLS 확장 요청을 사용하여 보안 연결로 승격 된 비보안 연결을 통해 전송되어야합니다.

    LDAP 연결은 익명으로 시작됩니다. 연결의 권한 부여 상태를 변경하려면 BIND 요청을 사용하십시오. BIND 요청에는 'simple'또는 'SASL'두 가지 형식이 있습니다. '간단한'BIND 요청은 식별 이름과 암호를 사용합니다. BIND 요청은 보안 연결을 통해 전송되거나 StartTLS 확장 요청을 사용하여 보안 연결로 승격 된 비보안 연결을 통해 전송되어야합니다.

    UnboundID LDAP SDK 사용 :

    // exception handling not shown
    LDAPConnection ldapConnection = new LDAPConnection(hostname,port);
    BindRequest bindRequest = new SimpleBindRequest(username,password);
    BindResult bindResult = ldapConnection.bind(bindRequest);
    if(bindResult.getResultCode().equals(ResultCode.SUCCESS)) {
       /// successful authentication
    }
    ldapConnection.close();
    
  3. ==============================

    3.도움이 될 몇 가지 JNDI 샘플이 있습니다.

    도움이 될 몇 가지 JNDI 샘플이 있습니다.

  4. ==============================

    4.이것을 사용해보십시오, 저를 위해 일했습니다.

    이것을 사용해보십시오, 저를 위해 일했습니다.

    public static Boolean validateLogin(String userName, String userPassword) {
        Hashtable<String, String> env = new Hashtable<String, String>();
    
    
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, "ldap://" + LDAP_SERVER + ":" + LDAP_SERVER_PORT + "/" + LDAP_BASE_DN);
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, userName + "@" + LDAP_SERVER);
        env.put(Context.SECURITY_CREDENTIALS, userPassword);
    
        DirContext ctx;
        try {
           ctx = new InitialDirContext(env); //throw exception, if username-password not correct
           return true;
        } catch (Exception e) {
            return false;
        }
    }
    
  5. from https://stackoverflow.com/questions/12163947/ldap-how-to-authenticate-user-with-connection-details by cc-by-sa and MIT license