authenticationspring-securityspring-ldap

Getting CN entry of an authenticated ldap user


I'm doing my first steps on LDAP with spring boot. I have managed to authenticate my user which is listed in my ldif file:

dn: dc=parascus,dc=de
objectclass: top
objectclass: domain
objectclass: extensibleObject
dc: parascus

dn: ou=groups,dc=parascus,dc=de
objectclass: top
objectclass: organizationalUnit
ou: groups

dn: ou=people,dc=parascus,dc=de
objectclass: top
objectclass: organizationalUnit
ou: people

dn: uid=jsmith,ou=people,dc=parascus,dc=de
objectclass: top
objectclass: person
objectclass: inetOrgPerson
cn: Smith, John
sn: Smith
uid: jsmith
userPassword: scrambled

dn: cn=developers,ou=groups,dc=parascus,dc=de
objectclass: top
objectclass: groupOfUniqueNames
cn: developers
ou: developer
uniqueMember: uid=jsmith,ou=people,dc=parascus,dc=de

Now I'm in my controller method and try to get the cn property "Smith, John":

@GetMapping("/profile")
public String index(Authentication authentication) {
    return "Profile of " + authentication.getName();
}

But I only get the uid "jsmith". Can somebody give me a hint how I can get all the information or at last the cn entry?

Kind Regards

Parascus


Solution

  • You will need to supply a UserDetailsContextMapper to tell Spring Security how to extract details from the DirContext.

    You do this when exposing the LdapAuthenticationProvider:

    @Bean
    LdapAuthenticationProvider ldap(LdapAuthenticator authenticator) {
        LdapAuthenticationProvider ldap = new LdapAuthenticationProvider(authenticator);
        ldap.setUserDetailsContextMapper(new PersonContextMapper());
        return ldap;
    }
    

    Spring Security ships with a couple of built-in context mappers, one for the person schema (PersonContextMapper) and another for the inetOrgPerson schema (InetOrgPersonContextMapper).

    With the above configuration, you can do either:

    public String index(Authentication authentication) {
        Person person = (Person) authentication.getPrincipal();
        String[] cn = person.getCn();
        return "Profile of " + cn[cn.length - 1];
    }
    

    or

    public String index(@AuthenticationPrincipal Person person) {
        String[] cn = person.getCn();
        return "Profile of " + cn[cn.length - 1];
    }
    

    If your entries use neither the person nor the inetOrgPerson schema, you can create your own UserDetailsContextMapper.