当前位置: 首页 > 知识库问答 >
问题:

401中的KeyCloak CORS标头

海宁
2023-03-14

我有两个钥匙扣客户,

  • Angular 4:具有访问类型凭据身份验证
  • 一个JAX-RS应用程序(它将是资源服务器):具有仅承载身份验证!在这个客户端中,我们激活CORS,如下面的json所示
{
  "realm": "demo-realm",
  "bearer-only": true,
  "auth-server-url": "http://demo-keycloack-server:8080/auth",
  "ssl-required": "external",
  "resource": "demo-server",
  "enable-cors": true
}

问题是,JAX-RS应用程序的状态代码为401(未授权)的HTTP响应没有给javascript客户端带来所需的CORS报头!

当HTTP状态为401时,我们如何添加相应的CORS标头?

共有1个答案

勾安翔
2023-03-14

(注:此行为已在KeyClope tomcat阀6.0.1中重现)

[更新以包括解决方案]

经过大量实验,问题似乎是这样的:

KeyClope向CORS飞行前(选项)请求发回401响应。无论您在飞行前添加了什么标题,错误状态代码(即,除了200系列响应之外的任何代码)都将被视为CORS故障。

解决方案:

1)扩展Keycloak-valve的CORS支持,用204来响应选项,可能通过添加如下所示的代码。如果你想看看它,弄清楚它迷宫般的架构,并提交一份公关,那就太好了。否则,

2) 禁用KeyClope的CORS支持,并在配置之前添加一个CORS阀。

我通过设置“enable_cors:false”(或简单地删除该条目)在仅承载服务器中禁用了 CORS 支持。然后,我创建了一个小的 CORS 支持阀来发送访问控制允许标头。由于这是一个持有者令牌系统,因此允许使用“*”是相当安全的。(此外,如果您允许源“*”,现代浏览器将不会发送凭据。

整个CORS支持阀大致如下:

public void invoke(Request rqst, Response rsp) throws ...
{
    HttpServletResponse response = rsp.getResponse();
    HttpServletRequest request = rqst.getRequest();

    if (null != request.getHeader("origin")) {
        response.setHeader("Access-Control-Allow-Origin", "*");

        String method = request.getMethod();
        if (method.equalsIgnoreCase("options")) { // preflight?
            rsp.reset();
            response.setHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS");
            response.setHeader("Access-Control-Max-Age", "10");
            response.setHeader("Access-Control-Allow-Headers", "Origin,Accept,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Your-Header-Here");
            rsp.setStatus(204);
            return;
        }
    }

    getNext().invoke(rqst, rsp);
}

但是您可能希望为您的应用程序编写一个功能更全的阀门。

添加此项后,CORS预检返回204,然后请求者正确接收401/403响应。

分析

Keycloak valve仅在向Keycloak auth服务器登记后发送CORS报头。这意味着承载令牌服务器端应用程序的任何网络、配置或令牌验证失败都会导致没有任何访问控制允许标头的错误响应,因此没有任何错误详细信息可用。

Keycloak tomcat阀确实为几乎任何故障提供详细的故障信息。对于401错误,它位于WWW-Authenticate响应标头中,与大多数标头一样,在CORS失败的情况下禁止使用该标头。但是,它会将此401错误返回给OPTIONS请求,即CORS预检,这会将其隐藏在客户端代码中。由于任何配置错误(auth-server-url有错误的端口,或领域拼写错误)也会触发CORS失败,因此您的应用程序永远不会看到标头。

该错误在某些浏览器的网络调试窗格中可见,但在Javascript中不可见。

 类似资料:
  • 我已经尝试使用vb使用eventbrite api有一段时间了。net,我使用来使用api,但是它只返回当我使用postman调用具有相同头的相同方法时,它返回具有

  • 问题内容: 在flask中,我使用以下代码段启用HTTP身份验证: 现在,根据我过去使用Flask的经验,如果某人的凭据不正确,我想让他们知道我可以打电话给: 这为你提供了基本的apache 401响应。有谁知道我如何使用上面的代码片段实现这一目标? 谢谢 问题答案: 在Flask中,自定义错误响应确实非常容易。创建一个仅将参数作为HTTP错误状态代码的函数,使其返回flask.Response实

  • HTTP 401 Unauthorized客户端错误状态响应代码指示该请求尚未应用,因为它缺少目标资源的有效认证凭证。 此状态与包含有关如何正确授权信息的WWW-Authenticate标头一起发送。 这种状态与此类似403,但在这种情况下,身份验证是可能的。 状态 401 Unauthorized 响应示例 HTTP/1.1 401 Unauthorized Date: Wed, 21 Oct

  • 我是Spring boot和Spring Security的新手,出现以下错误: “错误401未经授权(c.e.l.security.jwt.AuthEntryPointJwt:未经授权的错误:访问此资源需要完全身份验证)” 我试过这个认证 我的问题是,当我成功登录时,我想请求获取用户列表。我发送的请求是一个安全GET请求,它是http://localhost:8084/loginsystem/a

  • 我正试图使用谷歌api购物(商家),我被这个问题卡住了。 我对php不是很熟悉,但对我来说,代码似乎很好,我想做的就是尝试从我的商店取货。我已经按照google建议的步骤在开发者控制台中设置了客户端id和客户端机密,但是在登录之后我仍然得到了错误。 下面是我使用的代码: 我得到以下错误: 0数组致命错误:未捕获异常“Google_Service_exception”,消息“{”error:{”er

  • 我开发了android应用程序,可以将照片备份到flickr。 我有下一个问题几次:有时我收到401响应(响应代码: 401,响应消息:未授权,错误:oauth_problem=token_rejected),而不是访问令牌的响应,在将请求令牌交换为访问令牌期间。 这种问题主要发生在我的互联网连接不好的时候(当我起诉3g互联网时)。 以下是显示此行为的日志: 之后,我在浏览器中为用户打开下一个网址