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

Docker部署Spring Boot内嵌Tomcat调用返回401问题求助

Spring Boot容器化后401授权失败与Swagger异常排查

问题现象

  • 访问localhost:8080时,Spring Security弹出登录框,输入账号密码后显示白标错误页;Postman调用任何接口(含GET localhost:8080)均返回401未授权,且Spring Boot无请求日志,最后一条日志为应用启动完成:
2023-03-14T14:11:07.344Z  INFO 1 --- [           main] com.example.myapp.MyApplication       : Started MyApplication in 3.978 seconds (process running for 4.521)
  • 访问Swagger返回空内容,本地运行正常;
  • HTTPS访问localhost:8080时,Spring Boot记录HTTP请求头解析错误:
2023-03-14T14:13:36.511Z  INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2023-03-14T14:13:36.513Z  INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
2023-03-14T14:14:02.018Z  INFO 1 --- [nio-8080-exec-3] o.springdoc.api.AbstractOpenApiResource  : Init duration for springdoc-openapi is: 99 ms
2023-03-14T14:34:55.564Z  INFO 1 --- [nio-8080-exec-7] o.apache.coyote.http11.Http11Processor   : Error parsing HTTP request header
 Note: further occurrences of HTTP request parsing errors will be logged at DEBUG level.

java.lang.IllegalArgumentException: Invalid character found in method name [0x160x030x010x000xf70x010x000x000xf30x030x03z0xfe0x90q0xe80x0an0x960xd50xcc0xb80x93lv0xfcf0xfc0xf50xdeT0x980xfa0xd6?0x99^0xe70x940x900xcaoP ]. HTTP method names must be tokens
    at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:419) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:272) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1739) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]

环境配置

docker-compose.yml

version: '3.9'
services:
  mongo:
    image: mongo:4.4.15
    restart: unless-stopped
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: password
    ports:
      - "27017:27017"
    tty: true
    stdin_open: true
    volumes:
      - mongo-vol:/docker-entrypoint-initdb.d/
    healthcheck:
      test: echo 'db.runCommand("ping").ok' | mongo localhost:27017/test --quiet
      interval: 10s
      timeout: 10s
      retries: 5
      start_period: 40s

  mysql:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_DATABASE: 'mydb'
      MYSQL_USER: 'user'
      MYSQL_PASSWORD: 'password'
      MYSQL_ROOT_PASSWORD: 'password'
    volumes:
      - mysql-vol:/docker-entrypoint-initdb.d/
    healthcheck:
      test: /usr/bin/mysql mysql -ppassword --silent --execute "select 1"
      interval: 10s
      timeout: 10s
      retries: 5

  my-be:
    image: be_image
    container_name: be-container
    ports:
      - "8080:8080"
    environment:
      spring.datasource.url: "jdbc:mysql://mysql:3306/mydb?allowPublicKeyRetrieval=true&useSSL=false&createDatabaseIfNotExist=true"
      datasource.driver-class-name: "com.mysql.cj.jdbc.Driver"
      spring.h2.console.enabled: "false"
      spring.jpa.database-platform: "org.hibernate.dialect.MySQLDialect"
      spring.data.mongodb.host: mongo
      spring.data.mongodb.port: 27017
      logging.file.path: logs
      server.port: 8080
    depends_on:
      mongo:
        condition: service_healthy
      mysql:
        condition: service_healthy
volumes:
  mysql-vol:
  mongo-vol:

Dockerfile

FROM openjdk:17
EXPOSE 8080
ARG JAR_FILE="target/MyAPP-0.0.1-SNAPSHOT.jar"
ADD ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

容器运行状态

CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS                    PORTS                                           NAMES
996da02a43e5   be_image       "java -jar /app.jar"     11 minutes ago   Up 11 minutes             0.0.0.0:8080->8080/tcp, :::8080->8080/tcp       be-container
9c3d11ceb0ee   mongo:4.4.15   "docker-entrypoint.s…"   11 minutes ago   Up 11 minutes (healthy)   0.0.0.0:27017->27017/tcp, :::27017->27017/tcp   compose-mongo-1
15fe4d52a50e   mysql          "docker-entrypoint.s…"   11 minutes ago   Up 11 minutes (healthy)   3306/tcp, 33060/tcp                             compose-mysql-1

排查与解决方案

1. 401未授权及无请求日志问题

原因

  • Spring Security启用默认HTTP Basic认证,但未配置合法用户信息,导致登录后授权失败;
  • 日志输出到容器内logs目录,本地无法查看认证失败的详细日志;
  • 极端情况:应用硬绑定localhost监听地址,容器外请求无法到达,表现为无日志+401。

解决步骤

  • 在docker-compose.yml的my-be服务中添加Spring Security默认用户配置:
    environment:
      # 原有配置...
      spring.security.user.name: "admin"
      spring.security.user.password: "admin123"
      spring.security.user.roles: "ADMIN"
      server.address: 0.0.0.0
      logging.level.org.springframework.security: DEBUG
    
  • 执行docker logs -f be-container查看实时认证日志,定位具体失败原因。

2. Swagger返回空内容问题

原因

  • Spring Security拦截了Swagger的静态资源和API文档路径;
  • 容器化后Swagger的路径匹配或扫描规则未适配环境。

解决步骤

  • 在Spring Security配置类中放行Swagger相关路径:
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/swagger-ui/**", "/v3/api-docs/**", "/swagger-resources/**")
            .permitAll()
            .anyRequest()
            .authenticated();
    }
    
  • 若应用有自定义上下文路径,添加环境变量springdoc.api-docs.path: /v3/api-docs确保Swagger路径正确。

3. HTTPS访问报错问题

原因

应用未配置HTTPS,Tomcat仅监听HTTP端口8080,HTTPS请求的TLS握手数据会被当作非法HTTP请求解析。

解决步骤

  • 日常访问使用HTTP协议;若需HTTPS,需在Spring Boot中配置SSL证书,修改docker-compose.yml的端口映射为443:8443,并添加SSL相关环境变量:
    environment:
      # 原有配置...
      server.ssl.key-store: "/cert/keystore.jks"
      server.ssl.key-store-password: "your-cert-password"
      server.port: 8443
    volumes:
      - ./local-cert-path:/cert
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 06:07:04