《Spring Security》第九章 自定义 Security Mock 注解

第九章 自定义 Security Mock 注解

第八章 Spring Security 的测试支持 可以看到,如果不使用自定义的身份验证主体,@WithMockUser 是一个很好的选择。

一、@WithMockUser 存在的问题

大部分情况下,我们使用都不是 UserDetails 对象,而是 UserDetails 的自定义实现。

且 @WithUserDetails 注解还需要查询数据库,并且要求用户存在。

二、解决方案

我们可以通过模仿 @WithMockUser 注解,创建自己的 @WithMockSutomUser注解。并通过实现 WithSecurityContextFactory 来使用自己的注解。

1. @WithMockSutomUser

@Retention(RetentionPolicy.RUNTIME)
@WithSecurityContext(factory = WithMockCustomUserSecurityContextFactory.class)
public @interface WithMockCustomUser {

    String username() default "rob";

    String name() default "Rob Winch";
}

2. WithMockCustomUserSecurityContextFactory

final class WithUserDetailsSecurityContextFactory
    implements WithSecurityContextFactory<WithUserDetails> {

    private UserDetailsService userDetailsService;

    @Autowired
    public WithUserDetailsSecurityContextFactory(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    public SecurityContext createSecurityContext(WithUserDetails withUser) {
        String username = withUser.value();
        Assert.hasLength(username, "value() must be non-empty String");
        UserDetails principal = userDetailsService.loadUserByUsername(username);
        Authentication authentication = new UsernamePasswordAuthenticationToken(principal, principal.getPassword(), principal.getAuthorities());
        SecurityContext context = SecurityContextHolder.createEmptyContext();
        context.setAuthentication(authentication);
        return context;
    }
}

现在,我们使用新的注解来测试类或方法,Spring Security 的 WithSecurityContextTestExecutionListener 将确保我们的 SecurityContext 得到了适当的填充。

文章作者: koral
文章链接: http://luokaiii.github.io/2019/07/19/读书笔记/《SpringSecurity》/9.自定义注解/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自