Spring Security基础认证问题:密码仅首次验证有效
问题分析与解决建议
问题根源
这是因为Spring Security默认在Basic认证成功后会创建HTTP会话,后续请求会复用会话中已通过认证的用户信息,不再重新校验请求头里的Basic凭证。所以只要会话未过期/失效,哪怕后续请求携带错误的用户名密码,也会直接通过认证返回200。
解决方法
1. 配置无状态认证(推荐用于API场景)
如果你的服务是无状态的REST API,直接禁用会话创建,让每次请求都必须重新验证Basic凭证:
@Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .httpBasic() .and() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS); // 禁用会话 return http.build(); }
2. 强制每次请求重新校验凭证(保留会话场景)
如果必须保留会话,但要求每次请求都校验Basic凭证,可以通过自定义认证入口点结合会话销毁实现:
@Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .httpBasic() .authenticationEntryPoint(new BasicAuthenticationEntryPoint() { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authEx) throws IOException, ServletException { response.addHeader("WWW-Authenticate", "Basic realm=\"" + getRealmName() + "\""); response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authEx.getMessage()); // 销毁当前会话,强制后续请求重新认证 request.getSession().invalidate(); } @Override public void afterPropertiesSet() throws Exception { setRealmName("YourRealm"); super.afterPropertiesSet(); } }) .and() .sessionManagement() .maximumSessions(1); // 限制单用户同时会话数 return http.build(); }
3. 检查UserDetailsService实现
确保你的UserService中返回的UserDetails对象状态属性设置正确,避免因账户状态异常导致的认证逻辑异常:
@Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { UserEntity user = userRepository.findByUsername(username) .orElseThrow(() -> new UsernameNotFoundException("User not found")); return User.withUsername(user.getUsername()) .password(user.getPassword()) .roles(user.getRoles().toArray(new String[0])) .accountExpired(false) .accountLocked(false) .credentialsExpired(false) .enabled(true) .build(); }
验证步骤
修改配置后重启服务,按以下流程测试:
- 用错误密码请求接口,返回401
- 用正确密码请求接口,返回200
- 再次用错误密码请求接口,此时会返回401,符合预期
内容的提问来源于stack exchange,提问作者italktothewind
相关产品推荐
相关产品推荐

