Spring Security 如何在JUnit测试期间以@WithMockUser方式通过错误密码创建模拟用户?

6tqwzwtp  于 2023-06-23  发布在  Spring
关注(0)|答案(1)|浏览(301)

@WithMockUser方法中,WithMockUserSecurityContextFactorycreateSecurityContext方法用于创建具有模拟用户的安全上下文。但是,身份验证对象始终以已验证状态创建。这意味着,如果身份验证对象始终经过身份验证,则无法测试密码验证。因此,无法对错误密码情况进行测试。
WithMockUserSecurityContextFactory#createSecurityContext(WithMockUser withUser)
以下是来源:安全配置

@Bean
    public InMemoryUserDetailsManager userDetailsService(PasswordEncoder passwordEncoder) {

        String encPW = passwordEncoder.encode("123456");
        log.debug(encPW);
        UserDetails user = User.withUsername("user")
                .password(encPW)
                //.password("123456")
                .roles("USER")
                .build();

        UserDetails admin = User.withUsername("admin")
                .password(passwordEncoder.encode("123456"))
                .roles("USER", "ADMIN")
                .build();

        return new InMemoryUserDetailsManager(user, admin);
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .csrf((csrf)
                        -> csrf.ignoringRequestMatchers("/demo/**"))
                .authorizeHttpRequests((ah)
                        -> ah
                        .requestMatchers("/demo/authenticate").authenticated()
                        .anyRequest().permitAll()
                )
                .httpBasic(Customizer.withDefaults())
                ;
        return http.build();
    }

测试

//@WithMockUser(username = "no_exist_user", password = "123456777") //TEST NG
@Test
    void testHelloByWrongPw() throws Exception {

        mvc.perform(
                        post("/demo/authenticate")
                                .with(httpBasic("no_exist_user", "123456777"))
                                .content("{\"a1\":\"123\"}")
                                .contentType(MediaType.APPLICATION_JSON)
                                .accept(MediaType.APPLICATION_JSON)
                                .queryParam("a1","123")
                )
                .andExpect(status().isUnauthorized());
    }
bzzcjhmw

bzzcjhmw1#

它并不像你期望的那样工作。@WithMockUser只是为当前认证成功的用户配置一个具有一定权限的用户对象,不能模拟用户认证失败。因为如果用户身份验证失败,则对他来说不存在用户对象,因此没有什么可配置的。
所以@WithMockUser是一个测试授权而不是身份验证的工具。
如果你想测试一个用户发送了一个不正确的密码请求,只需要使用普通的@WebMvcTest进行测试,然后使用MockMvc来配置一个不正确的密码HTTP请求,就像你现在正在做的一样。

相关问题