Spring Security角色层次结构@Secured JavaConfig
问题描述:
我遇到了一些问题,试图在Spring Security中使用JavaConfig而不是XML实现角色层次结构。有没有办法用@Secured注解而不是HttpSecurity antMatchers实现角色层次结构?我似乎无法将角色层次结构添加到HttpSecurity中,但没有提供正确的String模式,尽管我希望能够仅使用@Secured做出访问决策。Spring Security角色层次结构@Secured JavaConfig
java.lang.IllegalStateException: At least one mapping is required (i.e. authorizeRequests().anyRequest.authenticated())
@Bean
public RoleHierarchyImpl roleHierarchy() {
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_USER");
return roleHierarchy;
}
private SecurityExpressionHandler<FilterInvocation> webExpressionHandler() {
DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
defaultWebSecurityExpressionHandler.setRoleHierarchy(roleHierarchy());
return defaultWebSecurityExpressionHandler;
}
public void configure(HttpSecurity http){
http.authorizeRequests().expressionHandler(webExpressionHandler()).and().//other stuff
}
对此非常感谢。
答
我也希望有一个使用@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://*.com/questions/29888458/spring-security-role-hierarchy-not-working-using-java-config,但有什么办法可以摆脱antMatchers,因为我只是想使用@Secured注释 – Lukehey