K8s集群内Spring Boot访问Keycloak时OpenID配置域名不匹配问题
我把Keycloak部署在portal.local/auth,本地跑的Spring Boot应用(localhost:8080)能正常连接portal.local/auth/realms/myshop完成授权码流认证。但把Spring Boot应用部署到K8s同集群后,配置用Keycloak内部服务名keycloak.svc作为Issuer地址(keycloak.svc/auth/realms/myshop)时,发现该Issuer对应的OpenID配置JSON里还是显示portal.local,导致应用识别不了,认证失败。
以下是用Bitnami Helm Chart(oci://registry-1.docker.io/bitnamicharts/keycloak)安装Keycloak的配置:
auth: adminUser: admin adminPassword: admin extraEnvVars: - name: KEYCLOAK_LOG_LEVEL value: DEBUG - name: PROXY_ADDRESS_FORWARDING value: "true" postgresql: postgresqlPassword: postgresPwd volumes: # 导入*.json文件 - ./import:/opt/bitnami/keycloak/data/import # 导出数据:进入容器后执行`kc.sh export --dir /export/ --users realm_file` - ./export:/export httpRelativePath: /auth/ ingress: enabled: true hostname: portal.local resources: requests: memory: "512Mi" cpu: "500m" limits: memory: "1Gi" cpu: "1"
一、调整Keycloak Helm配置,支持内部服务访问
Keycloak默认会跟着Ingress的hostname生成对外URL,但集群内部服务得单独指定内部访问地址。在现有Helm配置的extraEnvVars里新增几个环境变量:
extraEnvVars: # 原有变量保留不动 - name: KEYCLOAK_LOG_LEVEL value: DEBUG - name: PROXY_ADDRESS_FORWARDING value: "true" # 新增内部URL相关配置 - name: KC_HOSTNAME_INTERNAL value: "keycloak.svc/auth" - name: KC_HOSTNAME_INTERNAL_PORT value: "80" - name: KC_HOSTNAME_STRICT_HTTPS value: "false"
KC_HOSTNAME_INTERNAL:直接填集群内部访问Keycloak的服务名加路径,也就是keycloak.svc/authKC_HOSTNAME_INTERNAL_PORT:Bitnami的Keycloak内部默认用80端口,直接填这个即可KC_HOSTNAME_STRICT_HTTPS:集群内部一般走HTTP访问,所以关掉严格HTTPS检查
另外你已经设置了httpRelativePath: /auth/,保持这个配置不变就行。
二、检查Realm配置是否存在硬编码
如果上面改完还是不行,登录Keycloak控制台(portal.local/auth/admin)手动检查:
- 进入
myshopRealm,点击Realm Settings -> General - 找到Frontend URL配置项,别让它硬编码成
portal.local/auth/realms/myshop- 留空的话,Keycloak会自动根据请求的主机名生成URL,这样外部和内部访问都能适配
三、修正Spring Boot应用的配置
部署在K8s集群内的Spring Boot应用,直接把Issuer地址改成内部服务地址:
# application.properties spring.security.oauth2.resourceserver.jwt.issuer-uri=http://keycloak.svc/auth/realms/myshop
或者用YAML格式:
# application.yml spring: security: oauth2: resourceserver: jwt: issuer-uri: http://keycloak.svc/auth/realms/myshop
注意这里用http://,因为集群内部服务默认走HTTP,要是你给Keycloak内部配置了HTTPS,再改成https://就行。
四、验证配置是否生效
重新部署Keycloak和Spring Boot应用后,访问集群内部的OpenID配置地址:http://keycloak.svc/auth/realms/myshop/.well-known/openid-configuration,检查返回的JSON中issuer字段是否为http://keycloak.svc/auth/realms/myshop,是的话就说明配置生效了。
内容的提问来源于stack exchange,提问作者sancho21

