0

I have Springboot successfully authenticating against LDAP and adding to the view a CustomUserDetails model.

During the authentication event I would like to also bring back additional details like email, telephone and city.

According to this SO answer it is possible and I think this also addresses it.

Despite reading both these answers I am still unsure how to proceed to do this - particularly about how steps 2 and 3 from the second answer relate, and where the details like email, city and telephone are mapped?

My security class:

Security

@SpringBootApplication
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {

@Autowired
private UserDetailsService userDetailsService;

@Override
public void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
                .anyRequest().fullyAuthenticated()
                .and()
            .formLogin()
                .defaultSuccessUrl("/newExhibit");
}

@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth
            .userDetailsService(userDetailsService)
            .and()
            .ldapAuthentication()
            .userDnPatterns("uid={0},ou=people")
            .groupSearchBase("ou=groups")
            .contextSource()
            .url("ldap://localhost:8389/dc=springframework,dc=org")
            .and()
            .passwordCompare()
            .passwordEncoder(passwordEncoder())
            .passwordAttribute("userPassword");
}

My user object from test-server.ldif

dn: uid=abc123,ou=people,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Tom Smith
sn: Smith
uid: abc123
userPassword: pass
mail: tom@contoso.com
mobile: +212 307 12345
st: CA

Following this answer do I need to add to auth
(a) contextsource and
(b) userDetailsContextMapper?

Ultimately these details from ldap I would like to map to my java user class.

UPDATE

An updated AuthenticationManagerBuilder

@SpringBootApplication
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {

@Autowired
private UserDetailsService userDetailsService;

@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth
        .userDetailsService(userDetailsService)
        .and()
        .ldapAuthentication()
        .userDnPatterns("uid={0},ou=people")
        .groupSearchBase("ou=groups")
        .contextSource()
        .userDetailsContextMapper(???) // what object in here and how initalised
        .url("ldap://localhost:8389/dc=springframework,dc=org")
        .and()
        .passwordCompare()
        .passwordEncoder(passwordEncoder())
        .passwordAttribute("userPassword");
}
Al Grant
  • 2,102
  • 1
  • 26
  • 49
  • You only need a customized `UserDetailsContextMapper` to retrieve and set the custom attributes. The `ContextSource` is created by how you are configuring Spring Security. – M. Deinum May 28 '19 at 09:19
  • @M.Deinum what would this UserDetailsContextMapper look like? – Al Grant May 28 '19 at 09:32
  • Looking at your LDIF file, you don't really need an custom mapper, but you might get away with the `InetOrgPersonContextMapper`, so `new InetOrgPersonContextMapper()`, probably would do the trick. As the `mail` and `mobile` properties are defined in the LDAP schema for `inetOrgPerson`. So unless you really have custom attributes you don't really need one. – M. Deinum May 28 '19 at 10:35

1 Answers1

1

Looking at your LDIF file I looks like you are trying to get the properties which are defined as part of the inetOrgPerson. Spring Security has an out-of-the-box mapper for this the InetOrgPersonContextMapper. This will map the defined properties to an InetOrgPerson, which will act as the UserDetails needed.

To configure you just need to create a new instance and wire it to your configuration.

@SpringBootApplication
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {


@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth
      .ldapAuthentication()
        .userDnPatterns("uid={0},ou=people")
        .groupSearchBase("ou=groups")
        .contextSource()
        .url("ldap://localhost:8389/dc=springframework,dc=org")
        .and()
        .userDetailsContextMapper(new InetOrgPersonContextMapper())
        .passwordCompare()
        .passwordEncoder(passwordEncoder())
        .passwordAttribute("userPassword");
}

This will map the properties accordingly. As you are using LDAP you don't need the UserDetailsService injected as it will automatically configure an LdapUserDetailsService underneath.

Community
  • 1
  • 1
M. Deinum
  • 115,695
  • 22
  • 220
  • 224