First of all, I'm new to the Java Spring Framework. So forgive me if I did not provide enough information. I tried adding RoleHierarchy to my application, but it did not work. Below are the codes I tried.
SecurityConfig.java
// These config is try to set up a user Role Hierarchy @Bean public RoleHierarchy roleHierarchy() { System.out.println("arrive public RoleHierarchy roleHierarchy()"); RoleHierarchyImpl r = new RoleHierarchyImpl(); r.setHierarchy("ROLE_ADMIN > ROLE_STAFF"); r.setHierarchy("ROLE_STAFF > ROLE_USER"); r.setHierarchy("ROLE_DEVELOPER > ROLE_USER"); r.setHierarchy("ROLE_USER > ROLE_GUEST"); return r; } @Bean public AffirmativeBased defaultAccessDecisionManager(RoleHierarchy roleHierarchy){ System.out.println("arrive public AffirmativeBased defaultAccessDecisionManager()"); List<AccessDecisionVoter> decisionVoters = new ArrayList<>(); // webExpressionVoter WebExpressionVoter webExpressionVoter = new WebExpressionVoter(); DefaultWebSecurityExpressionHandler expressionHandler = new DefaultWebSecurityExpressionHandler(); expressionHandler.setRoleHierarchy(roleHierarchy); webExpressionVoter.setExpressionHandler(expressionHandler); decisionVoters.add(webExpressionVoter); decisionVoters.add(roleHierarchyVoter(roleHierarchy)); // return new AffirmativeBased(Arrays.asList((AccessDecisionVoter) webExpressionVoter)); return new AffirmativeBased(decisionVoters); } @Bean public RoleHierarchyVoter roleHierarchyVoter(RoleHierarchy roleHierarchy) { System.out.println("arrive public RoleHierarchyVoter roleHierarchyVoter"); return new RoleHierarchyVoter(roleHierarchy); } @Override protected void configure(HttpSecurity http) throws Exception { // skipping some codes http // skipping some codes .accessDecisionManager(defaultAccessDecisionManager(roleHierarchy())) // skipping some codes }
MethodSecurityConfig.java
@Configuration @EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true) public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { @Inject private SecurityConfig securityConfig; @Override protected AuthenticationManager authenticationManager() throws Exception { return securityConfig.authenticationManagerBean(); } @Override protected MethodSecurityExpressionHandler createExpressionHandler() { System.out.println("arrive protected MethodSecurityExpressionHandler createExpressionHandler()"); DefaultMethodSecurityExpressionHandler d = new DefaultMethodSecurityExpressionHandler(); d.setRoleHierarchy(securityConfig.roleHierarchy()); return d; } }
And I have UserDetailsServiceImpl implements UserDetailsService that provide principal , Authentication and GrantedAuthority
Finally, I have some APIs:
@PreAuthorize("hasRole('ROLE_STAFF')") @RequestMapping(value = "/api/v1/contactUs", method = RequestMethod.GET) @PreAuthorize("hasRole('ROLE_DEVELOPER')") @RequestMapping(value = "/api/v1/system", method = RequestMethod.GET)
The problem now, if I log in as ROLE_STAFF, ROLE_DEVELOPER, ROLE_ADMIN, I got the following result.
| API | ROLE_STAFF | ROLE_DEVELOPER | ROLE_ADMIN | |-----------|------------|----------------|------------| | contactUs | 200 | 403 | 403 | | system | 403 | 200 | 403 |
As you can see, ROLE_STAFF and ROLE_DEVELOPER are working fine. But I want ROLE_ADMIN as a super-role of both, and that didn't work.
FYI, I am using spring-security 3.2.5.RELEASE