node.js - 在 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 : true
到keycloak.json会导致访问被拒绝错误而不是上述错误。
配置有什么问题?
解决方案
首先:您的keycloak.json
配置和 node.jskeycloak.protect
应用程序代码未对齐:
keycloak.json
描述"realm":"master"
- 但是您仅在领域调用
keycloak.protection
应用程序的GET /hello
资源admin
:app.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 上设置不记名身份验证
并首先获得您的不记名代币
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 /hello
API 资源端点进行身份验证?然后,在您的第二个请求中,您尝试启用仅承载身份验证,但是:
- 您的客户端没有检查提供的响应 WWW-Authenticate 标头以确定所需的身份验证方法,最重要的是:
- 您的客户端没有发出一个新
GET /hello
请求,该请求提供了一个有效的 HTTPAuthorization
标头以及您获得的 Bearer 令牌,该令牌对GET /hello
分配的领域有效。因此,您只需得到一个 HTTP 身份验证错误响应(通常是401 Unauthorized
HTTP 响应,尽管403 Forbidden
有时会被使用)。
简而言之,您需要在客户端和应用服务器以及身份验证服务器配置上对齐领域和身份验证方案,因此:
您的应用服务器端点
GET /hello
将发送一个WWW-Authenticate
HTTP 标头,指定所需的用户领域和身份验证方案。然后,您的客户端将使用提供的用户凭据在您的 keycloak 身份验证服务器上进行身份验证并接收 Bearer 令牌。
您必须已配置 keycloak 身份验证服务器以支持该领域所需的身份验证方案,并且用户必须具有在该领域上操作的权限。为此目的查看 keycloak 服务器管理控制台。
最后,一旦为该领域和身份验证方案完成此操作,您的客户端将能够
GET /hello
向您的应用服务器发出请求,其中包含在 HTTPAuthorization
标头上获取的 HTTP Bearer 令牌。卷曲示例:curl -i http://example.com/api/hello -H "授权:承载 mytoken123"
欲了解更多信息:
作为 OAuth 2.0 标准的一部分,在RFC 6750 OAuth 2.0 Bearer Token Usage中描述了承载身份验证流程。
Keycloack 文档描述了如何在
keycloak.json
.保护您的 node.js 应用程序
GET /hello
资源的所述步骤(您可能希望使用自定义处理程序)。
推荐阅读
- r - 锁定环境但不锁定 .Random.seed
- python - Python散点图:如何使用与颜色周期具有相同颜色的颜色图
- .htaccess - .htaccess 来自旧休息端点新端点的重写请求
- android - 导航架构组件 singleTask 或 singleInstance 在返回堆栈中
- sql-server - 无法使用不同的服务器版本号运行 .sql 脚本
- java - 如何在 Spring Boot API 中实现 RabbitMQ 消费者部分(接收器)
- java - 如何在休息响应中归档的 json 文本中包含超链接
- php - 如何将当前时间与 PHP 表中提到的时间进行比较,以确定活动/过期/即将到来?
- bash - 如何阻止 wget 顺序下载在 url 中包含括号?
- angular - Angular 7 - 仅在选中复选框时验证输入字段