如何在keycloak中设置CORS配置以允许ajax请求?

时间:2019-01-01 18:00:32

标签: angular cors keycloak

我正在尝试将keycloak用作身份验证服务器。 我尝试使用ajax请求获取令牌。由于CORS,它的卷曲效果很好,但在角度上效果不佳。 我已将客户端的“直接访问授予启用”设置为true,并在Web Origin中添加了*。

fetch("http://localhost:8080/auth/realms/master/protocol/openid-connect/token", {
  body: "grant_type=password&client_id=admin-cli&username=adrien&password=adrien&undefined=",
  headers: {
    Accept: "application/json, text/plain, */*,application/x-www-form-urlencoded",
    "Access-Control-Allow-Headers": "Origin, Content-Type, Authorization, Content-Length, X-Requested-With",
    "Access-Control-Allow-Methods": "GET,PUT,POST,DELETE,OPTIONS",
    "Access-Control-Allow-Origin": "*",
    "Cache-Control": "no-cache",
    "Content-Type": "application/x-www-form-urlencoded",
    Dnt: "1",
    "Postman-Token": "cfd33776-882d-4850-b2e7-d66629da3826"
  },
  method: "POST"
})

你知道我在想什么吗?

谢谢。

1 个答案:

答案 0 :(得分:3)

我认为您正在尝试以错误的方式使用它。有用于角度的插件,我认为您应该使用它。所以这里是音符。安装插件:

npm i keycloak-angular

然后初始化密钥解密:

import {KeycloakService} from 'keycloak-angular';

export function initializer(keycloak: KeycloakService): () => Promise<any> {
  return (): Promise<any> => {
    return new Promise(async (resolve, reject) => {
      try {
        await keycloak.init({
          config: {
            url: 'http://localhost:8080/auth',
            realm: 'MySecureRealm',
            clientId: 'myAngularApplication'
          },
          initOptions: {
            onLoad: 'login-required',
            checkLoginIframe: false,
            responseMode: 'fragment',
            flow: 'standard'
          }
        });
        resolve();
      } catch (error) {
        reject(error);
      }
    });
  };
}

,然后在app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import {APP_INITIALIZER, NgModule} from '@angular/core';


import { AppComponent } from './app.component';
import {KeycloakService} from 'keycloak-angular';
import {initializer} from '../environments/environment';
import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http';
import {TokenInterceptor} from './token-interceptor';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule
  ],
  providers: [
    KeycloakService,
    {
      provide: APP_INITIALIZER,
      useFactory: initializer,
      multi: true,
      deps: [KeycloakService]
    },
    {
      provide: HTTP_INTERCEPTORS,
      useClass: TokenInterceptor,
      multi: true
    },
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

您还将需要此TokenInterceptor:

import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/observable/fromPromise';

import { KeycloakService, KeycloakAuthGuard, KeycloakAngularModule } from 'keycloak-angular';
import {HttpHeaders} from '@angular/common/http/src/headers';

@Injectable()
export class TokenInterceptor implements HttpInterceptor {

  constructor(protected keycloak: KeycloakService) {}

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return Observable
      .fromPromise(this.keycloak.getToken())
      .mergeMap(
      token => {

        console.log('adding heder to request');
        console.log(token);

        const headers: HttpHeaders = req.headers;
        const hedersWithAuthorization: HttpHeaders = headers.append('Authorization', 'bearer ' + token);
        const requestWithAuthorizationHeader = req.clone({ headers: hedersWithAuthorization });
        return next.handle(requestWithAuthorizationHeader);
      }
    );
  }
}

那应该做到。当您输入应用程序但尚未登录时,您将被重定向到keycloak登录屏幕,然后返回到您的应用程序。并向所有传出请求添加身份验证标头。让我知道您是否有麻烦,我对这项技术非常了解。