one of my clients requirement was to authenticate users against his corporate ActiveDirectory (LDAP). So I used standard ActiveDirectoryLdapAuthenticationProvider and it works like a charm.
@Bean public ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() { ActiveDirectoryLdapAuthenticationProvider adProvider = new ActiveDirectoryLdapAuthenticationProvider( ldapConfig.getLdapDomain(), ldapConfig.getLdapUrl(), ldapConfig.getLdapRoot()); adProvider.setConvertSubErrorCodesToExceptions(true); adProvider.setUseAuthenticationRequestCredentials(true); adProvider.setSearchFilter(ldapConfig.getLdapSearchFilter()); return adProvider; }
Problem is that clients AC is hidden behind firewall. It works after deployment, but I cannot reach AC during local development due to cleints security policy. So, I had an idea that maybe for dev profile I will use embedded LDAP server (UnboundID LDAP SDK for Java). I’m not an LDAP expert, but I somehow composed simple ldif file, and it looks like this:
dn: dc=test,dc=local objectclass: top objectclass: domain objectclass: extensibleObject dc: test # Organizational Units dn: ou=groups,dc=test,dc=local objectclass: top objectclass: organizationalUnit ou: groups dn: ou=people,dc=test,dc=local objectclass: top objectclass: organizationalUnit ou: people # Users dn: uid=john,ou=people,dc=test,dc=local objectclass: top objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson cn: John Doe sn: John uid: john password: johnspassword # Create Groups dn: cn=administrators,ou=groups,dc=test,dc=local objectclass: top objectclass: groupOfUniqueNames cn: administrators ou: administrator uniqueMember: uid=john,ou=people,dc=test,dc=local
I also configured embedded ldap properties:
spring.ldap.embedded.base-dn=dc=test,dc=local spring.ldap.embedded.ldif=classpath:localldapactivedirectory.ldif spring.ldap.embedded.port=12345 spring.ldap.embedded.url=ldap://localhost:12345/ spring.ldap.embedded.validation.enabled=false
UnboundID had no problem with that, but as you guess I encounter problem during authentication:
[LDAP: error code 34 - Unable to parse bind DN 'john@test.local': Unable to parse string 'john@test.local' as a DN because it does not have an equal sign after RDN attribute 'john@test.local'.]; nested exception is javax.naming.InvalidNameException: [LDAP: error code 34 - Unable to parse bind DN 'john@test.local': Unable to parse string 'user_cms@test.com' as a DN because it does not have an equal sign after RDN attribute 'john@test.local'.]
To show you whole picture I add that error occurs during authentication attempt (in custom authentication service):
Authentication authentication = authenticationManagerBuilder.getObject() .authenticate(authenticationToken);
I presume that it is caused by the fact that my ldif file is too simple. It would work with vanilla Ldap authentication provider, but not with ActiveDirectoryLdapAuthenticationProvider.
Is there anyone who knows how to “mock” ActiveDirectory(LDAP) in ldif file so ActiveDirectoryLdapAuthenticationProvider could use it during authentication?
Advertisement
Answer
I had the same problem and found a solution that works, but I am not very happy with it. Here is how it works for me:
Adjust the
.ldif
fileAdd the
userPrincipalName
attribute to your.ldif
file and fill it with the same value as thedn
, in your case:dn: uid=john,ou=people,dc=test,dc=local userPrincipalName: uid=john,ou=people,dc=test,dc=local
Use the
dn
instead of the email address for authenticationYou use
john@test.local
in your test for authentication. To make it work, you have to use thedn
:uid=john,ou=people,dc=test,dc=local
After these changes, the authentication against embedded LDAP worked in the tests. Better solutions are welcome!