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

时间:2016-06-30 22:15:53

标签: spring spring-security spring-java-config

我试图删除" ROLE _" Spring Security中的前缀。我尝试的第一件事是:

http.servletApi().rolePrefix("");

这没有用,所以我尝试按http://docs.spring.io/spring-security/site/migrate/current/3-to-4/html5/migrate-3-to-4-jc.html#m3to4-role-prefixing-disable中的建议创建BeanPostProcessor。这也不起作用。

最后,我尝试创建自己的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;
  }

然而,这也不起作用。如果我使用&#34; hasAuthority(roleName)&#34;而不是hasRole,它按预期工作。

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

7 个答案:

答案 0 :(得分:16)

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

@Bean
GrantedAuthorityDefaults grantedAuthorityDefaults() {
    return new GrantedAuthorityDefaults(""); // Remove the ROLE_ prefix
}

XML版本:

<beans:bean id="grantedAuthorityDefaults" class="org.springframework.security.config.core.GrantedAuthorityDefaults">
    <beans:constructor-arg value="" />
</beans:bean>

答案 1 :(得分:7)

以下配置适用于我。

import requests
import pyVmomi

答案 2 :(得分:3)

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

Configuration.ReplaceService<IPermissionChecker, NullPermissionChecker>(DependencyLifeStyle.Transient);

这些bean用于为拼写表达式创建评估上下文,并且它们的defaultRolePrefix设置为&#39; ROLE _&#39;。虽然这取决于您的使用案例。这个对我有用,而且没有。

编辑:回答有关xml配置的问题 - &gt;当然它可以在xml中完成。在java配置中完成的所有操作都可以用xml配置编写。这是一个例子(虽然我没有测试它所以可能有一个错字或其他东西):

not

答案 3 :(得分:3)

新的GrantedAuthorityDefaults似乎会更改DefaultWebSecurityExpressionHandlerDefaultMethodSecurityExpressionHandler的前缀,但它不会修改从RoleVoter.rolePrefix设置的@EnableGlobalMethodSecurity {1}}。

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;
    }
}

答案 4 :(得分:0)

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

@Bean
public GrantedAuthorityDefaults grantedAuthorityDefaults() {
    return  new GrantedAuthorityDefaults("<anything you want>");
}

之所以起作用,是因为当 GlobalMethodSecurityConfiguration 在方法 GlobalMethodSecurityConfiguration.accessDecisionManager()中创建 AccessDecisionManager 时。这是代码段,请注意 grantedAuthorityDefaults

上的空检查
    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);
}

答案 5 :(得分:0)

我为我发布了汇总的工作解决方案:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {

    /**
     * Allow skip ROLE_ when check permission using @Secured, like:
     *  @Secured({AuthorityConstants.ROLE_SYSTEM_ADMIN})
     */
    @Override
    protected AccessDecisionManager accessDecisionManager() {
        AffirmativeBased accessDecisionManager = (AffirmativeBased) super.accessDecisionManager();
        setAuthorityRolePrefix(accessDecisionManager, "");
        return accessDecisionManager;
    }

    private void setAuthorityRolePrefix(AffirmativeBased accessDecisionManager, String rolePrefix) {
        accessDecisionManager.getDecisionVoters().stream()
                .filter(RoleVoter.class::isInstance)
                .map(RoleVoter.class::cast)
                .forEach(it -> it.setRolePrefix(rolePrefix));
    }

    /**
     * Allow skip ROLE_ when check permission using @PreAuthorize, like:
     * @PreAuthorize("hasAnyRole('USER', 'SYSTEM_ADMIN')")
     */
    @Bean
    GrantedAuthorityDefaults grantedAuthorityDefaults() {
        return new GrantedAuthorityDefaults(""); // Remove the ROLE_ prefix
    }
}

答案 6 :(得分:0)

在Spring Boot 2.3中,我在启动时遇到了这个异常:

Error creating bean with name 'resourceHandlerMapping' defined in class path resource 
[org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]:
Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException:
Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: 
Factory method 'resourceHandlerMapping' threw exception;
nested exception is java.lang.IllegalStateException: No ServletContext set

这是我的解决方案:

@Configuration
@Import(RolePrefixConfiguration.class)
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class MyWebSecurityConfiguration extends WebSecurityConfigurerAdapter {

  public static class RolePrefixConfiguration {

    @Bean
    public GrantedAuthorityDefaults grantedAuthorityDefaults() {
      log.debug("remove prefix 'ROLE_' from grantedAuthorityDefaults");
      return new GrantedAuthorityDefaults("");
    }

  }
   
   // ... your usual config 
}