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

Postman每次请求发送相同认证头:Spring REST获取Basic Auth用户ID异常

解决Spring REST中Basic Auth获取用户ID始终相同的问题

嘿,我之前也踩过这个Basic Auth的坑!咱们一步步来排查和解决这个问题:

第一步:先确认Postman的请求是否真的传对了凭证

很多时候问题出在Postman的缓存或者配置上,先把这个排除掉:

  • 打开Postman的请求,切换到Headers标签,确认Authorization头是否存在,并且不同用户对应的base64编码是不同的。比如用户user1:password1对应的头是Basic dXNlcjE6cGFzc3dvcmQx,user2:password2则是Basic dXNlcjI6cGFzc3dvcmQy。
  • 关闭Postman的「Automatically send authorization headers」选项,避免它缓存旧的凭证。你可以在Postman的设置里找到这个选项,或者每次测试前手动清空Authorization头重新输入。
  • 极端情况下,直接用Raw请求头手动构造Authorization字段发送,彻底排除Postman自动处理的干扰。

第二步:检查Spring Security的配置是否正确

这是最容易出问题的地方,核心要确保Basic Auth启用且用户源配置正确:

1. 确保启用了Basic Auth

你的Security配置类里必须明确开启Basic Auth,否则认证根本不会生效:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .anyRequest().authenticated() // 要求所有请求都必须认证
            )
            .httpBasic(withDefaults()); // 关键:启用Basic Auth认证方式
        return http.build();
    }
}

如果没加.httpBasic(withDefaults()),Spring不会处理Basic Auth的凭证,可能会默认返回匿名用户或者固定用户。

2. 确保用户源不是硬编码的单一用户

如果你的UserDetailsService只配置了一个固定用户,那不管你传什么凭证,要么认证失败,要么就只能拿到这个固定用户。正确的做法是配置多个测试用户(或者从数据库读取):

@Bean
public UserDetailsService userDetailsService() {
    // 配置两个测试用户,{noop}表示不加密密码(仅测试用,生产环境必须用密码编码器)
    UserDetails user1 = User.withUsername("user1")
        .password("{noop}password1")
        .roles("USER")
        .build();
    UserDetails user2 = User.withUsername("user2")
        .password("{noop}password2")
        .roles("USER")
        .build();
    return new InMemoryUserDetailsManager(user1, user2);
}

第三步:优化控制器中获取用户ID的方式

虽然request.getUserPrincipal().getName()没问题,但更推荐用Spring Security提供的@AuthenticationPrincipal注解,更简洁也更不容易出错:

@RestController
@RequestMapping("/api")
public class UserController {

    @GetMapping("/current-user")
    public ResponseEntity<String> getCurrentUser(@AuthenticationPrincipal UserDetails userDetails) {
        String userId = userDetails.getUsername();
        return ResponseEntity.ok("当前用户ID:" + userId);
    }
}

这种方式直接从Spring Security的上下文获取认证用户,避免了HttpServletRequest可能的绑定问题。

第四步:排查自定义过滤器/拦截器的干扰

如果项目里有自定义的Filter或者Interceptor,并且在Spring Security过滤器之前执行,要检查是否有代码篡改了SecurityContext:
比如如果有类似这样的代码,会强制设置固定用户,覆盖Basic Auth的认证结果:

SecurityContextHolder.getContext().setAuthentication(
    new UsernamePasswordAuthenticationToken("fixedUser", null, Collections.emptyList())
);

遇到这种情况,要么删除这段代码,要么调整过滤器的执行顺序,让它在Security过滤器之后运行。

内容的提问来源于stack exchange,提问作者ajay tomar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:31:16