javascript - Keycloak 内省端点
问题描述
我正在尝试从我的前端应用程序访问我的 Keycloak 服务器/openid-connect/token/introspect中的自省端点,但我收到下一个错误:
Access to fetch at 'http://localhost:8180/auth/realms/backoffice/protocol/openid-connect/token/introspect' from origin 'http://localhost:8080' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
使用 Postman、curl 或 Node 应用程序,此请求工作正常,但从我的前端应用程序使用 fetch 方法会抛出此错误。我不确定是否可以从浏览器中的前端应用程序查询自省端点,或者是否只能从服务器应用程序查询。
其他端点如:
- openid-连接/令牌:
- 开放ID连接/用户信息:
使用 Postman JS 代码可以正常工作。
密钥斗篷配置
我在 Keycloak 中的客户设置了Web Origins *和Access Type 机密。
客户代码
我的前端应用程序只是 Postman 代码 JS,我使用节点 http-server 部署它。
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
var urlencoded = new URLSearchParams();
urlencoded.append("client_id", "my-client");
urlencoded.append("client_secret", "my-secret");
urlencoded.append("token", "eyJ...oCA");
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: urlencoded,
redirect: 'follow'
};
fetch("http://localhost:8180/auth/realms/backoffice/protocol/openid-connect/token/introspect", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
标头响应
userinfo 端点中的标头响应带有 Access-Control-Allow-Origin 和 Access-Control-Allow-Credentials 但自省端点中不存在。
解决方案
从外观上看,Keycloak 服务器阻止为自省端点设置 CORS 标头。这可能是错误或设计使然。我试过了,我得到了同样的错误。
如果您真的想从 Web 应用程序访问自省端点,您可以在 Keycloak 服务器前设置 NGINX 反向代理,并使用它来添加缺少的标头。
话虽如此,根据oauth.com,您不应该将自省端点对公众开放,这是您目前正在做的事情,因为任何人都可以从您的 Web 应用程序中检索客户端 ID 和密码。
如果内省端点保持打开且未受到限制,则它为攻击者提供了一种轮询端点以获取有效令牌的方法。为了防止这种情况,服务器必须要求使用端点对客户端进行身份验证,或者仅通过防火墙等其他方式使端点对内部服务器可用。
这可以解释不允许 CORS 的决定。
另一件事,您似乎忘记设置token_type_hint
查看此 stackoverflow帖子以获取更多信息。
推荐阅读
- logstash - 解析 nginx 错误日志的 grok 模式的问题
- php - 如何使用 PHP 将月份添加到特定日期?
- intel - 错误:无法安全地从此类存储库进行更新,因此默认禁用
- javascript - 未捕获的 URIError:尝试解码 var 时 URI 格式错误(javascript)
- c# - 当 RowState = Modified 时 SQLDataAdapter.Update() 不更新
- python - 命名两个或多个相关 Python 变量的首选方法是什么?
- python - 使用 os.walk 将多个文本文件转换为 csv
- xquery - 如何将纬度和经度值替换为一个元素值?
- botframework - 聊天对话的长期历史记录(恢复对话)
- neo4j - Neo4J 对象未在使用 KafkaListener 进行第二次保存时保存