具有应用程序服务器副本的 K8s 上的 Keycloak oidc 身份验证问题

问题描述 投票:0回答:1

我在 K8s 集群中设置的副本上遇到

authorization_code
授权类型问题,并寻求建议和帮助。我的设置如下:

  1. 1 个 Keycloak 服务器实例在 1 个节点的 1 个 pod 上运行。
  2. 2 个后端服务器实例在 2 个不同节点的 2 个 Pod 上运行。 (说 api1api2

基本上,这里的问题是,假设如果api1在身份验证工作流程期间向Keycloak发起代码验证质询,并且用户使用有效的用户名和密码成功通过Keycloak进行身份验证后,Keycloak将调用后端服务器的redirectURI。但是,redirectURI 没有命中 api1,而是命中后端服务器的另一个实例 api2。因此,api2 的请求对象的会话状态不会具有

code_verifier
属性,因此我们无法调用
/protocol/openid-connect/token
api 来获取访问令牌。

我想要实现的目标是让redirectURI始终命中发起请求的同一个后端服务器实例,或者是否有办法让后端服务器(api1api2)共享会话这样,无论谁发起请求,在使用 Keycloak 成功进行身份验证后,会话将始终保留

code_verifier
值。我知道这不是 Keycloak 特定的问题,更多的是 K8s 的问题(我想),但如果有人以前也遇到过这种情况并设法做到了正确的解决方案(不损害 HA),那么请在这里分享您的知识。

我尝试检查是否可以在 Keycloak 和后端服务器之间附加一个粘性会话,以便重定向URI 始终命中启动身份验证请求的同一后端服务器,但遗憾的是找不到任何线索,也找不到社区中发布的任何类似问题.

非常感谢任何帮助或建议。谢谢

authentication kubernetes keycloak openid-connect replication
1个回答
0
投票

您的 API 似乎扮演着基于浏览器的应用程序的前端后端的角色。这种类型的解决方案并不特定于 Keycloak 或 Kubernetes。考虑通过 URL

https://www.product.com
登录 Web 应用程序。

代码流消息

代码流程从这样的请求开始,后端生成两个随机值,即

state
code_verifier
。它将两者存储在临时加密的仅 HTTP cookie 中,然后形成授权请求 URL。然后前端使用它将浏览器重定向到授权服务器:

GET https://login.example.com/oauth/v2/authorize?
   client_id=my-web-client&
   redirect_uri=https://www.product.com/callback&
   response_type=code&
   scope=openid profile&
   code_challenge=WhmRaP18B9z2zk...&
   code_challenge_method=S256&
   state=CfDJ8Nxa-YhPzjpBilDQz2C...

用户在授权服务器上登录,这可以通过多种可能的方式完成。然后,将响应返回到前端,后端处理该 URL。

https://www.product.com/callback?
  code=I9xL9DY9jAYHPuHSiW2OpWUaNRW4otei&
  state=CfDJ8Nxa-YhPzjpBilDQz2C...

此时BFF读取临时cookie并取回之前生成的两个随机值。它验证响应状态,然后发送授权代码授予请求,以将代码交换为令牌:

POST https://login.example.com/oauth/v2/token

client_id=my-web-client&
client_secret=***************&
code=I9xL9DY9jAYHPuHSiW2OpWUaNRW4otei&
grant_type=authorization_code&
redirect_uri=http://www.product.com/callback&
code_verifier=HlfffYlGy7SIX3pYHOMJfhnO5AhUW1eOIKfjR42ue28

Cookie 处理

通过使用 cookie,BFF 可以处理多个并发呼叫者。它也是无状态的并且易于管理。不存在不方便的托管限制,例如需要粘性会话,如果服务器发生故障,这可能会导致可用性问题。

唯一的要求是使用相同的 cookie 加密密钥部署 BFF 的所有实例,以便实例 api1 可以解密实例 api2 发出的 cookie。这可能是按如下方式生成的值,并与加密算法一起使用,例如

AES256-GCM
:

openssl rand 32 | xxd -p -c 64

组件角色

我建议在 OAuth 架构中以不同的方式描述这些组件:

  • API 通常是资源服务器,其唯一的安全职责是验证访问令牌并实现基于声明的授权。

  • BFF 充当 OAuth 客户端,为基于浏览器的应用程序提供服务并将令牌排除在浏览器之外。通常的结果是基于浏览器的应用程序使用仅 HTTP 的 cookie 凭据发送每个 API 请求。 BFF 不是资源服务器,但可以作为实用程序 API 实现。它们需要与基于浏览器的应用程序具有相同的父域关系,以便将 Cookie 视为第一方,并且不会因浏览器 Cookie 限制而被删除。例如。 BFF 可能在诸如

    https://api.product.com
    之类的域中运行。

如果我对这个问题有任何误解,请回复...

© www.soinside.com 2019 - 2024. All rights reserved.