1

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

这个想法是前端和后端共享kc-access令牌。

现在,访问令牌在后端 Gatekeeper 中过期。如果 SPA 在浏览器中刷新,则前端将重新路由到 Keycloak,并且需要新的访问令牌。但是,如果没有刷新,当令牌过期时,对 DOMAIN/graphql 的 POST 请求会失败并返回 307 状态码。浏览器不知道如何处理。浏览器日志记录提供"{"error":"RESTEASY003065: Cannot consume content type"}". 如果 POST 的内容类型标头被删除,则错误为“未提供 client_id”,而 client_id 包含在查询字符串中。

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

这就是我们通过将会话状态存储添加到后端的 Gatekeeper 来尝试的。我们正在使用以下配置:

- --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 文件,但它似乎没有被使用,因为该文件没有更改。

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

|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"}|

所以我们“无法找到用户的刷新令牌”,因为根据日志记录“没有找到会话状态”。

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

4

2 回答 2

2

它看起来不像一个好的设计。Keycloak Gatekeeper 使用授权代码流,这不是您所发现的 SPA 的最佳流程(在 SPA 案例中读取 Gatekeeper 提供的用户身份似乎非常骇人听闻)。

SPA 使用带有 PKCE 或隐式流的代码流,这些流使用静默令牌更新(而不是刷新令牌)。恕我直言,最好的选择是在前端(SPA)和后端(例如 API)中使用相同的客户端 ID。但是前端将受到带有 PKCE 的代码流的保护,它将处理自己的令牌更新。只有后端会受到 Gatekeeper 的保护(+--no-redirects设置对 API 保护有意义)

于 2019-10-21T20:42:00.067 回答
0

通过enable-refresh-tokens=true在前端的 Gatekeeper 中设置相同的加密密钥,设计工作。

用户检索前端并被重定向到 Keycloak。获得授权码。此授权代码由前端 Gatekeeper 交换为放置在前端 cookie 中的访问和刷新令牌。当使用过期的访问令牌调用后端时,刷新令牌被解密并用于获取新的访问令牌。

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

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

于 2019-10-24T10:46:33.433 回答