14

I am using the Spring Security ActiveDirectoryLdapAuthenticationProvider with Spring Boot (annotation based config) to authenticate with Active Directory and generate tokens. All works fine.

I wish to add some integration tests that simulate the whole process, and I was thinking of maybe using the Spring embedded LDAP server for that.

I added this ldif file that I got from another example I found online.

#Actual test data

dn: dc=test,dc=com
objectclass: top
objectclass: domain
objectclass: extensibleObject
dc: local

# Organizational Units
dn: ou=groups,dc=test,dc=com
objectclass: top
objectclass: organizationalUnit
ou: groups

dn: ou=people,dc=test,dc=com
objectclass: top
objectclass: organizationalUnit
ou: people

# Create People
dn: uid=testuser,ou=people,dc=test,dc=com
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Test
sn: User
uid: testuser
password: secret

# Create Groups
dn: cn=developers,ou=groups,dc=test,dc=com
objectclass: top
objectclass: groupOfUniqueNames
cn: developers
ou: developer
uniqueMember: uid=testuser,ou=people,dc=test,dc=com

dn: cn=managers,ou=groups,dc=test,dc=com
objectclass: top
objectclass: groupOfUniqueNames
cn: managers
ou: manager
uniqueMember: uid=testuser,ou=people,dc=test,dc=com

But this of course does not include any of the Active Directory schema stuff. Each user needs to have a sAMAccountName and needs to have the memberOf attribute to determine which groups it is in.

Is there any way to make this behave similar to active directory so that the Spring ActiveDirectoryLdapAuthenticationProvider binds to it with the user's username and password and gets its group membership to populate its authorities?

Otherwise if this is not viable, is there any other way to mock this and have a proper test?

jbx
  • 21,365
  • 18
  • 90
  • 144
  • How did you end-up writing integration tests – ravthiru May 20 '20 at 13:08
  • @ravthiru Unfortunately I didn't, and just tested it against the real thing (Active Directory). Not ideal, but I was too tight on time to keep wasting time going around in circles on this. – jbx May 21 '20 at 00:04
  • Thanks for reply, looks like there is no easy way to do.I spent a day looking for it. – ravthiru May 21 '20 at 00:13
  • Have you tried using TestContainers instead? Because it automatically creates a docker image to run your integration tests and is binded to their lifecycle you would be able to customise it as you want. It supports most configurations and even reading docker-compose files. https://www.testcontainers.org/features/creating_container/ – Sara Jun 10 '20 at 13:13
  • @Sara no i haven't, but sounds a bit too heavy weight to run with each build in the unit tests. is it slow? – jbx Jun 10 '20 at 20:41
  • because it should be only used in a single integration test class per module, although a bit slower than an embedded component it's not problematic usually. the first time you run it in a build it will be slower because it will require the docker image to download. :) Overall it has been growing quite popular over embedded components specially to replace embedded databases but in this cases it's also quite useful – Sara Jun 11 '20 at 01:04
  • @jbx it will take some time to instantiate and start docker container but what you´ll get is an integration testing on an environment very close to the real one which will be used in production (off course, you'll need sometime to set it up correctly and in a way you need it). – Dmitriy Jul 16 '20 at 18:32

1 Answers1

3

You could use spring ldap-testing dependency which provides an Apache DS to setup an embedded ldap server. See

article: https://www.baeldung.com/spring-ldap#testing

sources: https://github.com/eugenp/tutorials/blob/master/spring-security-modules/spring-security-ldap/src/test/java/com/baeldung/ldap/javaconfig/TestConfig.java

Other in Memory LDAP Java implementation that you can use are: https://docs.ldap.com/ldap-sdk/docs/in-memory-directory-server.html

// Create the configuration to use for the server.
InMemoryDirectoryServerConfig config =
     new InMemoryDirectoryServerConfig("dc=example,dc=com");
config.addAdditionalBindCredentials("cn=Directory Manager", "password");

// Create the directory server instance, populate it with data from the
// "test-data.ldif" file, and start listening for client connections.
InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config);
ds.importFromLDIF(true, "test-data.ldif");
ds.startListening();

Or: https://github.com/inbloom/ldap-in-memory

You could also use a full blown ldap server inside a testcontainer if you prefer a more production like scenario.

Andi
  • 131
  • 1
  • 10
  • Link offline: https://github.com/eugenp/tutorials/blob/master/spring-ldap/src/test/java/com/baeldung/ldap/javaconfig/TestConfig.java – JRichardsz Feb 01 '23 at 15:56
  • The LDAP framework provided by PingIdentity (referenced in this answer) seems to be well maintained and potentially useful for testing: https://github.com/pingidentity/ldapsdk – Robert Feb 10 '23 at 15:35
  • updated the source link to https://github.com/eugenp/tutorials/blob/master/spring-security-modules/spring-security-ldap/src/test/java/com/baeldung/ldap/javaconfig/TestConfig.java – Andi Feb 12 '23 at 23:00