You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security登录接口测试返回401而非200问题求助

解决Spring Security登录测试返回401的问题

咱们一步步拆解你遇到的问题,逐个解决:

1. 测试类注解冲突导致安全配置未加载

你同时使用了@DataJpaTest和@SpringBootTest,但@DataJpaTest是切片测试注解——它只会加载与JPA相关的Bean,不会完整加载你的WebSecurityConfig等Web层配置。这直接导致你的Spring Security规则没生效,/api/login并没有被允许匿名访问,所以返回401。

修复方案:
去掉@DataJpaTest,只保留@SpringBootTest和@AutoConfigureMockMvc,这样才能加载完整的应用上下文,包括安全配置:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class AuthenticationTest {
    // 测试代码保持不变
}

2. Form Login路径配置不匹配

在你的WebSecurityConfig中,.loginPage("/api/login")是指定登录页面的GET请求路径,但Spring Security默认的登录处理(POST提交凭证)路径是/login。你的测试是POST到/api/login,但这个路径并没有被配置成登录处理端点,所以请求被当成了需要认证的普通接口,返回401。

修复方案:
添加loginProcessingUrl("/api/login")来指定处理登录POST请求的路径:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .antMatchers("/api/login").permitAll()
            .antMatchers("/api/registration").permitAll()
            .anyRequest().authenticated()
            .and()
            .csrf().disable()
            .exceptionHandling().authenticationEntryPoint(new Http403ForbiddenEntryPoint())
            .and()
            .formLogin()
                .successHandler(authenticationSuccessHandler)
                .loginPage("/api/login") // 处理GET请求的登录页面路径
                .loginProcessingUrl("/api/login") // 处理POST登录请求的路径
                .failureHandler(new SimpleUrlAuthenticationFailureHandler())
            .and()
            .logout()
                .logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK));
}

3. 密码编码与凭证匹配问题

你配置了BCryptPasswordEncoder,但要注意:BCrypt要求存储的是加密后的哈希值,而不是明文密码。如果你的UserDetailsServiceImpl返回的用户密码是明文,或者application.properties里的配置是明文,都会导致凭证验证失败。

快速验证方案:
可以临时在测试中生成加密后的密码,替换到用户数据中:

BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
System.out.println(encoder.encode("password"));

或者直接在configureGlobal中配置内存用户来测试:

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth
            .inMemoryAuthentication()
            .passwordEncoder(passwordEncoder())
            .withUser("user")
            .password(passwordEncoder().encode("password"))
            .roles("USER");
}

4. 日志中Handler为null的问题

从日志里的Handler: Type = null可以看出,请求根本没被Spring Security的登录过滤器拦截,本质还是前面的上下文加载或路径配置问题,解决前两个问题后这个现象会自动消失。


按照上面的步骤调整后,再运行测试应该就能拿到200状态码了。

内容的提问来源于stack exchange,提问作者Denys Bondarenko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:33:40