将Springboot webapp部署到Docker时Keycloak适配器无法验证令牌

Posted

技术标签:

【中文标题】将Springboot webapp部署到Docker时Keycloak适配器无法验证令牌【英文标题】:Keycloak Adapter Failed to verify token when deploy Springboot webapp to Docker 【发布时间】:2020-04-02 03:43:00 【问题描述】:

我正在开发一个 Springboot 应用程序和一个在 Tomcat 上运行的 React 前端,以及 Hasura Graphql 和 Keycloak。所有 3 个项目都在一个 Docker 堆栈中运行,具有以下 stack.yml:

version: '3.7'

services:
  timescale-primary:
    image: timescale-replication:latest
    env_file:
      - primary.env
    networks:
      - public-network
    ports:
      - 5432:5432
    volumes:
      - timescale-primary-storage:/var/lib/postgresql/data
    deploy:
      placement:
        constraints:
          - node.labels.type == primary

  timescale-replica:
    image: timescale-replication:latest
    env_file:
      - replica.env
    networks:
      - public-network
    volumes:
      - timescale-replica-storage:/var/lib/postgresql/data
    deploy:
      placement:
        constraints:
          - node.labels.type != primary

  hasura:
    image: hasura/graphql-engine
    networks:
      - public-network
    ports:
      - 6080:8080
    env_file:
      - hasura.env
    volumes:
      - hasura-storage:/var/lib/hasura
    depends_on:
      - timescale-primary

  keycloak:
    image: keycloak
    networks:
      - public-network
    ports:
      - 9080:8080
    env_file:
      - keycloak.env
    volumes:
      - keycloak-storage:/opt/jboss/keycloak/themes
    depends_on:
      - timescale-primary

  tomcat:
    image: tomcat:v1
    networks:
      - public-network
    ports:
      - 8086:8080
    volumes:
      - tomcat-storage:/usr/local/tomcat/webapps:Z
      - tomcat-log-storage:/var/log/tomcat:Y

networks:
  public-network:

volumes:
  timescale-primary-storage:
  timescale-replica-storage:
  hasura-storage:
  keycloak-storage:
  tomcat-storage:
  tomcat-log-storage:

SpringBoot webapp 是运行在http://tomcat:8080/backend 下的graphql 服务器,React 应用部署在http://tomcat:8080/ui 下。

在 Hasura 中,我设置了一个远程架构以指向该服务器:http://tomcat:8080/backend/graphql,并转发了所有客户端标头。

基本上,React 应用程序通过 Hasura 间接访问“后端”。

在 Keycloak 中,我为“ui”应用设置了一个公共客户端,为“后端”应用设置了一个机密客户端。

然后我得到如下认证流程:

    在 docker 的主机上,调用http://localhost:8086/ui 转发到 localhost:9080/auth/...(Keycloak 的登录屏幕) 登录成功后,重定向到“ui”应用 React 应用调用 Hasura Hasura 调用“后端”并得到“验证令牌失败”、“授权标头无效,详情请参阅 WWW-Authenticate 标头”
