Nginx反向代理SpringBoot接口交替返回401/200问题排查求助
问题排查:Nginx后SpringBoot Security接口交替返回401/200(PermitAll接口)
我有一个部署在Nginx后的SpringBoot应用(集成Spring Security),页面加载时前端调用标记为@PermitAll的无需认证接口,但通过Nginx访问时该接口交替返回401和200状态码;直接访问容器或本地IDEA运行时始终返回200。
相关配置信息如下:
Nginx配置片段
location /v1/auth { include /etc/nginx/shared.conf; proxy_pass http://user-svc; }
upstream配置
upstream user-svc { server user-svc:8080; }
shared.conf内容
error_page 405 =200 $uri; # proxy_cache my_cache; # proxy_cache_valid 200 30s; # proxy_cache_methods GET HEAD POST; # proxy_cache_min_uses 1; # proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504; proxy_cache_bypass $http_cache_control; proxy_no_cache $http_cache_control; proxy_cache off; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #proxy_set_header X-forwarded-Host $server_name; proxy_set_header X-Forwarded-Host $host:$server_port;
Dockerfile
FROM java-base-image as builder WORKDIR /app COPY pom.xml ./ COPY ./src ./src RUN mvn -o clean install -DskipTests spring-boot:repackage FROM --platform=linux/amd64 jdk11-base-image COPY --from=builder /app/target/user-svc-0.0.1-SNAPSHOT.jar /app/user-svc-0.0.1-SNAPSHOT.jar EXPOSE 8080 WORKDIR /app ENTRYPOINT ["java", "-jar", "user-svc-0.0.1-SNAPSHOT.jar"]
docker-compose.yaml
version: "3" services: user-svc: container_name: user-svc image: user-svc:latest expose: - "8080" networks: - private-network environment: TZ: Asia/Singapore SERVER_PORT: 8080 DB_URL: jdbc:mysql://mysql-db:3306/user DB_USER: root DB_PASS: password networks: private-network: external: true
可能的问题原因及排查方向
1. Spring Security未正确处理Nginx转发头
Spring Security对代理后的请求头识别异常,会导致会话或认证判断不稳定:
- 检查Spring Boot配置是否开启转发头支持:在
application.yml或application.properties中添加server.forward-headers-strategy=native(适用于Spring Boot 2.2+),或者手动配置ForwardedHeaderFilter,确保应用能正确识别Nginx传递的X-Forwarded-*系列头。 - 对比直接访问和Nginx转发的请求头,重点查看
Host、X-Forwarded-Host等字段是否一致,不一致的头信息可能触发Security的安全校验逻辑。
2. 会话管理配置导致的偶发未认证
即使是@PermitAll接口,默认Spring Security仍会创建会话,如果会话Cookie传递异常,会出现交替401/200:
- 检查Spring Security配置,是否设置了
sessionCreationPolicy(SessionCreationPolicy.STATELESS)。对于无需认证的接口,采用无状态模式可以彻底避免会话相关问题。 - 查看应用返回的Cookie属性(Domain、Path、HttpOnly等),确认是否适配Nginx的访问域名,避免浏览器偶尔无法携带Cookie导致会话未被识别。
3. Nginx的error_page配置干扰状态码
shared.conf中的error_page 405 =200 $uri;会将405状态码强制转为200,如果接口偶发返回405(比如请求方法不匹配),可能和实际的401状态码混淆,造成交替的假象:
- 临时注释该配置,测试是否还会出现状态码交替的情况,排查是否是状态码转换导致的异常表现。
4. 日志排查定位根源
通过日志确认问题发生的具体环节:
- 查看Nginx的
access.log和error.log,记录401请求的时间和请求详情,确认请求是否成功转发到应用容器。 - 对应查看应用的日志,看401状态码是应用的Spring Security返回的,还是Nginx层面返回的。如果是Security返回401,进一步查看Security的认证日志,确定是会话未识别还是其他校验逻辑触发。
内容的提问来源于stack exchange,提问作者Mike Toleds
相关产品推荐
相关产品推荐

