【问题标题】:How to remove "ROLE_" prefix when testing Spring security with JUnit?使用 JUnit 测试 Spring 安全性时如何删除“ROLE_”前缀?
【发布时间】:2019-12-10 22:39:48
【问题描述】:

一些背景知识:我们有一个集成测试类,用于测试与 Spring 授权一起使用的常量 SPEL 字符串。简单例子:

@SpringBootTest
@RunWith(SpringRunner.class)
public class HasRoleConstantsTest {
    @Test
    @WithMockUser(username = "uname", roles = "ADMIN")
    public void test() {
        // just calling some test method with appropriate annotation
    }
}

上述常量的用法如下:

@PreAuthorize(PREDEFINED_AUTHORIZATION_RULE)

常量可能是一些更复杂的检查,例如:

public static final String PREDEFINED_AUTHORIZATION_RULE =
    "hasRole('ADMIN') OR (hasRole('MAINTAINER') AND hasRole('#id'))"

我们已经按照建议的here 配置了我们的WebSecurityConfiguration,所以添加像这样的bean:

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

除了帖子顶部显示的测试失败之外,一切都像魅力一样工作,因为在测试环境中 Spring 安全性仍然为每个模拟用户角色添加前缀 ROLE_

有人能解释一下应该如何配置测试类,或者——例如——应该如何操作SecurityContext 以在测试中去掉这个前缀吗?

【问题讨论】:

  • @WithMockUser 注解中使用authorities 而不是roles 属性。
  • @M.Deinum 谢谢它似乎解决了这个问题。我自己也应该尝试过,但不知何故错过了那个属性:)。如果你愿意提供这个作为答案,最好有一些解释,我至少会支持它。当然,最好的答案是有一种方法可以让它像在生产代码中一样,但对我们来说这已经足够了。
  • hasRolehasAuthority 是相同的,区别在于hasRole 添加了前缀(除非您禁用它)。所以在你的生产代码中而不是使用hasRole 使用hasAuthority 将节省你配置角色前缀的时间。

标签: java spring junit spring-security spring-test


【解决方案1】:

很简单,打开这个注解的javadoc,用authorities代替roles

【讨论】:

    【解决方案2】:

    这对我来说很好用:

    配置:

    @Configuration
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class GlobalMethodSecurityConfig extends GlobalMethodSecurityConfiguration {
        private final ApplicationContext context;
    
        @Autowired
        public GlobalMethodSecurityConfig(ApplicationContext context) {
            this.context = context;
        }
    
        @Override
        protected MethodSecurityExpressionHandler createExpressionHandler() {
            DefaultMethodSecurityExpressionHandler handler = 
                new DefaultMethodSecurityExpressionHandler();
    
            handler.setDefaultRolePrefix("");
            handler.setApplicationContext(context);
            return handler;
        }
    }
    

    测试:

    @Test
    @WithMockUser(roles = "USER")
    void getCard() {
        ...
    }
    

    如果这没有帮助,您能否在 GitHub 上展示一个有效的代码示例? (可能有助于发现问题)

    【讨论】:

      猜你喜欢
      • 2016-11-03
      • 2015-05-28
      • 2020-07-01
      • 1970-01-01
      • 2012-01-09
      • 1970-01-01
      • 2020-06-10
      • 2015-08-10
      • 2018-07-22
      相关资源
      最近更新 更多