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.
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. –
In unserer Testumgebung betreiben wir nur einen einzigen Controller. –