使用 OpenId Connect 的多个 Liberty 服务器 SSO

Multiple Liberty servers SSO with OpenId Connect

我正在尝试使用 openidconnect 插件在多个 Liberty 服务器之间实现 SSO。使用 Keycloak 作为 openid 提供者和配置是这样的。

<webAppSecurity  logoutOnHttpSessionExpire="true"  ssoCookieName="LtpaToken2" />
<openidConnectClient id="RP" scope="openid" signatureAlgorithm="RS256"
    clientId="liberty" clientSecret="secret"
    discoveryEndpointUrl="https://localhost:8243/auth/realms/abc/.well-known/openid-configuration"
    userIdentityToCreateSubject="id"
    groupIdentifier="groupof"
    realmName="abc"
    />
<application type="ear" location="/opt/was-services.ear"></application>

这些是一台服务器发生的事情

  1. 在受保护的资源https://localhost:9444/test-services/secure/whoAmI 访问后,它会将我重定向到 Keycloak 以登录
  2. 使用 keycloak 成功登录后,它使用代码和状态
  3. 将我重定向回 Liberty 服务器 https://localhost:9444/oidcclient/redirect/RP
  4. (内部)调用 keycloak 的 Openid 插件使用代码获取 accessToken 和 idToken,并创建主题并使用 cookie WASOidcCode(只有一个 cookie)将我重定向回 https://localhost:9444/test-services/secure/whoAmI(只有一个 cookie)
  5. 一旦浏览器重定向到 whoAmI 端点,它就会通过以下 cookie 获得成功响应
Set-Cookie: WASOidcCode=""; Expires=Thu, 01 Dec 1994 16:00:00 GMT; Path=/; HttpOnly
Set-Cookie: WASOidcStaten1705148370=""; Expires=Thu, 01 Dec 1994 16:00:00 GMT; Path=/; HttpOnly
Set-Cookie: WASOidcStaten1705148370=""; Expires=Thu, 01 Dec 1994 16:00:00 GMT; Path=/; HttpOnly
Set-Cookie: WASOidcState=""; Expires=Thu, 01 Dec 1994 16:00:00 GMT; Path=/; HttpOnly
Set-Cookie: WASReqURLOidc=""; Expires=Thu, 01 Dec 1994 16:00:00 GMT; Path=/; HttpOnly
Set-Cookie: WASOidcCode=""; Expires=Thu, 01 Dec 1994 16:00:00 GMT; Path=/; HttpOnly
Set-Cookie: WASOidcNonce=""; Expires=Thu, 01 Dec 1994 16:00:00 GMT; Path=/; HttpOnly
Set-Cookie: WASOidcClient_p2088384039=viftWG2c2OLfstAJs20olB1ik6sqt0AN; Path=/; HttpOnly
Set-Cookie: WAS_p1727417709=EdONwO1su3sXZp3OFPlbu7lsbwmUF5GKbAdQswzuKQE9oA/If0pLRO4T5owRXm+3c7W+LEHNmDGFBisCe14enxnZPMuM2sTO/gTy+RT10gUVDC5r++HR3UHBLov7GmBPrmwTK8ISMZnSEgMxMr7RLTUi917dlBVEQ9ga14gN8PuaUA0lW+h1i/Ya870qZ+HvjoH6EDnwKmGFC9j8Ba1Unkr8FWRO4JUy8VVzJX5NNT/fmbns2CXnB69ICMk9gMC4YaYpJ1LRzfn22iv9404Vq0qy8lwEeQTQx/urz8bu6qI930+eJI0KqP3O2Kv434p6bdexg5eNdvIYKw9Ldz4J96SHrjCQOHVuYt6hzfHUg9DT8QIrQizznbZU2D8xKe3TDfeqActgK044AkBA+88K7sRMScbxnTAeggjZqYHrDjIe/8MlBcmfAxsYr0t5yzHj/QaQlJzh16xmzVS2+FdMlQ==; Path=/; HttpOnly

但是当我转到另一个自由服务器(假设 https://localhost:9544/test-services/secure/whoAmI)时,后台发生了相同的重定向(没有 OP 登录,因为我已经登录了),但这次我得到了另一个名称不同的 WAS cookie WAS_p1737373709.

问题

  1. 这些 WAS_xxxxx cookie 是否像 LtpaToken2
  2. 为什么 2 个服务器给了 2 个不同的 cookie
  3. 我们能否在不同服务器之间移动时避免这些 OP 重定向(我们能否将客户详细信息存储在 cookie 或其他地方)?
  4. AJAX 调用如何工作,假设我登录到 SeverA,但对 ServerB 进行 AJAX 调用。
  5. 如果每个服务器都需要代码进行内省(在授权代码流中),我们是否需要公开每个服务器的 oidcclient 端点?
  6. 如何退出所有服务器?我们有单一注销端点吗?

如何理解 Liberty 中的 OIDC 实现?

这里尝试解释 -

Q1) 这些 WAS_xxxxx cookie 是否类似于 LtpaToken2?

A1) 是的。

Q2) 为什么有两个不同的 cookie?

A2) 当两个不同的服务器发出一个同名的cookie 时,第二个替换第一个,然后用户返回到第一台服务器时会遇到意想不到的身份验证挑战。使用不同的名称避免了这个问题,但它也阻止了在不返回供应商的情况下跨多个相同服务器的透明负载平衡。

问题 6) 我们有单一注销端点吗?

A6) OIDC 没有分布式注销,但 SAML 有。但是,当使用共享 cookie 时,服务器 "a" 删除 cookie 的效果也会阻止对服务器 b、c、d 等的访问。

Q3) 我们能否在不同服务器之间移动时避免这些 OP 重定向(我们能否将客户详细信息存储在 cookie 或其他地方)?

A3) 是的,尽管需要使用不同类型的 cookie。 LTPA cookie 不保存有关用户的完整信息,服务器必须回调用户注册表(例如 LDAP)才能获取它。但是,当使用 OIDC 等远程身份提供者时,这是不可能的。通过添加 jwtsso-1.0 功能部件,可以将 LTPA cookie 替换为 JWT cookie。这样就可以在不返回提供商的情况下跨服务器共享 cookie。

Q4) AJAX 调用如何工作,假设我登录到 SeverA,但对 ServerB 进行 AJAX 调用。

A4) #3 完成后,#4 成为可能,但服务器的 CORS 设置可能需要调整。

Q5) 我们是否需要公开每个服务器的 oidcclient 端点?

A5) 在大多数情况下,使用 JWT cookie 应该是自包含的,但所有客户端仍然需要能够与提供者通信,以防它们是启动登录过程的人。

要使用 Liberty 20.004 或更高版本实现 #3,请添加此功能:

<feature>jwtsso-1.0</feature>

并将此属性添加到 openIdConnectClient xml 元素:

includeCustomCacheKeyInSubject="false"

如果服务器不完全相同(即 Docker 容器),那么您将需要更多自定义,以便它们构建相同的 jwt,尽管具有不同的主机名 and/or 端口:

<jwtSso jwtBuilderRef="myBuilder" />
<jwtBuilder id="myBuilder" issuer="https://localhost:9443/jwt"
    jwkEnabled="false" />

  <mpJwt id="myMpJwt" issuer="https://localhost:9443/jwt" />

您会看到一个名为 JWT 的新 cookie。

要在多个服务器之间工作,它们的密钥库(用于签署 JWT)和信任库(用于读取)必须配置相同。在所有服务器之间共享相同的 key.p12 文件是一种方法。

希望对您有所帮助。