我目前正在使用Spring Boot构建一个微服务后端,Zuul作为API网关,Keycloak作为身份验证和身份提供者。 对于我的前端,我目前正在使用带有授权代码授予功能的Angular作为SPA。 在将请求发送到微服务之前,API网关应通过Keycloak验证每个请求(如果用户被授权)。 每个微服务(ResourceServer)都应该能够通过使用自省端点来获取当前请求的用户信息。
实现此目标的正确方法是什么,或者这甚至是一个糟糕的设计,而我的方法也不正确?
答案 0 :(得分:0)
通常,您有两个选择:
给客户端的JWT :客户端(在您的情况下为Angular SPA)对JWT进行身份验证和接收。一方可以使用Keycloak公钥来验证JWT令牌。它还包含许多用户信息。
授予后端的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包含所有信息,您将获得一个不透明的令牌,该令牌只能针对自省端点进行验证。