401 中的 keycloak CORS header

标签 keycloak

我有两个 keycloack 客户端,

  • 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 响应不会将所需的 CORS header 带到 javascript 客户端!

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

最佳答案

(注意:此行为已在 keycloak tomcat Valve 6.0.1 中重现)

[更新以包含解决方案]

经过多次实验,问题似乎是这样的:

Keycloak 发回对 CORS 预检 (OPTIONS) 请求的 401 响应。无论您向预检添加什么 header ,错误状态代码(即除 200 系列响应之外的任何 header )都将被视为 CORS 失败。

解决办法:

1) 扩展 Keycloak-valve 的 CORS 支持以使用 204 响应 OPTIONS,可能通过添加如下所示的代码。如果您想检查一下,弄清楚它迷宫般的架构,并提交 PR,那就太好了。否则,

2) 禁用 keycloak 的 CORS 支持并在配置中在其前面添加一个 CORS 阀。

我通过设置“enable_cors: false”(或简单地删除该条目)在仅承载服务器中禁用了 CORS 支持。然后我创建了一个小型 CORS 支持阀来发送 Access-Control-Allow- header 。因为这是一个不记名 token 系统,所以允许“*”是相当安全的。 (此外,如果您允许来源“*”,现代浏览器将不会发送凭据。)

整个 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 阀门仅在与 Keycloak 身份验证服务器 checkin 后发送 CORS header 。这意味着不记名 token 服务器端应用程序的任何网络、配置或 token 验证失败都会导致错误响应,而没有任何 Access-Control-Allow header ,因此没有任何错误详细信息可用。

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

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

关于401 中的 keycloak CORS header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47860019/

相关文章:

jboss - Keycloak 自定义验证输出消息

node.js - "500 Error: Cannot exchange code for grant in bearer-only mode"在Keycloak中成功登录浏览器后

spring-boot - Spring Keycloak 适配器权限策略执行器。如何设置

java - 在 keycloak 中跳过 kerberos sso 身份验证

spring - Spring Boot的application.properties中的Keycloak配置

spring-boot - 在Spring Boot中获取Keycloak的AccessToken

oauth-2.0 - Keycloak JAX-RS 和 Postman 授权(Auth URL)

mysql - WildFly jboss-cli.sh 使用 useSSL=false 添加数据源 Mysql

java - 我找不到部署在tomcat中的keycloak web资源

node.js - 从 NodeJS 中的 Keycloak Token 获取信息