首页 > 解决方案 > 在 Keycloak 中成功登录浏览器后,“500 错误:无法在仅承载模式下交换代码以获得授权”

问题描述

用户试图通过反向代理访问浏览器中的/hello url。

“500 错误:无法在仅承载模式下交换代码以获得授权”

用户在 Keycloak 登录页面上访问受保护的 url 成功登录后会弹出错误。

以下代码用于反向代理:

var Keycloak = require('keycloak-connect');
var session = require('express-session');
var memoryStore = new session.MemoryStore();

let keycloak = new Keycloak(memoryStore);
app = express();
app.use( keycloak.middleware() );
app.get( '/hello', keycloak.protect( 'realm:admin' ));

keycloak.json 是:

{
  "realm": "master",
  "auth-server-url": "https://127.0.0.1/auth",  
  "resource": "test_ui",
  "confidential-port": 0,  
  "credentials" : {
    "password" : "d31c4718-12e9-407b-9bf2-cb72734a23f0"
  }
}

客户端test_ui是保密的。添加bearer-only : truekeycloak.json会导致访问被拒绝错误而不是上述错误。

配置有什么问题?

标签: node.jsoauth-2.0authorizationopenid-connectkeycloak

解决方案


首先:您的keycloak.json配置和 node.jskeycloak.protect应用程序代码未对齐:

  • keycloak.json描述"realm":"master"
  • 但是您仅在领域调用keycloak.protection应用程序的GET /hello资源adminapp.get( '/hello', keycloak.protect( 'realm:admin' ));

尝试将领域更改为大师

app.get( '/hello', keycloak.protect( 'realm:master' ));

您可以使用 cURL 测试它是否有效

curl -i http://YOUR_APP_SERVER_HOST/hello -H "Authorization: Bearer YOUR_BEARER_TOKEN"

不要忘记在 KEYCLOAK 上设置不记名身份验证

https://www.keycloak.org/docs/3.1/authorization_services/topics/enforcer/keycloak-enforcement-bearer.html

并首先获得您的不记名代币

curl \
  -d 'client_id=YOUR_KEYCLOAK_CLIENT' \
  -d 'username=YOUR_USERNAME' \
  -d 'password=YOUR_PASSWORD' \
  -d 'grant_type=password' \
  'https://YOUR_KEYCLOAK_SERVER_HOST/auth/realms/YOUR_REALM/protocol/openid-connect/token'

现在,文学

这里发生的事情本质上是:

  • 在您的第一个请求中:您正在尝试访问需要不记名令牌身份验证的功能,但您正在使用授权交换代码。因此错误 500 响应。您是否首先使用您的用户凭据对您的 keycloak/auth身份验证服务端点进行身份验证,以获得该领域的有效承载令牌?或者相反,您是否错误地尝试使用您的用户凭据直接针对您的应用程序的服务GET /helloAPI 资源端点进行身份验证?

  • 然后,在您的第二个请求中,您尝试启用仅承载身份验证,但是:

    1. 您的客户端没有检查提供的响应 WWW-Authenticate 标头以确定所需的身份验证方法,最重要的是:
    2. 您的客户端没有发出一个新GET /hello请求,该请求提供了一个有效的 HTTP Authorization 标头以及您获得的 Bearer 令牌,该令牌对GET /hello分配的领域有效。因此,您只需得到一个 HTTP 身份验证错误响应(通常是401 UnauthorizedHTTP 响应,尽管403 Forbidden 有时会被使用)。

简而言之,您需要在客户端和应用服务器以及身份验证服务器配置上对齐领域和身份验证方案,因此:

  • 您的应用服务器端点GET /hello将发送一个WWW-AuthenticateHTTP 标头,指定所需的用户领域和身份验证方案。

  • 然后,您的客户端将使用提供的用户凭据在您的 keycloak 身份验证服务器上进行身份验证并接收 Bearer 令牌。

您必须已配置 keycloak 身份验证服务器以支持该领域所需的身份验证方案,并且用户必须具有在该领域上操作的权限。为此目的查看 keycloak 服务器管理控制台。

  • 最后,一旦为该领域和身份验证方案完成此操作,您的客户端将能够GET /hello向您的应用服务器发出请求,其中包含在 HTTPAuthorization标头上获取的 HTTP Bearer 令牌。卷曲示例:

    curl -i http://example.com/api/hello -H "授权:承载 mytoken123"

欲了解更多信息:


推荐阅读