Using spring embedded ldap to simulate active directory for integration tests
Asked Answered
M

1

15

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?

Maintain answered 9/10, 2017 at 8:25 Comment(7)
How did you end-up writing integration testsStair
@Stair 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.Maintain
Thanks for reply, looks like there is no easy way to do.I spent a day looking for it.Stair
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. testcontainers.org/features/creating_containerHendrick
@Hendrick no i haven't, but sounds a bit too heavy weight to run with each build in the unit tests. is it slow?Maintain
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 usefulHendrick
@Maintain 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).Boothman
H
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.

Hands answered 19/12, 2020 at 21:55 Comment(3)
Link offline: github.com/eugenp/tutorials/blob/master/spring-ldap/src/test/…Goldengoldenberg
The LDAP framework provided by PingIdentity (referenced in this answer) seems to be well maintained and potentially useful for testing: github.com/pingidentity/ldapsdkTasman
updated the source link to github.com/eugenp/tutorials/blob/master/spring-security-modules/…Hands

© 2022 - 2024 — McMap. All rights reserved.