为啥 Keycloak 使用 Session-Cookie 而不是 JWT Authorization Header

Posted

技术标签:

【中文标题】为啥 Keycloak 使用 Session-Cookie 而不是 JWT Authorization Header【英文标题】:Why does Keycloak use a Session-Cookie instead of JWT Authorization Header为什么 Keycloak 使用 Session-Cookie 而不是 JWT Authorization Header 【发布时间】:2020-10-14 12:35:35 【问题描述】:

我将 Keycloak 用于微服务架构。 当我想访问受保护的资源时,我会看到 Keycloak 登录表单并且可以登录。登录后我会被重定向到该资源。在请求标头中,我可以看到标头 Cookie: mongo-express=s%3AVpTxrBrZp_bb1kpZOuCo6nitgpTzI0YJ.6OS1ttu4hjcnut%2FG6zdyDnLk2B%2FrEmMEEw9jy2rCUrE; SESSION=510eb294-493e-4cb6-9cb8-1e09604a7fc7 已设置。 当我尝试使用 Authorization: Bearer ... 标头访问资源时(例如,来自 Postman 的先前 requestet JWT),我无法访问该资源。相反,我再次看到登录表单。

如何配置 Keycloak 以在登录后使用 JWT 而不是标头中的 Session 或至少接受带有 Bearer 令牌的 Authorization 标头?

【问题讨论】:

【参考方案1】:

你写:

当我想访问受保护的资源时,我会看到 Keycloak 登录表单并可以登录。登录后我会被重定向到该资源。

这让我假设您正在使用浏览器并发出 GET 请求。我假设浏览器正在使用OAuth 2.0 Authorization Code Grant Type,因此令牌在客户端(Web 服务器)和 Keycloak 服务器之间交换。而不是在网络浏览器和网络服务器之间。这是开发“受保护资源”的团队做出的决定,而不是您可以在不更改“受保护资源”的源代码的情况下更改的决定。

你也写:

在请求标头中,我可以看到标头 Cookie: mongo-express=s%3AVpTxrBrZp_bb1kpZOuCo6nitgpTzI0YJ.6OS1ttu4hjcnut%2FG6zdyDnLk2B%2FrEmMEEw9jy2rCUrE; SESSION=510eb294-493e-4cb6-9cb8-1e09604a7fc7 已设置。

如果您从头开始浏览器表单(或在 Chrome 中使用“新隐身窗口”或在 Firefox 中使用“新私人窗口”),我很确定您会在对第一个 GET 请求的响应中看到受保护的资源,您会在服务器 response 中找到Set-Cookie HTTP 标头(可能是重定向到 OAuth2 服务器的标头)。这就是受保护资源管理其会话的方式。对此你无能为力,我很害怕。

【讨论】:

其实我也是开发受保护资源(OAuth2资源服务器)的团队。如何更改代码以启用与 Web 浏览器的令牌交换?我使用 Spring Security 和 Keycloak 作为 OAuth2 IDP。我假设当您谈论受保护的资源时,您正在谈论 OAuth2 资源服务器(在我的情况下是 Spring API 网关)?当我想要一个无状态服务器时,为什么要在那里管理会话?我不在那里处理会话。还是您的意思是受保护资源的Keycloak?感谢您的建议@Peter V. Mørch 我想要实现的是:Web Browser ---Request---> Gateway (Resource Server) ---Redirect (to Login)---> Web Browser ---Authenticate-- -> Keycloak (IDP) ---Token--> Gateway ---Relay Token---> Web Browser ---Request with Token---> Gateway 您必须在浏览器中实现 Authorization Code Flow with Proof Key for Code Exchange (PKCE) 并将 JWT 访问令牌发送到您的服务器 并在服务器上验证令牌是否有效并由您的特定发行/签名OAuth2 服务器。不知道如何用 Spring 做最后一点。不过要小心。现在突然之间,页面上的所有 javascript(广告、第三方库、恶意浏览器扩展)都可以访问您的令牌。

以上是关于为啥 Keycloak 使用 Session-Cookie 而不是 JWT Authorization Header的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Keycloak 会不断重新部署相同的 .jar 文件?

keycloak,为啥后端频道需要重定向 url

KeyCloak用户rest api返回403禁止,为啥?

为啥 Spring Boot 不会重定向到 403 上的 Keycloak 登录页面?

为啥在较新版本的 Keycloak 中不允许使用身份验证流程中的脚本

为啥 keycloak 在页面刷新时未经授权?