2016-11-11 4 views
0

UPDATE 11/14: Ich habe durch unser ops-Team verifiziert, dass der Benutzername/das Passwort gültig ist, wenn Sie sich über die Active Directory-Benutzeroberfläche anmelden. Also ist es nur programmatisch, dass es scheitert.LDAP AD kann einen Benutzer, den ich gerade erstellt habe, nicht authentifizieren

Ich arbeite mit einem einfachen Active Directory-Server und testen die Möglichkeit, einen neuen Benutzer zu erstellen und dann diesen Benutzer mit den gerade angegebenen Anmeldeinformationen zu authentifizieren.

Ich kann einen vorhandenen Benutzer erfolgreich authentifizieren (erstellt über die Admin-Schnittstelle auf dem Server); Ich kann einen neuen Benutzer erstellen und das Passwort festlegen (siehe Code-Schnipsel unten); Ich kann diesen Benutzer finden erfolgreich

Allerdings, wenn ich die Anmeldeinformationen zu authentifizieren versuchen, mit I zur Verfügung gestellt, ich bin der

javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db0] 

bekommen Sie den Code unten ein Benutzer

public UserEntity authenticate (@NotNull final String username, 
            @NotNull final String password) 
    throws NamingException 
{ 
    try 
    { 
     Hashtable<String, Object> env = new Hashtable<>(); 

     env.put(Context.SECURITY_AUTHENTICATION,"simple"); 
     env.put(Context.SECURITY_PRINCIPAL,  username); 
     env.put(Context.SECURITY_CREDENTIALS, password); 
     env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); 
     env.put(Context.PROVIDER_URL,   "ldaps://<host>:636"); 
     env.put(Context.SECURITY_PROTOCOL,  "ssl") ; 

     LdapContext context = new InitialLdapContext(env, null); 

     // find the account now that the user is authenticated to 
     // construct the UserEntity 
     // note: code for findAccountByAccountName() not included as 
     //  the creation of the context is what generates the 
     //  exception 
     return findAccountByAccountName(context, "<search-base>", username); 
    } 
    } 

Hier zu authentifizieren ist der Code, um einen neuen Benutzer

public static void addUser(@NotNull final String username, 
           @NotNull final String firstName, 
           @NotNull final String password) 
    throws NamingException 
    { 
    // Create a container set of attributes 
    // 
    Attributes container = new BasicAttributes(true); // case ignore 

    // Create the object class to add 
    Attribute objClasses = new BasicAttribute("objectClass"); 
    objClasses.add("top"); 
    objClasses.add("person"); 
    objClasses.add("organizationalPerson"); 
    objClasses.add("user"); 

    // Assign the username and first name 
    // 
    Attribute givenName = new BasicAttribute("givenName", firstName); 
    Attribute sAMAccountName = new BasicAttribute("sAMAccountName", username); 

    // Make the account active 
    // 
    Attribute userAccountControl = new BasicAttribute("userAccountControl", "512") ; 

    // Add these to the container 
    // 
    container.put(objClasses); 
    container.put(givenName); 
    container.put(sAMAccountName); 
    container.put(userAccountControl) ; 

    // only can do this if connecting via secure ldap 
    // 
    if (isSecureLdap()) 
    { 
     try 
     { 
      final String quotedPassword = String.format("\"%s\"", password) ; 
      Attribute pwd = new BasicAttribute("unicodePwd", quotedPassword.getBytes("UTF-16LE")); 
      container.put(pwd); 
     } 
     catch (UnsupportedEncodingException e) 
     { 
      LOGGER.error("Unable to encode password"); 
     } 
    } 

    // creates a context using the Admin credentials. 
    LdapContext context = setup() ; 

    // Create the entry 
    // 
    context.createSubcontext(getUserDN(username), container); 
} 

Dann in meinem Test-Code erstellt:

// authenticate a known user 
// 
try 
{ 
    // existing user 'dev' and this works just fine 
    authenticate("dev", "password") ; 
} 
catch (NamingException e) 
{ 
    // if authentication fails, which it does not in this case 
} 

// create new user 
// 
final String username = "myTestUser" ; 
final String password = "myTestPassword" ; 
try 
{ 
    addUser(username, "test", password) ; 
} 
catch (NamingException e) 
{ 
    // if creation fails, which it does not in this case 
} 

// try to find that user 
// 
try 
{ 
    // code for find() not included since it works 
    final UserEntity user = findUser(username) ; 
} 
catch (NoSuchUserException e) 
{ 
    // thrown by find() if it fails -- again, this part still works 
} 

// attempt to authenticate the newly created user 
// 
try 
{ 
     authenticate(username, password) ; 
} 
catch (NamingException e) 
{ 
    // this is the part that throws the exception 
} 

Ich bin sicher, dass es etwas ist gering, das fehlt, aber auf SO und anderen Orten rund um ziemlich viel nach der Suche, ich habe nicht die magische Bohne zu beheben diese gefunden.

+1

Hat Ihre AD-Domäne mehr als einen Domänencontroller? Wenn Sie das Konto, das Sie gerade erstellt haben, sofort verwenden möchten, müssen Sie sicherstellen, dass Sie denselben Domänencontroller verwenden, da das Konto nicht auf die anderen Domänencontroller repliziert wurde. –

+0

In unserer Testumgebung betreiben wir nur einen einzigen Controller. –

Antwort

0

Versuchen Sie den Code für das Kennwort:

private byte[] encodePassword(String pass) throws UnsupportedEncodingException 
{ 
    final String ATT_ENCODING = "Unicode"; 
    // Agree with MS's ATTRIBUTE_CONSTRAINT 
    String pwd = "\"" + pass +"\""; 
    byte bytes[] = pwd.getBytes(ATTENCODING); 
    // strip unicode marker 
    byte bytes[] = new byte [_bytes.length - 2]; 
    System.arraycopy(_bytes, 2, bytes, 0,_bytes.length - 2); 
    return bytes; 
} 

Microsoft Active Directory über Passwörter lustig ist. Normalerweise fügen wir zuerst den Benutzer hinzu und ändern dann das Passwort. -jim

+0

Dies ist nicht notwendig. Es kann sich um ein Replikationsproblem handeln. –

+0

Versuchte den obigen Code, aber das generiert eine Ausnahme WILL_NOT_PERFORM. Ich habe versucht, "Unicode" zu dem ursprünglichen UTF-16LE zu ändern und das gleiche Ergebnis zu erhalten. Mein ursprünglicher Code (aus dem Posting) scheint erfolgreich zu sein. –

+0

und durch 'erfolgreich', ich meine, es scheint, den Benutzer zu erstellen. Trotzdem kann ich mich nicht gegen diesen Benutzer authentifizieren. –

Verwandte Themen