Wednesday, December 31, 2014

Homebrew LDAP authorization with Spring Security

Continuing my journey from previous post, I realize that although LDAP authentication has been done successfully, but the user were still have no roles being assign. For this issue, I'm require to implement a custom authorization mechanism in order to assign LDAP user a role.

I found there are plenty of resources on how could an LDAP user is map to a role:
  1. configure LdapAuthenticationProvider in Spring. (read here)
  2. configure user-context-mapper-ref and extends one class with DefaultLdapAuthoritiesPopulator (read here)
  3. confgiure user-context-mapper-ref and extends one class with LdapUserDetailsMapper (read here)
  4. configure BindAuthenticator constructor and implements one class with LdapAuthoritiesPopulator (read here)
Among those resources, I found option 3 would be the most suit for my use case since I don't have the role group define in LDAP. And my requirement is as long as I got the name huahsin detected, then grant him an ROLE_ADMIN. To put nonsense short, I created a class extending LdapUserDetailsMapper:
public class MyAuthorityMapper extends LdapUserDetailsMapper {
 
 @Override
 public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection authority) {
  
  UserDetails userDetails = super.mapUserFromContext(ctx, username, authority);
  
  Collection<grantedauthority> authorities = new ArrayList<grantedauthority>();
  
  if( "huahsin".equalsIgnoreCase(username) ) {
   authorities.add(new GrantedAuthorityImpl("ROLE_ADMIN"));
  }
  else {
   authorities.add(new GrantedAuthorityImpl("ROLE_USER"));
  }
  
  return new User(userDetails.getUsername(), 
    userDetails.getPassword(),
    true,
    true,
    true,
    true,
    authorities);
 }
 
}
ROLE_ADMIN and ROLE_USER shown in the code snippet above is hard coded sample on how the authority is granted. In real life, the role should obtain from other source such as database. On Spring configuration site, I will have this:
    <authentication-manager alias="authenticationManager">

        <ldap-authentication-provider user-search-filter="cn={0}" group-search-base="ou=Counter Strike,ou=java,dc=homebrew,dc=org" user-context-mapper-ref="myAuthorityMapper"/>

    </authentication-manager>

    <beans:bean class="org.huahsin.WebEngineering.MyAuthorityMapper" id="myAuthorityMapper"/>

    <ldap-server url="ldap://127.0.0.1:10389"/>

No comments: