我也希望有一個使用@Secured註釋的角色層次結構。發現它非常棘手,但最終有一個以下的解決方案(groovy代碼)。
定義你的選民和決定經理@Configuration類:
@Bean
public static RoleHierarchy roleHierarchy() {
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl()
roleHierarchy.setHierarchy("""\
$SUPER_ADMIN > $ORGANIZATION_ADMIN
$ORGANIZATION_ADMIN > $DOCTOR
$DOCTOR > $NURSE
$NURSE > $PATIENT
$PATIENT > $USER""".stripIndent())
roleHierarchy
}
@Bean
public static RoleHierarchyVoter roleVoter() {
new RoleHierarchyVoter(roleHierarchy())
}
@Bean
public AffirmativeBased accessDecisionManager() {
List<AccessDecisionVoter> decisionVoters = new ArrayList<>();
decisionVoters.add(webExpressionVoter());
decisionVoters.add(roleVoter());
new AffirmativeBased(decisionVoters);
}
private WebExpressionVoter webExpressionVoter() {
WebExpressionVoter webExpressionVoter = new WebExpressionVoter()
webExpressionVoter.setExpressionHandler(expressionHandler())
webExpressionVoter
}
@Bean
public DefaultWebSecurityExpressionHandler expressionHandler(){
DefaultWebSecurityExpressionHandler expressionHandler = new DefaultWebSecurityExpressionHandler();
expressionHandler.setRoleHierarchy(roleHierarchy());
return expressionHandler;
}
然後在安全性配置中添加的決策管理器:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
...
.and()
.authorizeRequests()
.accessDecisionManager(accessDecisionManager())
.antMatchers("/auth").permitAll()
...
}
然後,你還必須覆蓋GlobalMethodSecurityConfiguration也使用RoleHierarchyVoter:
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
new DefaultMethodSecurityExpressionHandler(roleHierarchy: SecurityConfiguration.roleHierarchy())
}
@Override
protected AccessDecisionManager accessDecisionManager() {
AffirmativeBased manager = super.accessDecisionManager() as AffirmativeBased
manager.decisionVoters.clear()
manager.decisionVoters << SecurityConfiguration.roleVoter()
manager
}
}
我是刪除其他選民,只需在AccessDecisionManager中添加我的RoleHierarchyVoter,但如果需要,您可以保留其他選民。在我的情況下,我只使用@Secured註釋,因此不需要其他人。這是在任何地方都沒有提到的使用@Secured註釋工作的部分。
另一種解決方案就是創建一個RoleHierarchy豆與層次配置,並將其注入到您的自定義驗證過濾器,你會認證用戶,並通過有關部門通過調用UsernamePasswordAuthenticationToken:
roleHierarchy.getReachableGrantedAuthorities(authorityFromUserDetails)
這第二如果您不使用任何自定義授權,解決方案有點棘手,但在我的情況下,它更簡單。
你的RoleHierarchyImpl是什麼樣的? – Stefan
編輯我的文章。大部分使用http://stackoverflow.com/questions/29888458/spring-security-role-hierarchy-not-working-using-java-config,但有什麼辦法可以擺脫antMatchers,因爲我只是想使用@Secured註釋 – Lukehey