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

Posted

技术标签:

【中文标题】如何实现多后端服务和解耦架构的单点登录【英文标题】:How to implement SSO with multi back-end services and decoupled architecture 【发布时间】:2021-09-20 06:43:45 【问题描述】:

背景

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

一个前端应用程序可以使用异步方法调用一些后端服务(它们通过反向代理在同一个域下,因此不会出现CORS问题)。

目标

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

问题

    REST API 应该遵循客户端凭据流(如果未通过身份验证则返回 401)或身份验证代码流(如果未通过身份验证则返回 302)?

许多文档/提示/帖子建议 REST API 应遵循客户端凭据流,因为它是无状态的并且不知道重定向 uri。但是,如果我没记错的话,使用客户端凭据流实现 OSS 是不可能的,否则所有后端服务都应该是 keycloak 中的同一客户端,可以共享 client_idclient_secret

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

front-end             back-end     keycloak
    |  -- asyn call -->  |
    |  <-- HTTP 302 --   |
    |  -- redirect to login page -->  |
    |     <-- redirect to where ???-- |

    如果问题 1 的答案是遵循客户端凭据流,那么在多个后端服务之间共享相同的 client_idclient_secret 是最佳做法吗?或者有其他解决方案吗?

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

【问题讨论】:

【参考方案1】:

1.) SSO 协议

Open ID Connect 应该被使用。理论上还有SAML,但它是为网络应用程序指定的,而不是为 SPA 应用程序/REST API 指定的。

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 API)只是验证令牌

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

【讨论】:

非常感谢您的详细回复。它确实是一个优秀的架构。但是,我仍然对一件事感到困惑。你说如果后端服务返回 401,那么前端应用程序应该使用自己的业务逻辑来处理登录过程。生成用户认证请求并重定向到keycloak的登录页面的过程是否应该由OIDC客户端/库处理? @TonnyTc 前端生成/重定向到 Keycloak 登录页面。当然你可以自己实现它,但你必须根据 OIDC 规范实现 OIDC Authorization Code Flow with Proof Key for Code Exchange (PKCE) 流、令牌刷新、注销。那么,为什么要重新发明***,当您可以使用适当实现的现成库时。

以上是关于如何实现多后端服务和解耦架构的单点登录的主要内容,如果未能解决你的问题,请参考以下文章

nginx反代varnish缓存服务器实现后端amp动静分离架构

认证和SSO-基于OAuth2单点登陆基本架构

前后端分离的项目如何实现登录状态的保持。

前端(SPA)和后端解耦:JWT 认证 + 持久登录

CloudKit 用户身份验证与单点登录

.NET CORE开源 DDD微服务 支持 多租户 单点登录 多级缓存自动任务分布式日志授权和鉴权 网关 注册与发现 系统架构 docker部署