如何使用JavaConfig从Spring Security中删除ROLE_前缀?

Mat*_*ble 11 spring spring-security spring-java-config

我正在尝试删除Spring Security中的"ROLE_"前缀.我尝试的第一件事是:

http.servletApi().rolePrefix("");
Run Code Online (Sandbox Code Playgroud)

这没用,所以我尝试BeanPostProcessorhttp://docs.spring.io/spring-security/site/migrate/current/3-to-4/html5/migrate-3-to-4-中的建议创建一个jc.html#m3to4-role-prefixing-disable.那也行不通.

最后,我尝试创建自己的SecurityExpressionHandler:

  @Override
  protected void configure(HttpSecurity http) throws Exception {
      http
          .authorizeRequests()
          .expressionHandler(webExpressionHandler())
          .antMatchers("/restricted").fullyAuthenticated()
          .antMatchers("/foo").hasRole("mycustomrolename")
          .antMatchers("/**").permitAll();
  }

  private SecurityExpressionHandler<FilterInvocation> webExpressionHandler() {
      DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
      defaultWebSecurityExpressionHandler.setDefaultRolePrefix("");
      return defaultWebSecurityExpressionHandler;
  }
Run Code Online (Sandbox Code Playgroud)

但是,这也不起作用.如果我使用"hasAuthority(roleName)"而不是hasRole,它按预期工作.

是否可以从Spring Security的hasRole检查中删除ROLE_前缀?

小智 19

从Spring 4.2开始,您可以使用单个bean定义前缀,如下所述:https://github.com/spring-projects/spring-security/issues/4134

@Bean
GrantedAuthorityDefaults grantedAuthorityDefaults() {
    return new GrantedAuthorityDefaults(""); // Remove the ROLE_ prefix
}
Run Code Online (Sandbox Code Playgroud)

XML版本:

<beans:bean id="grantedAuthorityDefaults" class="org.springframework.security.config.core.GrantedAuthorityDefaults">
    <beans:constructor-arg value="" />
</beans:bean>
Run Code Online (Sandbox Code Playgroud)

  • 没有为我工作 (3认同)

wal*_*lsh 8

以下配置适用于我.

@Override
public void configure(WebSecurity web) throws Exception {
    web.expressionHandler(new DefaultWebSecurityExpressionHandler() {
        @Override
        protected SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, FilterInvocation fi) {
            WebSecurityExpressionRoot root = (WebSecurityExpressionRoot) super.createSecurityExpressionRoot(authentication, fi);
            root.setDefaultRolePrefix(""); //remove the prefix ROLE_
            return root;
        }
    });
}
Run Code Online (Sandbox Code Playgroud)


Jef*_*ets 6

它出现的新GrantedAuthorityDefaults会更改前缀DefaultWebSecurityExpressionHandlerDefaultMethodSecurityExpressionHandler,但不会修改RoleVoter.rolePrefix这是从设置@EnableGlobalMethodSecurity

RoleVoter.rolePrefix 是用于@Secured("ADMIN")方法安全性的样式。

因此,除此之外GrantedAuthorityDefaults,我还必须添加此类CustomGlobalMethodSecurity以覆盖RoleVoter.

@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class CustomGlobalMethodSecurity extends GlobalMethodSecurityConfiguration {

    protected AccessDecisionManager accessDecisionManager() {
        AffirmativeBased accessDecisionManager = (AffirmativeBased) super.accessDecisionManager();

        //Remove the ROLE_ prefix from RoleVoter for @Secured and hasRole checks on methods
        accessDecisionManager.getDecisionVoters().stream()
                .filter(RoleVoter.class::isInstance)
                .map(RoleVoter.class::cast)
                .forEach(it -> it.setRolePrefix(""));

        return accessDecisionManager;
    }
}
Run Code Online (Sandbox Code Playgroud)


Pio*_*pes 5

如果您在 4.2 之前并且正在使用所谓的投票者(如果您使用 @hasRole 等注释),那么您需要在上下文中定义以下 bean:

@Bean
public DefaultMethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler() {
    DefaultMethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler = new DefaultMethodSecurityExpressionHandler();
    defaultMethodSecurityExpressionHandler.setDefaultRolePrefix("");
    return defaultMethodSecurityExpressionHandler;
}

@Bean
public DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler() {
    DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
    defaultWebSecurityExpressionHandler.setDefaultRolePrefix("");
    return defaultWebSecurityExpressionHandler;
}
Run Code Online (Sandbox Code Playgroud)

这些 bean 用于为拼写表达式创建求值上下文,并且它们的 defaultRolePrefix 设置为“ROLE_”。尽管这取决于您的用例。这个对我有用,而上面的没有。

编辑:回答有关 xml 配置的问题 -> 当然可以在 xml 中完成。java配置中所做的一切都可以写在xml配置中。这是示例(尽管我没有测试它,因此可能存在拼写错误或其他问题):

<bean id="defaultWebSecurityExpressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler">
        <property name="defaultRolePrefix" value=""></property>
</bean>

<bean id="defaultMethodSecurityExpressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
        <property name="defaultRolePrefix" value=""></property>
</bean>
Run Code Online (Sandbox Code Playgroud)


Hun*_*ran 5

如果您使用 Spring Boot 2,您可以创建此 bean 来覆盖RoteVoter前缀

@Bean
public GrantedAuthorityDefaults grantedAuthorityDefaults() {
    return  new GrantedAuthorityDefaults("<anything you want>");
}
Run Code Online (Sandbox Code Playgroud)

它之所以有效,是因为当GlobalMethodSecurityConfiguration在方法GlobalMethodSecurityConfiguration.accessDecisionManager()中创建AccessDecisionManager时。这是代码片段,请注意grantAuthorityDefaults上的 null 检查

    protected AccessDecisionManager accessDecisionManager() {
    ....
    RoleVoter roleVoter = new RoleVoter();
    GrantedAuthorityDefaults grantedAuthorityDefaults =
            getSingleBeanOrNull(GrantedAuthorityDefaults.class);
    if (grantedAuthorityDefaults != null) {
        roleVoter.setRolePrefix(grantedAuthorityDefaults.getRolePrefix());
    }
    decisionVoters.add(roleVoter);
    decisionVoters.add(new AuthenticatedVoter());
    return new AffirmativeBased(decisionVoters);
}
Run Code Online (Sandbox Code Playgroud)