使用 Keycloak 作为授权服务器,Zuul 作为 API 网关

Posted

技术标签:

【中文标题】使用 Keycloak 作为授权服务器,Zuul 作为 API 网关【英文标题】:Using Keycloak as Authorization Server with Zuul as API Gateway 【发布时间】:2019-11-27 09:48:32 【问题描述】:

我目前正在使用 Spring Boot 构建微服务后端,Zuul 作为 API 网关,Keycloak 作为身份验证和身份提供者。 对于我的前端,我目前使用 Angular 作为授权代码授予的 SPA。 API 网关应在将每个请求发送到微服务之前通过 Keycloak 验证每个请求(如果用户已获得授权)。 每个微服务(ResourceServer)都应该能够通过自省端点获取当前请求的用户信息。

实现这一点的正确方法是什么,或者这甚至是一个糟糕的设计,我走错了路?

【问题讨论】:

【参考方案1】:

通常,您有两种选择:

    JWT 提供给客户端:客户端(在您的情况下为 Angular SPA)进行身份验证并接收 JWT。 JWT 令牌可以由一方使用 Keycloak 公钥进行验证。它还包含很多用户信息。

    JWT 给予后端:客户端获得临时授权码授予。它被转发到后端系统,后端系统将其交换为 JWT。后端系统需要创建用户会话,将 JWT 存储在用户会话中,并使用会话 ID cookie(或类似机制)将客户端与会话匹配。

所提议的架构是两个世界的混合体。选项 1 会更自然。

选项 1:客户端通过 Keycloak 进行身份验证并获取 JWT。然后它将 JWT 附加到每个请求。 Zuul 可以检查 JWT 是否由受信任的 Keycloak 实例签名并且它尚未过期(无需联系 Keycloak)。微服务也可以这样做。如果需要的不仅仅是基本的用户信息,微服务可以联系 Keycloak。

选项 2: 我无法告诉您 Zuul 是否可以使用选项 2。让我们假设它是。如果是这样,网关会将未经身份验证的请求重定向到 Keycloak。一旦客户端收到授权码授权,它就会被重定向到 API 网关。 API 网关然后联系 Keycloak 以交换 JWT 的代码并将其保存在会话中。客户端会获得一个会话 ID。当请求被转发到微服务时,JWT 被添加到请求中。客户端永远不会看到 JWT。

这些描述假设您使用的是 Open ID Connect,它受 Keycloak 支持。如果您使用 OAuth 2 设置,大多数情况仍然适用,但一些细节会更复杂,例如而不是包含所有信息的 JWT,您将获得一个只能针对自省端点进行验证的不透明令牌。

【讨论】:

您好,谢谢您的回答。是的,我正在使用 Open ID Connect。我想使用带有不透明令牌的自省端点来使用 Keycloak 验证每个请求。我也不太想用 jwt,因为我觉得它真的很危险。 为什么你认为 JWT 比不透明的令牌更危险?主要危险是黑客可以获取令牌并自己访问系统(令牌劫持)。在这方面,如果正确实施,选项 2 会更安全——但也更复杂。另请参阅OWASP's tips regarding token sidejacking(带有 Java 特定提示)。我认为不透明令牌与 JWT 相比没有任何主要的安全优势。 因为不能使 JWT 失效,所以必须更改密钥。当然,不透明的令牌也可能被盗。 如果人们明确注销(很少见)或者如果您有一个可以检测到不活动状态的有状态后端,则令牌提前到期可以提高安全性。你的后端支持会话状态吗? 不,它完全是无状态的。

以上是关于使用 Keycloak 作为授权服务器,Zuul 作为 API 网关的主要内容,如果未能解决你的问题,请参考以下文章

apache shiro:在 shiro.ini 中添加啥以使用 JWT 和 keycloak 作为授权服务器进行客户端身份验证

使用 KeyCloak 的 OAuth2 授权接口

在 Keycloak 中禁用刷新令牌

Keycloak 授权 - 最佳实践角色与组

为啥带有 Netflix Zuul 反向代理的 Keycloak OAUTH2 不传递令牌

使用 Keycloak 构建 Java OAuth2.0 授权服务器