【问题标题】:Spring Security role hierarchy @Secured JavaConfigSpring Security 角色层次结构@Secured JavaConfig
【发布时间】:2016-01-03 09:24:36
【问题描述】:

我在尝试使用 JavaConfig 而不是 XML 在 Spring Security 中实现角色层次结构时遇到了一些问题。有没有办法使用 @Secured 注释而不是 HttpSecurity antMatchers 来实现角色层次结构?如果不提供正确的字符串模式,我似乎无法将角色层次结构添加到 HttpSecurity,但我希望能够仅使用 @Secured 做出访问决策。

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
}

非常感谢您对此的任何帮助。

【问题讨论】:

  • 你的 RoleHierarchyImpl 是什么样的?
  • 编辑了我的帖子。主要关注stackoverflow.com/questions/29888458/…,但有什么办法可以摆脱antMatchers,因为我只想使用@Secured 注释

标签: java spring spring-security


【解决方案1】:

我还想使用@Secured 注解来创建角色层次结构。发现它真的很棘手,但最终有一个以下解决方案(groovy code)。

在@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 bean,并将其注入您的自定义身份验证过滤器中,您将在其中对用户进行身份验证并将权限传递给 UsernamePasswordAuthenticationToken 通过调用:

roleHierarchy.getReachableGrantedAuthorities(authorityFromUserDetails)

如果您不使用任何自定义授权,则第二种解决方案有点棘手,但在我的情况下它更简单。

【讨论】:

    猜你喜欢
    • 2012-12-01
    • 2019-06-21
    • 2011-11-21
    • 2011-11-03
    • 2013-10-31
    • 1970-01-01
    • 2016-09-06
    • 2014-11-13
    • 2011-01-31
    相关资源
    最近更新 更多