java - 使用 Keycloak 作为授权服务器,使用 Zuul 作为 API 网关
问题描述
我目前正在使用 Spring Boot、Zuul 作为 API 网关和 Keycloak 作为身份验证和身份提供者构建微服务后端。对于我的前端,我目前使用 Angular 作为授权代码授予的 SPA。API 网关应在将每个请求发送到微服务之前通过 Keycloak 验证每个请求(如果用户已获得授权)。每个微服务(ResourceServer)都应该能够通过使用自省端点获取当前请求的用户信息。
实现这个的正确方法是什么,或者这甚至是一个糟糕的设计,我走错了路?
解决方案
通常,您有两种选择:
提供给客户端的 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。
这些描述假定您使用的是 Keycloak 支持的Open ID Connect 。如果您使用OAuth 2设置,大多数事情仍然适用,但一些细节会更复杂,例如,代替包含所有信息的 JWT,您将获得一个只能针对自省端点进行验证的不透明令牌。
推荐阅读
- numpy - 不等式的最小二乘线性规划
- algorithm - 线性代数,几何。点积的值为 0
- swift - Swift GCD:为什么信号处理程序在函数中不起作用
- scala - 使用枢轴旋转单行 Spark 数据框
- python - 如何模拟在类属性中调用的函数?
- python - Python:通过行中的非零值获取列名
- javascript - amCharts (V4):无年份的 DateAxis 中的第一个月格式
- vue.js - 如何修复终端中的 npm run serve 错误
- javascript - React.js 中每个表格行的单独复选框
- node.js - 猫鼬今天使用 $gte 和 $lte 查找日期?