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
jsr250AuthorizationMethodInterceptor
to override the one (with same name) from the security lib. If you remove thejsr250Enabled
configuration fromEnableMethodSecurity
, then you can name your bean anything you want and remove the configuration fromapplication.properties
.