Skip to content

Proof of Spring Boot app with LDAP authentication and groups and users management

License

Notifications You must be signed in to change notification settings

DISID/disid-proof-ldap

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

56 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

disid-proof-ldap

Requirements to provide in this proof

  • ❏ Integrate the Spring LDAP related utilities:

    • [X] Spring LDAP

    • -[ ] Spring Data LDAP- (not needed)

    • [X] Spring Security LDAP

  • [X] Provide authentication over an LDAP server using Spring Security LDAP

  • [X] Provide authentication for an administrator user stored in the local database, which will have priority over any other user with the same id defined in the LDAP server.

  • [X] Integrate and test with an embedded LDAP server for testing and also to be used with the dev profile.

  • ❏ Integrate and test with an external LDAP server for the default production profile (TODO: which external LDAP server to test?).

  • [X] Synchronization of groups data with the LDAP server.

  • [X] Synchronization of users data with the LDAP server.

  • ❏ Create/update and delete groups stored in the LDAP server.

  • [X] Create/update and delete users stored in the LDAP server and additional information located in the local database. This includes setting or updating the users password.

  • [X] Load local database user information to the UserDetails when authenticating to LDAP

  • ❏ Configurable properties to:

    • [X] Connect to the LDAP server

    • [X] Filter groups from the LDAP server

    • [X] Filter users from the LDAP server

    • [X] Uniquely identification of single users

    • [X] Display users information

  • ❏ Document the meaning and when to use the LDAP properties.

Steps performed

Integrate LDAP authentication following the Spring guide

  • Upgrade to Spring IO platform Brussels-SR4 to auto-run the embedded LDAP server.

  • Add the properties to run the embedded LDAP server in the 'dev' profile:

spring.ldap.embedded.ldif=classpath:test-server.ldif
spring.ldap.embedded.base-dn=dc=springframework,dc=org
spring.ldap.embedded.port=8389
  • Add additional dependencies:

  	<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.ldap</groupId>
        <artifactId>spring-ldap-core</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-ldap</artifactId>
    </dependency>
    <dependency>
        <groupId>com.unboundid</groupId>
        <artifactId>unboundid-ldapsdk</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-test</artifactId>
        <scope>test</scope>
    </dependency>
  • Create WebSecurityConfig class with the guide contents.

  • Create src/main/resources/test-server.ldif file with the guide contents.

  • Create SecurityIT class for integration testing. Make it run with the dev profile.

Test multiple authentication method support

  • Test multiple authentication method support for the local administrator user in memory, by updating the WebSecurityConfig class with:

  public void configure( AuthenticationManagerBuilder auth ) throws Exception
  {

    // To have many authentication options, just add them to the AuthenticationManagerBuilder in
    // the order to be checked

    auth.inMemoryAuthentication().withUser( "user" ).password( "password" ).roles( "USER" ).and().withUser( "admin" )
        .password( "password" ).roles( "USER", "ADMIN" );

    auth.ldapAuthentication().userDnPatterns( "uid={0},ou=people" ).groupSearchBase( "ou=groups" )
        .contextSource( contextSource() ).passwordCompare().passwordEncoder( new LdapShaPasswordEncoder() )
        .passwordAttribute( "userPassword" );
  }

Add support to store the local administrator user in the application database

  • Create a new entity (AdminUser) to store the administration user password.

  • Generate related repository and service. Add new method to the repository:

AdminUser findByLogin( String login );
  • Create the AdminUserDetails class.

  • Make the AdminUserService implement UserDetailsService.

  • Replace in memory authentication with a DaoAuthenticationProvider using the AdminUserService in the WebSecurityConfig.

Make the LDAP connection configurable

  • Create a LdapProperties class annotated with @ConfigurationProperties.

  • Create a LdapConfiguration class to initialize the DefaultSpringSecurityContextSource from the LdapProperties.

  • Remove the creation of the ldap context in WebSecurityConfig.

Make LDAP authentication properties configurable

  • Add additional properties to LdapProperties and the application*.properties files.

  • Use the LdapProperties component in the WebSecurityConfiguration in the configuration of the LDAP authentication.

Which property to use as …​

Unique to identify users/groups

From the documentation, LDAP by itself doesn’t define a single property to be unique. What it defines to be unique is the DN (Distinguished Name), which is a combination of properties of an LDAP entry and its parent entries that uniquely identifies it (see https://stackoverflow.com/questions/7814569/what-do-people-use-for-cn-with-inetorgperson-in-ldap-directories or https://stackoverflow.com/questions/18756688/what-are-cn-ou-dc-in-an-ldap-search)

If a property must be unique between sibling entries, it is usually something controlled at a higher level. In the case of persons, this is usually the case of the cn (Common Name) property. In Active Directory, for example, the property sAMAccountName is unique in all principal objects of the same domain (see https://blogs.msdn.microsoft.com/openspecification/2009/07/10/understanding-unique-attributes-in-active-directory/).

Taking into account all this information, which is the property most suitable to be used as a unique identifier? To be absolutely sure the DN would have to be used. But if the list of users to used are all included under the same LDAP entry, a property unique between them is enough. This is the usual case, and the parent entry is defined in the LDAP connection properties like the BaseDN and the UserDN.

One of the properties usually used in this case is the cn, although it should be a configurable property, just in case the LDAP server data is using another one, like uid or sAMAccountName.

In the case of groups or profiles, to identify them the cn field (configurable) will be used, as well as the group (configurable) objectClass.

Display users/groups name

TODO

Relate users and groups

TODO

Reference documentation

Technical references

LDAP documentation

*

About

Proof of Spring Boot app with LDAP authentication and groups and users management

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published