When updating to Spring Security 6, the JSR250 annotation @RolesAllowed on my @RestController doesn't take the defined roleHierarchy into account.
Related to: AccessDecisionVoter Deprecated with Spring Security 6.x
Since Spring Security 6, the AccessDecisionVoter is deprecated and the suggested way, from the thread above, is to "simply expose a expressionHandler". This didn't work for me with JSR250 enabled.
@Bean
public DefaultMethodSecurityExpressionHandler expressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
expressionHandler.setRoleHierarchy(roleHierarchy());
return expressionHandler;
}
@Bean
public RoleHierarchy roleHierarchy() {
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
String hierarchy = "a > b";
roleHierarchy.setHierarchy(hierarchy);
return roleHierarchy;
}
It seems like the created AuthorityAuthorizationManager by Jsr250AuthorizationManagerRegistry.resolveManager for RolesAllowed doesn't take the expressionHandler nor DefaultMethodSecurityExpressionHandler into account.
The AuthorityAuthorizationManager does have a field for a roleHierarchy to be set, but I couldn't figure out how or when this is supposed to be called.
I would have commented on the related post above but unfortunately I don't have the required reputation.
Unfortunately there is no support to add role hierarchy to JSR250 manager. But there is a workaround that basically clones the library's implementation. At this point it makes more sense to drop JSR250 since you will be just replicating the logic from the libs to your code base, but if you want to do it anyway, just follow these instructions:
You can just copy and paste the code above into a new class in your code, this is a class that I made myself based on the one that exists in the spring security lib.
Advisor:@EnableMethodSecurity(jsr250Enabled = true), you will also need to add this configuration to yourapplication.properties:This will allow to override a bean that is defined in the security lib that deals with JSR250 annotations. Because this bean's configuration is hardcoded in the lib wihtout exposing a way to change it, we have to override it altogheter to add the behavior we need. Note that the name of your bean needs to be
jsr250AuthorizationMethodInterceptorto override the one (with same name) from the security lib. If you remove thejsr250Enabledconfiguration fromEnableMethodSecurity, then you can name your bean anything you want and remove the configuration fromapplication.properties.