在后端API之前使用Keycloak Gatekeeper

时间:2019-10-21 16:07:10

标签: keycloak keycloak-gatekeeper

在运行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文件,但由于该文件未更改,因此似乎未使用。

后端的网守给出以下日志记录:

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

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

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

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

还通过在前端的Gatekeeper中用相同的加密密钥设置enable-refresh-tokens=true

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

刷新令牌可以过期或无效。撤消401时,前端应刷新页面,以便将用户重定向到Keycloak。

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