Erstens, ich bin neu in Java Spring Framework. Also vergib mir, wenn ich nicht genug Informationen zur Verfügung stelle. Ich habe versucht, RoleHierarchy in meine App hinzuzufügen, aber es hat nicht funktioniert. Unten sind die Codes, die ich versucht habe.Spring Sicherheitsrollenhierarchie funktioniert nicht mit Java Config
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;
}
}
Und Ich habe eine UserDetailsServiceImpl implements UserDetailsService
vorsehen, dass die principal
, Authentication
und GrantedAuthority
Schließlich habe ich einige 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)
Das Problem ist jetzt, wenn ich als ROLE_STAFF anmelden, ROLE_DEVELOPER, ROLE_ADMIN, bekam ich folgende Ergebnis.
| API | ROLE_STAFF | ROLE_DEVELOPER | ROLE_ADMIN |
|-----------|------------|----------------|------------|
| contactUs | 200 | 403 | 403 |
| system | 403 | 200 | 403 |
Wie Sie ROLE_STAFF
und ROLE_DEVELOPER
gut funktionieren sehen. Aber ich möchte ROLE_ADMIN
als eine super Rolle von beiden und es hat nicht funktioniert.
FYI, ich bin mit feder Sicherheit 3.2.5.RELEASE
Beachten Sie, dass die Verwendung von "und" optional ist. Für Spring "" ROLE_ADMIN> ROLE_STAFF und ROLE_ADMIN "entspricht" "ROLE_ADMIN> ROLE_STAFF ROLE_ADMIN". Ich bevorzuge Ihre Notation aber nur sagen – kiedysktos
Das funktioniert auch, wenn es optionale Syntax verwendet. Es wäre schön, wenn es eine Art Syntax-Ausnahme auslösen würde, weil ich 'A> B> C' –