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

Labels: ,