Implementing a role hierarchy in Spring Security (Java config style)

From http://static.springsource.org/spring-security/site/docs/3.1.x/reference/authz-arch.html:

It is a common requirement that a particular role in an application should automatically “include” other roles. For example, in an application which has the concept of an “admin” and a “user” role, you may want an admin to be able to do everything a normal user can.

To achieve this, you can either make sure that all admin users are also assigned the “user” role. Alternatively, you can modify every access constraint which requires the “user” role to also include the “admin” role. This can get quite complicated if you have a lot of different roles in your application.

The use of a role-hierarchy allows you to configure which roles (or authorities) should include others. An extended version of Spring Security’s RoleVoter, RoleHierarchyVoter, is configured with a RoleHierarchy, from which it obtains all the “reachable authorities” which the user is assigned. A typical configuration might look like this” (in Java config style):

 @Bean
 public RoleHierarchy roleHierarchy() {
  RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
  roleHierarchy.setHierarchy(environment
    .getProperty("security.rolesHierarchy"));
  return roleHierarchy;
 }

 @Bean
 public RoleVoter roleVoter() {
  return new RoleHierarchyVoter(roleHierarchy());
 }

With security.rolesHierarchy=ADMIN > PREMIUM PREMIUM > USER USER > GUEST

But then, if you want to use your custom roles hierarchy in your security expressions or in all your authentication providers, you have to inject the roleHierarchy in all these beans:

@Configuration
@ImportResource("classpath:spring/security.xml")
@ComponentScan(basePackages = Constants.SECURITY_PACKAGE)
public class SecurityConfig {

 private final static Logger LOGGER = LoggerFactory
   .getLogger(SecurityConfig.class);

 @Inject
 private List<DaoAuthenticationProvider> authenticationProviders;

 @Inject
 private Environment environment;

 @Inject
 private Map<String, AbstractSecurityExpressionHandler<?>> handlers;

 @Bean
 public RoleHierarchy roleHierarchy() {
  RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
  roleHierarchy.setHierarchy(environment
    .getProperty("security.rolesHierarchy"));
  for (DaoAuthenticationProvider authenticationProvider : authenticationProviders) {
   authenticationProvider
     .setAuthoritiesMapper(new RoleHierarchyAuthoritiesMapper(
       roleHierarchy));
  }

  for (Entry<String, AbstractSecurityExpressionHandler<?>> handler : handlers
    .entrySet()) {
   handler.getValue().setRoleHierarchy(roleHierarchy);
   LOGGER.debug("Setting roleHierarhy for expressionHandler {}",
     handler.getKey());
  }
  return roleHierarchy;
 }

 @Bean
 public RoleVoter roleVoter() {
  return new RoleHierarchyVoter(roleHierarchy());
 }
}

Links:
http://static.springsource.org/spring-security/site/docs/3.1.x/reference/authz-arch.html

Related Posts

Leave a comment

About privacy:

This site uses Akismet to reduce spam. Learn how your comment data is processed.