我正在外部 sso 中编写身份验证的后端实现。我使用 Spring Boot 3 进行微服务,Keycloak 负责身份验证。 Keycloak 包含多个领域来支持多租户。我们的服务和前端使用 jwt 令牌进行授权,因此作为 sso 身份验证的结果,我们应该收到 Keycloak 的令牌。
预计实施:
** 我尝试使用keycloak帐户客户端URL转到sso表单,Keycloak本身在redirect_uri中替换其URL并且身份验证成功,但这不是我需要的,因为前端已经有一个登录表单。
我的问题是: 步骤 3 中的链接应该是什么样的,“auth”微服务将在 Keycloak 中调用该链接?需要在重定向中插入什么内容 - 原始前端 URL、Keycloak URL 还是外部 sso 端点?如何返还 Keycloak 令牌?
我是这样写的: {keycloakUrl}/realms/{realmName}/protocol/openid-connect/auth?client_id={clientId}&redirect_uri={???}&response_type=code&scope=openId&kc_idp_hint={alias}
您想象的解决方案违背了当前的建议,并违反了多项 OAuth2 规则。
前端调用“bff”(前端的后端)微服务,将用户的登录信息作为输入传递
这不是 OAuth2 的工作原理。在 OAuth2 授权代码流程(这是唯一推荐的用户登录流程)中,前端和 OAuth2 客户端都不应访问用户凭据。只有授权服务器可以(Keycloak 或在您的情况下是其背后的 IDP)。
将用户重定向到外部 IDP 页面,绕过 Keycloak 表单
使用 Keycloak,这是通过在授权请求中提供
kc_idp_hint
参数来完成的。
连同 jwt 令牌一起重定向回原始前端页面
根据最新建议,OAuth2 令牌不应离开您的服务器。前端和后端之间的通信应使用会话 cookie 进行授权(并防止 CSRF)。 BFF 在会话中保留令牌,并在转发请求时用承载令牌替换会话 cookie。我在 Baeldung 写了一篇文章。
假设BFF是Spring Cloud Gateway实例:
authorization_code
(每个领域至少一个,如果您希望每个领域对外部 IDP 进行“直接访问”,则需要更多)
TokenRelay=
过滤器会用会话中的 Bearer 令牌替换会话 cookie
Baeldung文章中有解释。