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

disbfnqx  于 2023-11-17  发布在  Kubernetes
关注(0)|答案(1)|浏览(142)

bounty将在3天内过期。回答此问题可获得+300声望奖励。Nick正在寻找来自信誉良好的来源的**答案 *。

我在K8s集群中设置的副本上遇到authorization_code授权类型问题,并寻求建议和帮助。我的设置如下:
1.在1个节点上的1个Pod上运行的1个Keycloak服务器示例。
1.在2个不同节点上的2个pod上运行的2个后端服务器示例。(例如 api1 和 *api2 *)
基本上,这里的问题是,假设 api1 在认证工作流期间向Keycloak发起代码验证挑战,并且用户在使用有效的用户名和密码成功地与Keycloak进行认证后,Keycloak将调用后端服务器的redirectURI。然而,redirectURI而不是命中 api1,命中后端服务器 api2 的另一个示例。由于这个原因,api2 的Request对象的会话状态将没有code_verifier属性,因此我们无法调用/protocol/openid-connect/token api来获取访问令牌。
我试图实现的是,要么让redirectURI总是命中发起请求的同一个后端服务器示例,要么让后端服务器(api1api2)共享会话,以便无论谁发起请求,会话都将在成功通过Keycloak验证后始终保持code_verifier值。我知道这不是Keycloak具体的问题,而不是K8的事情(我想),但如果有人也遇到过这种情况之前,并设法做了适当的解决方案(不妥协HA),然后请分享你的知识在这里。
我试着检查我是否可以在Keycloak和后端服务器之间附加一个粘性会话,以便redirectURI总是命中启动auth请求的同一个后端服务器,但不幸的是,在社区中找不到任何线索或任何类似的问题。
任何帮助或建议都非常感谢。谢谢

gdx19jrr

gdx19jrr1#

您的API似乎在扮演基于浏览器的应用程序的前端后端的角色。这种类型的解决方案并不特定于Keycloak或Kubernetes。考虑在https://www.product.com的URL处登录Web应用程序。

代码流消息

代码流以这样的请求开始,后端产生两个随机值,分别为statecode_verifier。它将两者存储在一个临时加密的仅限HTTP的cookie中,然后形成一个授权请求URL。然后前端使用此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。

GET 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,BFF可以处理多个并发调用者。它也是无状态的,易于管理。没有不方便的托管限制,例如需要粘性会话,如果服务器出现故障,可能会导致可用性问题。
唯一的要求是使用相同的cookie加密密钥部署BFF的所有示例,以便示例api1可以解密示例api2发出的cookie。这可能是一个如下生成的值,并与加密算法(如AES256-GCM)一起使用:

openssl rand 32 | xxd -p -c 64

组件角色

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

  • API通常是资源服务器,其唯一的安全责任是验证访问令牌和实现基于声明的授权。
  • BFF充当OAuth客户端,为基于浏览器的应用程序提供服务,并将令牌排除在浏览器之外。通常的结果是基于浏览器的应用程序将每个API请求与仅HTTP的cookie凭据一起发送。BFF不是资源服务器,但可以实现为实用程序API。它们需要与基于浏览器的应用程序具有相同的父域关系,以便将cookie视为第一方,而不是因为浏览器cookie限制而被删除。例如,BFF可能在https://api.product.com这样的域中运行。

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

相关问题