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

如何通过Docker内部URL正确内省Keycloak访问令牌?

问题

使用Python Keycloak库结合FastAPI验证Keycloak访问令牌时,当server_url设为外部地址https://example.com/auth/时,内省令牌功能正常;但将server_url替换为Docker Compose环境中Keycloak容器的内部地址http://keycloak:8080/auth/后,内省结果始终返回{'active': False}。

相关Python代码:

keycloak_openid = KeycloakOpenID(
    server_url="https://example.com/auth/",
    realm_name="abc",
    client_id="myclient",
    client_secret_key="secret",
    verify=False,
)
header = request.headers.get('Authorization')
token = header.split()[1]
token_info = keycloak_openid.introspect(token)
print(token_info)

Docker Compose配置:

services:
  keycloak:
    image: quay.io/keycloak/keycloak:25.0.2
    command: 
      - start
      - --import-realm
      - --features=hostname:v2
    volumes:
      - ./config/keycloak/imports:/opt/keycloak/data/import
    environment:
      - KC_DB=postgres
      - KC_DB_URL=jdbc:postgresql://keycloak-db/access-control-db
      - KC_DB_USERNAME=${POSTGRES_USER}
      - KC_DB_SCHEMA=public
      - KC_DB_PASSWORD=${POSTGRES_PASSWORD}
      - KEYCLOAK_ADMIN=${KEYCLOAK_USER}
      - KEYCLOAK_ADMIN_PASSWORD=${KEYCLOAK_PASSWORD}
      - KC_HOSTNAME=example.com
      - KC_HOSTNAME_STRICT=false
      - KC_HTTP_ENABLED=true     
      - KC_HTTP_RELATIVE_PATH=/auth
      - KC_PROXY_HEADERS=xforwarded
    depends_on:
      - keycloak-db
    restart: always

  keycloak-db:
    image: postgres:16
    environment:
      POSTGRES_DB: access-control-db
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - keycloak-db-data:/var/lib/postgresql/data
    restart: always

volumes:
  keycloak-db-data:

已尝试移除KC_HOSTNAME变量,但问题未解决。

解决方案

出现这个问题的核心原因是:Keycloak颁发的令牌中issuer字段为外部域名https://example.com/auth/realms/abc,当通过内部地址http://keycloak:8080/auth/调用内省接口时,Keycloak默认会校验请求地址与令牌issuer的一致性,不匹配则返回active: False。

可以通过以下两种方法解决:

方法一:修改Keycloak配置,允许内部地址的后台请求

在Docker Compose的Keycloak环境变量中添加以下配置,关闭后台请求的严格校验,并允许内部地址作为合法来源:

environment:
  # 原有配置保留,新增以下项
  - KC_HOSTNAME_STRICT_BACKCHANNEL=false
  - KC_HOSTNAME_ALLOWED_ORIGINS=http://keycloak:8080,https://example.com
  - KC_HOSTNAME_STRICT_HTTPS=false
  • KC_HOSTNAME_STRICT_BACKCHANNEL=false:关闭后台服务(如令牌内省)的主机名严格校验,允许内部地址调用内省接口
  • KC_HOSTNAME_ALLOWED_ORIGINS:添加内部地址和外部域名作为合法来源
  • KC_HOSTNAME_STRICT_HTTPS=false:允许内部HTTP请求(因为内部地址用的是http而非https)

修改后重启Keycloak容器,即可用内部地址正常内省令牌。

方法二:在Python代码中添加Host请求头

无需修改Keycloak配置,在调用内省接口时,手动添加Host请求头为外部域名example.com,让Keycloak认为请求来自合法的issuer地址:

token_info = keycloak_openid.introspect(token, headers={"Host": "example.com"})

这样Keycloak收到请求时,会匹配令牌中的issuer字段,正常返回令牌的活跃状态和其他信息。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 15:28:20