如何实现多后端服务和解耦架构的单点登录

How to implement SSO with multi back-end services and decoupled architecture

背景:

有几个服务(spring 引导 REST API 服务和一些其他使用 REST 的产品 API)作为后端和一些 angular 应用程序(一些 web不同二级域名的站点)作为前端。

一个前端应用可以通过异步的方式调用一些后端服务(通过反向代理在同一个域下,不存在CORS问题)。

目标

SSO,即。如果用户成功登录前端应用程序,则用户无需再次登录即可访问其他应用程序。 (当然,在启用cookie的同一浏览器中)

问题

  1. REST API 应该遵循客户端凭据流(return 401 如果未通过身份验证)还是身份验证代码流(return 302 如果未通过身份验证)?

许多 documents/tips/posts 建议 REST API 应该遵循客户端凭证流程,因为它是无状态的并且不知道重定向 uri。但是,如果我没记错的话,不可能使用客户端凭证流来实现 OSS,否则所有后端服务都应该是 keycloak 中可以共享 client_idclient_secret.[=15 的同一个客户端=]

如果使用Authentication Code Flow,问题是前端如何在用户成功登录后获取响应数据。这个过程是这样的:

front-end             back-end     keycloak
    |  -- asyn call -->  |
    |  <-- HTTP 302 --   |
    |  -- redirect to login page -->  |
    |     <-- redirect to where ???-- |
  1. 如果问题 1 的答案遵循客户端凭证流程,那么在多个后端服务之间共享相同的 client_idclient_secret 是否是最佳做法?或者还有其他解决方案吗?

  2. 如果问题2的答案是按照Authentication Code Flow,那么登录成功后如何处理异步REST API调用?

1.) SSO 协议

应使用

Open ID Connect。理论上也有 SAML,但那个是为 Web 应用程序指定的,而不是为 SPA apps/REST APIs.

2.) 前端(SPA 应用程序)管理身份验证

您需要用户身份,因此客户端凭据流不正确。你需要Authorization Code Flow with Proof Key for Code Exchange (PKCE)。使用成熟的(OIDC 认证的)库(例如 https://github.com/damienbod/angular-auth-oidc-client),它们将管理一切(令牌刷新、路由授权、注销……)。您不需要任何名称中带有 Keycloak 的库(OIDC 是标准,必须实施,而不是 Keycloak)。 Fronted 为每个 API 请求添加访问令牌(例如使用 Angular 拦截器)。

3.) 后端 (REST APIs) 只需验证令牌

来自前端的调用是 XMLHttpRequest 请求 - 它们在后台。有 302 响应(重定向到 auth)没有意义。用户将无法看到它,所以这就是为什么应该返回 401 Unauthorized 的原因(然后前端可以有自己的业务逻辑来处理它——例如重定向到 auth)。所以后端不需要实现任何登录流程。他们只验证请求中使用的令牌的有效性。最终,他们进行授权,例如只有具有某些特定 groups/roles 的用户才能执行相同的操作 - 只有编辑才能编辑,只有管理员才能删除,否则使用正确的响应代码进行响应 - 403 Forbidden.