使用反向代理时Oauth2 Bff无法连接Keycloak的问题修复
修复Keycloak反向代理下的颁发者不匹配问题
问题描述
将BFF应用通过反向代理连接Keycloak时,出现错误:配置元数据中的颁发者"http://localhost:8080/auth/realms/baeldung"与请求的颁发者"http://localhost:7080/auth/realms/baeldung"不匹配。核心原因是Keycloak默认使用自身服务地址作为颁发者,而反向代理改变了外部访问地址,导致元数据与实际请求地址不一致。
解决方案
1. 配置Keycloak领域的前端URL
登录Keycloak管理控制台,进入baeldung领域的领域设置 -> 常规页面,设置前端URL为反向代理的访问地址:
http://localhost:7080/auth/realms/baeldung
该配置会让Keycloak在生成OIDC元数据和JWT令牌时,使用这个反向代理地址作为颁发者,确保与BFF配置一致。
2. 确保反向代理正确传递转发头
反向代理需要传递X-Forwarded-*系列头,让Keycloak和BFF识别真实的外部请求地址。以Nginx为例,添加以下配置:
location /auth { proxy_pass http://localhost:8080/auth; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $host:$server_port; }
3. 调整BFF的网关配置
在BFF的YML配置中,开启Spring Cloud Gateway对转发头的支持,确保网关能正确处理代理传递的地址信息:
spring: cloud: gateway: x-forwarded: enabled: true
4. 验证配置有效性
访问反向代理地址下的Keycloak OIDC元数据端点:
http://localhost:7080/auth/realms/baeldung/.well-known/openid-configuration
检查返回结果中的issuer字段,确认其值为http://localhost:7080/auth/realms/baeldung,与BFF配置中的issuer一致即可。
用户提供的BFF配置(已添加转发头支持)
# Custom properties to ease configuration overrides # on command-line or IDE launch configurations scheme: http hostname: localhost reverse-proxy-port: 7080 reverse-proxy-uri: ${scheme}://${hostname}:${reverse-proxy-port} authorization-server-prefix: /auth issuer: http://localhost:7080${authorization-server-prefix}/realms/baeldung client-id: baeldung-confidential client-secret: secret username-claim-json-path: $.preferred_username authorities-json-path: $.realm_access.roles bff-port: 7081 bff-prefix: /bff resource-server-port: 7084 audience: server: port: ${bff-port} ssl: enabled: false spring: cloud: gateway: routes: - id: bff uri: ${scheme}://${hostname}:${resource-server-port} predicates: - Path=/api/** filters: - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin - TokenRelay= - SaveSession - StripPrefix=1 x-forwarded: enabled: true # 新增转发头支持配置 security: oauth2: client: provider: baeldung: issuer-uri: ${issuer} registration: baeldung: provider: baeldung authorization-grant-type: authorization_code client-id: ${client-id} client-secret: ${client-secret} scope: openid,profile,email,offline_access com: c4-soft: springaddons: oidc: ops: - iss: ${issuer} authorities: - path: ${authorities-json-path} aud: ${audience} # SecurityFilterChain with oauth2Login() (sessions and CSRF protection enabled) client: client-uri: ${reverse-proxy-uri}${bff-prefix} security-matchers: - /api/** - /login/** - /oauth2/** - /logout/** permit-all: - /api/** - /login/** - /oauth2/** - /logout/connect/back-channel/baeldung post-logout-redirect-host: ${hostname} csrf: cookie-accessible-from-js oauth2-redirections: rp-initiated-logout: ACCEPTED back-channel-logout: enabled: true # internal-logout-uri: ${reverse-proxy-uri}${bff-prefix}/logout # should work too, but there is no reason to go through the reverse proxy for this internal call internal-logout-uri: ${scheme}://localhost:${bff-port}/logout # SecurityFilterChain with oauth2ResourceServer() (sessions and CSRF protection disabled) resourceserver: permit-all: - /login-options - /error - /v3/api-docs/** - /swagger-ui/** - /actuator/health/readiness - /actuator/health/liveness management: endpoint: health: probes: enabled: true endpoints: web: exposure: include: '*' health: livenessstate: enabled: true readinessstate: enabled: true logging: level: root: INFO org: springframework: boot: INFO security: TRACE web: INFO --- spring: config: activate: on-profile: ssl server: ssl: enabled: true scheme: https --- spring: config: activate: on-profile: cognito issuer: https://cognito-idp.us-west-2.amazonaws.com/us-west-2_RzhmgLwjl client-id: 12olioff63qklfe9nio746es9f client-secret: change-me username-claim-json-path: username authorities-json-path: $.cognito:groups com: c4-soft: springaddons: oidc: client: oauth2-logout: baeldung: uri: https://spring-addons.auth.us-west-2.amazoncognito.com/logout client-id-request-param: client_id post-logout-uri-request-param: logout_uri --- spring: config: activate: on-profile: auth0 issuer: https://dev-ch4mpy.eu.auth0.com/ client-id: yWgZDRJLAksXta8BoudYfkF5kus2zv2Q client-secret: change-me username-claim-json-path: $['https://c4-soft.com/user']['name'] authorities-json-path: $['https://c4-soft.com/user']['roles'] audience: bff.baeldung.com com: c4-soft: springaddons: oidc: client: authorization-params: baeldung: audience: ${audience} oauth2-logout: baeldung: uri: ${issuer}v2/logout client-id-request-param: client_id post-logout-uri-request-param: returnTo
内容的提问来源于stack exchange,提问作者Kado
相关产品推荐
相关产品推荐

