KeyCloak:请求的资源上不存在 'Access-Control-Allow-Origin' header

KeyCloak : No 'Access-Control-Allow-Origin' header is present on the requested resource

我正在使用 Angular 8.0.3 和 keycloak 6.0.1 进行前端身份验证。

问题

我成功地从我的应用程序进入了 keycloak 登录页面。使用我的登录详细信息登录后,出现错误:
-localhost/:1 对“https://localhost:8080/auth/realms/pwe-realm/protocol/openid-connect/token' from origin 'http://localhost:4200”处的 XMLHttpRequest 的访问已被 CORS 策略阻止:No 'Access-Control-Allow-Origin' header 存在于所请求的资源上.
-Keycloak init failed Keycloak初始化过程中发生错误。

你能帮帮我吗?

我的 Keycloak 配置:

1 境界:pwe-realm
2 位客户:
-pwe-api(对于我的后端)
-pwe-web(我的认证前端)

pwe-web配置:
客户端协议:openid-connect
访问类型:public
有效的重定向 Uris:http//:localhost:4200/(我也试过“*”)

我的代码(我正在使用这个库:keycloak-angular):

environments.ts :

import {KeycloakConfig} from 'keycloak-angular';

const keycloakConfig: KeycloakConfig = {
  url: 'https://localhost:8080/auth',
  realm: 'pwe-realm',
  clientId: 'pwe-web'
};

export const environment = {
  production: false,
  keycloakConfig
};

app.moudle.ts

//imports

const keycloakService = new KeycloakService();

@NgModule({
  declarations: [
    AppComponent,
    ...
  ],
  imports: [
    KeycloakAngularModule,
    BrowserModule,
    AppRoutingModule,
    ...
  ],
  providers: [
    {
      provide: KeycloakService,
      useValue: keycloakService,
    }
  ],
  entryComponents: [AppComponent]
})
export class AppModule implements DoBootstrap {
  async ngDoBootstrap(app) {
    const { keycloakConfig } = environment;

    try {
      await keycloakService.init({ config: keycloakConfig });
      app.bootstrap(AppComponent);
    } catch (error) {
      console.error('Keycloak init failed', error);
    }
  }
}

CORS相关问题需要设置Web Originsweb-origion有什么用,下面是官方文档

网络起源

This option centers around CORS which stands for Cross-Origin Resource Sharing. If browser JavaScript tries to make an AJAX HTTP request to a server whose domain is different from the one the JavaScript code came from, then the request must use CORS. The server must handle CORS requests in a special way, otherwise the browser will not display or allow the request to be processed. This protocol exists to protect against XSS, CSRF and other JavaScript-based attacks.

Keycloak has support for validated CORS requests. The way it works is that the domains listed in the Web Origins setting for the client are embedded within the access token sent to the client application. The client application can then use this information to decide whether or not to allow a CORS request to be invoked on it. This is an extension to the OIDC protocol so only Keycloak client adapters support this feature. See Securing Applications and Services Guide for more information.

To fill in the Web Origins data, enter in a base URL and click the + sign to add. Click the - sign next to URLs you want to remove. Remember that you still have to click the Save button!

因此在您的客户端中设置 'Web Origins'(或仅添加 *)。

我同意,您需要配置 Web Origins,但是:

  • 通配符 * 不适用于经过身份验证的请求,因此请显式配置它们

  • 有些浏览器可能不支持 localhost 的 CORS (),所以不要使用 localhost 进行开发

我在使用 Vue.js 针对本地主机上的服务器进行开发时浪费了半天时间。

您可能需要在您的 Keycloak 服务器上为您的 Keycloak 客户端设置网络来源:

  1. 登录到 Keycloak 管理屏幕,select 领域 pwe-realm,然后是您的客户端 pwe-web。
  2. 滚动到 Web Origin 设置并键入加号。不要点击 (+) 按钮,而是直接输入 + 。这会将您在上面定义的所有有效重定向 URI 添加到 Web 来源 headers。您还需要将 angular 应用程序的 URI 添加到有效重定向 URI 列表中。
  3. 按屏幕底部的保存。

它应该会立即生效。

我同意,您需要配置 Web Origins,但也许,您必须配置 Wildfly 以提供 CORS 支持。

这是示例配置 (standalone.xml) :

<subsystem xmlns="urn:jboss:domain:undertow:12.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="${wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}">
    <buffer-cache name="default"/>
    <server name="default-server">
        <http-listener name="default" socket-binding="http" redirect-socket="https"/>
        <host name="default-host" alias="localhost">
            <location name="/" handler="welcome-content"/>
            <filter-ref name="server-header"/>
            <filter-ref name="x-powered-by-header"/>
            <filter-ref name="Access-Control-Allow-Origin"/>
            <filter-ref name="Access-Control-Allow-Methods"/>
            <filter-ref name="Access-Control-Allow-Headers"/>
            <filter-ref name="Access-Control-Allow-Credentials"/>
            <filter-ref name="Access-Control-Max-Age"/>
        </host>
    </server>
    <servlet-container name="default">
        <jsp-config/>
        <websockets/>
    </servlet-container>
    <handlers>
        <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
    </handlers>
    <filters>
        <response-header name="server-header" header-name="Server" header-value="WildFly"/>
        <response-header name="x-powered-by-header" header-name="X-Powered-By" header-value="Undertow"/>
        <response-header name="Access-Control-Allow-Methods" header-name="Access-Control-Allow-Methods" header-value="GET, POST, OPTIONS, PUT"/>
        <response-header name="Access-Control-Allow-Headers" header-name="Access-Control-Allow-Headers" header-value="accept, authorization, content-type, x-requested-with, Access-Control-Allow-Origin"/>
        <response-header name="Access-Control-Max-Age" header-name="Access-Control-Max-Age" header-value="1"/>
    </filters>
</subsystem>

对某些人来说可能有点晚了。但在我的例子中,问题是 keycloak URL 没有正确地写在我的前面。确保您的提供者或发行者中有下一个结构:http://server_ip:PORT/auth/realms/realm_name