Keycloak 在后端API前面使用KeyClope网关守护程序

Keycloak 在后端API前面使用KeyClope网关守护程序,keycloak,keycloak-gatekeeper,louketo-proxy,Keycloak,Keycloak Gatekeeper,Louketo Proxy,在单页应用程序(SPA)上,对域/graphql的域调用被重新路由到后端。前端和后端都通过KeyClope Gatekeeper实例进行保护 其思想是前端和后端共享kc访问令牌 现在,访问令牌在后端网守中过期。如果SPA在浏览器中刷新,前端将被重新路由到KeyClope,并且需要一个新的访问令牌。但是如果没有刷新,当令牌过期时,对域/graphql的POST请求将失败,状态代码为307。浏览器不知道如何处理此问题。浏览器日志记录给出一个“{”错误:“RESTEASY003065:无法使用内容类型

在单页应用程序(SPA)上,对域/graphql的域调用被重新路由到后端。前端和后端都通过KeyClope Gatekeeper实例进行保护

其思想是前端和后端共享
kc访问
令牌

现在,访问令牌在后端网守中过期。如果SPA在浏览器中刷新,前端将被重新路由到KeyClope,并且需要一个新的访问令牌。但是如果没有刷新,当令牌过期时,对域/graphql的POST请求将失败,状态代码为307。浏览器不知道如何处理此问题。浏览器日志记录给出一个
“{”错误:“RESTEASY003065:无法使用内容类型“}”
。如果文章的内容类型标题被删除,则错误为“未提供客户端id”,而客户端id包含在查询字符串中

将POST请求重定向到KeyClope可能不是最好的解决方案。如果后端刷新其访问令牌本身,则会更干净

这就是我们通过向后端的网关守护者添加会话状态存储所尝试的。我们正在使用以下配置:

- --discovery-url=DISCOVERY_URL
- --client-id=CLIENT_ID
- --client-secret=****
- --enable-refresh-tokens=true
- --encryption-key=0123456789012345
- --store-url=boltdb:///boltdb
- --listen=0.0.0.0:3001
- --verbose=true
- --redirection-url=REDIRECTION_URL
- --upstream-url=http://127.0.0.1:3000
这确实会在Gatekeeper中创建一个/boltdb文件,但似乎没有使用它,因为该文件没有更改

后端的网守提供以下日志记录:

|1.5716729131430433e+09|debug|keycloak-gatekeeper/session.go:51|found the user identity|{"id": "b5b659cd-148e-4f23-bf2f-28e6f207f6c7", "name": "piet", "email": "", "roles": "offline_access,dashboard_viewer,uma_authorization,account:manage-account,account:manage-account-links,account:view-profile", "groups": ""}|
|1.5716729131462774e+09|info|keycloak-gatekeeper/middleware.go:154|accces token for user has expired, attemping to refresh the token|{"client_ip": "****", "email": ""}|
|1.5716729131463811e+09|error|keycloak-gatekeeper/middleware.go:161|unable to find a refresh token for user|{"client_ip": "**", "email": "", "error": "no session state found"}|
因此,根据日志记录,我们“无法找到用户的刷新令牌”,因为“未找到会话状态”


有人知道如何启用令牌刷新吗?

这看起来不是一个好的设计。KeyClope Gatekeeper使用授权代码流,这并不是您发现的SPA的最佳流(在SPA案例中,读取Gatekeeper提供的用户身份似乎是非常黑客的)


SPA将代码流与PKCE或隐式流一起使用,这些流使用静默令牌更新(而不是刷新令牌)。IMHO最好的选择是在前端(SPA)和后端(如API)使用相同的客户端id。但前端将受到PKCE代码流的保护,它将处理自己的令牌更新。只有后端将受到Gatekeeper的保护(+
--没有重定向
设置对API保护有意义)

通过在前端的Gatekeeper中使用相同的加密密钥设置
启用刷新令牌=true
,设计工作

用户检索前端并被重定向到KeyClope。获得授权码。该授权码由前端网关守卫交换,以获得放在前端cookie中的访问和刷新令牌。当使用过期的访问令牌调用后端时,刷新令牌将被解密并用于获取新的访问令牌

刷新令牌可能会过期或失效。当返回401时,前端应刷新页面,以便将用户重定向到KeyClope


更安全的做法是不将代币存储在前端cookie中,而是存储在共享存储中

谢谢。然而,前端是有效的。后端没有。但是你说前端应该更新它自己的代币?那么这个令牌也会被发送并在后端使用吗?如果没有重定向,我们会得到401而不是重定向?为什么您认为设置enable refresh tokens=true不会在后端刷新令牌?前端初始页面受到保护,然后通过后端调用检索所有需要的信息,其中需要知道用户身份只在后端刷新令牌不是很好吗?这难道不应该也起作用吗?我不明白为什么商店启用时会显示“找不到会话状态”。PKCE用于没有后端的移动应用程序或SPA对吗?我们有一个后端。我不明白我们为什么要用PKCE实现代码流。后端令牌更新是否存在安全风险?我是说前端将使用PKCE,它将处理令牌更新,后端(API)将由Gatekeeper保护,Gatekeeper实际上只验证访问令牌。