Search code examples
spring-securityapachedsspring-security-ldapldif

Granting an ADMIN role to a user in a ldif file


For a test environment, I have an .ldif file to grant the ben user, the ADMIN role, as this role is required by my Spring security configuation: .hasRole("ADMIN").anyRequest().

Here is the .ldif file content:

dn: ou=groups,dc=springframework,dc=org
objectclass: top
objectclass: organizationalUnit
ou: groups

dn: ou=people,dc=springframework,dc=org
objectclass: top
objectclass: organizationalUnit
ou: people

dn: uid=ben,ou=people,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Ben LeHeros
sn: Ben
uid: ben
userPassword: {SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=

dn: uid=toto,ou=people,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Toto LeHeros
sn: Toto
uid: toto
userPassword: totopass

dn: cn=adMIN,ou=groups,dc=springframework,dc=org
objectclass: top
objectclass: groupOfNames
cn: ADMin
uniqueMember: uid=ben,ou=people,dc=springframework,dc=org

dn: cn=user,ou=groups,dc=baeldung,dc=com
objectclass: top
objectclass: groupOfNames
cn: user
member: uid=toto,ou=people,dc=springframework,dc=org

The test environment Spring Security configuration is the following:

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
        throws Exception {
    auth
    .ldapAuthentication()
        .userDnPatterns("uid={0},ou=people")
        .groupSearchBase("ou=groups")
        .contextSource().ldif("classpath:test-server.ldif");
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable().httpBasic()
            .authenticationEntryPoint(restAuthenticationEntryPoint).and()
            .authorizeRequests().antMatchers("/**")
            .hasRole("ADMIN").anyRequest()
            .authenticated();
}

There are a few observations:

1- The test is successful and the user is authenticated and accredited as having the admin role.

2- If instead of configuring the role accreditation as .hasRole("ADMIN").anyRequest() I do it as .hasRole("admin").anyRequest() then the user role given in the test is not accepted and the test fails with a 403 (not a 401) upon authentication.

3- The case does not seem to matter in the .ldif file as the admin group can be written as adMIN and ADMin and the test is still successful.

4- Replacing the admin group by a user group for the user, makes the test fails with a 403, that is, the user requires an admin role to be logged in.

dn: cn=user,ou=groups,dc=springframework,dc=org
objectclass: top
objectclass: groupOfNames
cn: user
uniqueMember: uid=ben,ou=people,dc=springframework,dc=org

How come the case does not matter in the .ldif file and matters in the configure method ?


Solution

  • Per Directory Server schema (that are the defined attributes and objectclasses) the attributes to build the Distinguished Name (DN) of the group entry are defined as case-ignore (DN "spec" https://www.rfc-editor.org/rfc/rfc4514).

    Personally I would consider it as a bug that the hasRole(..) matches in a case-sensitive way. However I think this is the case because the DefaultLdapAuthoritiesPopulator defaults to convertToUpperCase to true