Reputation: 61
In Spring Boot 2.7.x , I used the RoleHierarchyVoter
public RoleHierarchy roleHierarchy() {
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
roleHierarchy.setHierarchy("ROLE_ADMINISTRATOR > ROLE_USER > ROLE_GUEST");
return roleHierarchy;
}
@Bean
public RoleHierarchyVoter roleVoter() {
return new RoleHierarchyVoter(roleHierarchy());
}
In Spring Boot 3.x AccessDecisionVoter
are deprecated - the use of AuthorizationManager
is recommended. Is there any posibility to use an AuthorizationManager-Implementation to set a role hierarchy? The usage of
@Bean
AccessDecisionVoter hierarchyVoter() {
RoleHierarchy hierarchy = new RoleHierarchyImpl();
hierarchy.setHierarchy("ROLE_ADMIN > ROLE_STAFF > ROLE_USER" +
"ROLE_USER > ROLE_GUEST");
return new RoleHierarchyVoter(hierarchy);
}
did not work since I use the AuthorizationFilter
.
Upvotes: 6
Views: 5238
Reputation: 15729
Simply exposing a expressionHandler
bean should do the job.
If you use method security (@EnableMethodSecurity
) :
@Bean
public RoleHierarchyImpl roleHierarchy() {
final RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_STAFF > ROLE_USER > ROLE_GUEST");
return roleHierarchy;
}
@Bean
public DefaultMethodSecurityExpressionHandler expressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
expressionHandler.setRoleHierarchy(roleHierarchy());
return expressionHandler;
}
If you use web security (@EnableWebSecurity
) :
@Bean
public RoleHierarchyImpl roleHierarchy() {
final RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_STAFF > ROLE_USER > ROLE_GUEST");
return roleHierarchy;
}
@Bean
public DefaultWebSecurityExpressionHandler expressionHandler() {
DefaultWebSecurityExpressionHandler expressionHandler = new DefaultWebSecurityExpressionHandler();
expressionHandler.setRoleHierarchy(roleHierarchy());
return expressionHandler;
}
EDIT
setHierarchy
is deprecated since 7.0, you can now directly use :
return RoleHierarchyImpl.fromHierarchy("ROLE_ADMIN > ROLE_STAFF > ROLE_USER > ROLE_GUEST");
Upvotes: 2
Reputation: 1552
First, you create and instance of AuthorizationManager
:
var access = AuthorityAuthorizationManager.<RequestAuthorizationContext>hasRole("USER");
This instance will be used to authorize our endpoints. So in the hasRole
method, provide the name of your role or roles you want to use to protect a specific endpoint.
Second, you define your role hierarchy:
var hierarchy = new RoleHierarchyImpl();
hierarchy.setHierarchy("ROLE_ADMIN > ROLE_USER");
In this case we are defining that ROLE_ADMIN
is above ROLE_USER
, so ROLE_ADMIN
has the same role as an ROLE_USER
.
Third, we set the RoleHierarcy
instance in the AuthorizationManager
instance:
access.setRoleHierarchy(hierarchy);
Finally, we set the AuthorizationManager
instance in our route protection configuration. So all the code togheter would look like this:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
var access = AuthorityAuthorizationManager.<RequestAuthorizationContext>hasRole("USER");
var hierarchy = new RoleHierarchyImpl();
hierarchy.setHierarchy("ROLE_ADMIN > ROLE_USER");
access.setRoleHierarchy(hierarchy);
http.authorizeHttpRequests(authorize -> authorize.anyRequest().access(access));
return http.build();
}
Upvotes: 0