2019-12-09 02:47:59.163 DEBUG 1 --- [io-8080-exec-30] o.k.adapters.PreAuthActionsHandler       : adminRequest http://tomcat:8080/backend/graphql
2019-12-09 02:47:59.164 DEBUG 1 --- [io-8080-exec-30] f.KeycloakAuthenticationProcessingFilter : Request is to process authentication
2019-12-09 02:47:59.164 DEBUG 1 --- [io-8080-exec-30] f.KeycloakAuthenticationProcessingFilter : Attempting Keycloak authentication
2019-12-09 02:47:59.165 TRACE 1 --- [io-8080-exec-30] o.k.adapters.RequestAuthenticator        : --> authenticate()
2019-12-09 02:47:59.165 TRACE 1 --- [io-8080-exec-30] o.k.adapters.RequestAuthenticator        : try bearer
2019-12-09 02:47:59.165 DEBUG 1 --- [io-8080-exec-30] o.k.a.BearerTokenRequestAuthenticator    : Found [1] values in authorization header, selecting the first value for Bearer.
2019-12-09 02:47:59.165 DEBUG 1 --- [io-8080-exec-30] o.k.a.BearerTokenRequestAuthenticator    : Verifying access_token
2019-12-09 02:47:59.165 TRACE 1 --- [io-8080-exec-30] o.k.a.BearerTokenRequestAuthenticator    :        access_token: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJyb1NzQ2I1VWJPeDYyZHltWThzUm9qR2lGMHpINDJXQWdOU0JFd0Q2TEFFIn0.eyJqdGkiOiIyOWJlZmQ4MC04NGU3LTQ5NzMtOGQyMS0zOWE3ZTZiZjZiMjMiLCJleHAiOjE1NzU4NTk5NzksIm5iZiI6MCwiaWF0IjoxNTc1ODU5Njc5LCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjkwODAvYXV0aC9yZWFsbXMvdGQyMSIsInN1YiI6ImRlNWM2NjRhLWY0NTQtNDI0NC05OTY4LWJmYzAwZDg2YjA2ZSIsInR5cCI6IkJlYXJlciIsImF6cCI6InRkMjEtd2ViLXVpIiwibm9uY2UiOiJmZWE1NjE4My1kNDE2LTQ3NTktOWI0Yi1kNzI1NTVjZTA5OTAiLCJhdXRoX3RpbWUiOjE1NzU4NTg5NDksInNlc3Npb25fc3RhdGUiOiJiMmY2MjBhMC00MDRjLTRiYTctOGNlYy04OGQ2Y2Y3MDZmZmUiLCJhY3IiOiIwIiwiYWxsb3dlZC1vcmlnaW5zIjpbIioiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbIkFETUlOIl19LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiJ9.signature
2019-12-09 02:47:59.167 DEBUG 1 --- [io-8080-exec-30] o.k.a.BearerTokenRequestAuthenticator    : Failed to verify token
2019-12-09 02:47:59.167 DEBUG 1 --- [io-8080-exec-30] o.k.adapters.RequestAuthenticator        : Bearer FAILED
2019-12-09 02:47:59.167 DEBUG 1 --- [io-8080-exec-30] f.KeycloakAuthenticationProcessingFilter : Auth outcome: FAILED
2019-12-09 02:47:59.167 DEBUG 1 --- [io-8080-exec-30] f.KeycloakAuthenticationProcessingFilter : Authentication request failed: org.keycloak.adapters.springsecurity.KeycloakAuthenticationException: Invalid authorization header, see WWW-Authenticate header for details

org.keycloak.adapters.springsecurity.KeycloakAuthenticationException: Invalid authorization header, see WWW-Authenticate header for details
        at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter.attemptAuthentication(KeycloakAuthenticationProcessingFilter.java:158) ~[keycloak-spring-security-adapter-7.0.0.jar:7.0.0]

如果我将 React 和 Springboot 应用程序放在直接安装到 Docker 主机上的 Tomcat 中,那么后端的身份验证就可以了。仅当所有内容都部署到 Docker 时才会出现此问题。

我是 Keycloak 和 Docker 的新手,感谢任何帮助。

【问题讨论】:

【参考方案1】:

为了使身份验证工作,React 应用程序和 springboot 应用程序的 Keycloak 的 URL 需要相同。 IE。您不能将 localhost 用于一个,将 Docker 容器名称用于另一个。

就我而言,可以使用公共 IP 或实际域名。

【讨论】:

我遇到了同样的问题,即在 web 应用程序生成的令牌在我的后端应用程序中不起作用。我在 localhost 上对其进行测试,因此 web 应用程序在 url(localhost:8090) 上运行,而后端应用程序在同一领域下的 url(localhost:8080) 上运行。那么我在这里还缺少什么?

以上是关于将Springboot webapp部署到Docker时Keycloak适配器无法验证令牌的主要内容,如果未能解决你的问题,请参考以下文章

对使用 java -jar 部署的 Grails 3 webapp (Springboot) 应用程序使用 Logback 访问

springboot jar webapp 部署linux 的 404 问题

docker项目部署

如何把springboot项目部署到tomcat上

Maven - 在 JUnit 测试之前将 webapp 部署到 tomcat

IDEA快速部署Spring Boot 项目到Docker