Доступ к XMLHttpRequest по адресу "http://localhost:..." из источника "http://localhost:4200" заблокирован политикой CORS

Я устанавливаю безопасную конфигурацию с Keycloak и Kong для углового API.

Я следил за следующим учебником https://www.jerney.io/secure-apis-kong-keycloak-1/, но в конце я получаю следующую ошибку:

Доступ к XMLHttpRequest по адресу "http‍://localhost:8000/ops/warehouses" из источника "http‍://localhost:4200" был заблокирован политикой CORS: Ответ на предварительный запрос не проходит проверку контроля доступа: Перенаправление не выполняется разрешено для предполетного запроса.

У меня есть угловой API, который подключается к бэкэнд-API в машинописи. Поэтому я хочу защитить весь API-интерфейс с помощью Keycloak.

Я использую Kong в качестве шлюза API, а Konga - в качестве интерфейса для администрирования Kong.

Интеграция Keycloak с Kong осуществляется через плагин OIDC https://github.com/nokia/kong-oidc

Моя текущая версия Keycloak - 6.0.1, версия Kong - 1.2.1 и Konga 0.14.3. И я внедряю каждый из этих элементов в контейнеры с помощью Docker.

Мое угловое приложение использует npm install keycloak-js --save, и я следую следующей конфигурации https://medium.com/@blained3/connecting-keycloak-to-angular-d175c92a0dd3


Это конфигурация docker compose:

//docker-compose.yml

version: '3.4'

networks: 
  kong_network:

volumes:
  kong-datastore:
  keycloak-datastore:

services:
  kong-db:
    image: postgres:9.6
    restart: always
    volumes:
      - kong-datastore:/var/lib/postgresql/data
    networks:
      - kong_network
    ports:
      - "15432:5432"
    environment:
      POSTGRES_DB:       kong
      POSTGRES_USER:     kong
      POSTGRES_PASSWORD:
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "kong"]
      interval: 5s
      timeout: 5s
      retries: 5

  kong-migration:
    build: .
    command: "kong migrations bootstrap"
    networks:
      - kong_network
    restart: on-failure
    environment:
      KONG_PG_HOST: kong-db
    links:
      - kong-db
    depends_on:
      - kong-db

  kong:
    build: .
    restart: always
    depends_on:
      - kong-migration
      - kong-db
    healthcheck:
      test: ["CMD", "curl", "-f", "http://kong:8001"]
      interval: 5s
      timeout: 2s
      retries: 15
    networks:
      - kong_network
    ports:
      - "8000:8000" # Listener
      - "8001:8001" # Admin API
      - "8443:8443" # Listener  (SSL)
      - "8444:8444" # Admin API (SSL)
    extra_hosts:
      - "keycloak-host:192.168.18.247"
    environment:
      KONG_DATABASE:         postgres
      KONG_PG_HOST:          kong-db
      KONG_PG_PORT:          5432
      KONG_PG_DATABASE:      kong
      KONG_PROXY_ACCESS_LOG: /dev/stdout
      KONG_ADMIN_ACCESS_LOG: /dev/stdout
      KONG_PROXY_ERROR_LOG:  /dev/stderr
      KONG_ADMIN_ERROR_LOG:  /dev/stderr
      KONG_PROXY_LISTEN:     0.0.0.0:8000, 0.0.0.0:8443 ssl
      KONG_ADMIN_LISTEN:     0.0.0.0:8001, 0.0.0.0:8444 ssl
      KONG_PLUGINS:          oidc

  keycloak-db:
    image: postgres:9.6
    volumes: 
      - keycloak-datastore:/var/lib/postresql/data
    networks:
      - kong_network
    ports:
      - "25432:5432"
    environment:
      POSTGRES_DB:       keycloak
      POSTGRES_USER:     keycloak
      POSTGRES_PASSWORD: password

  keycloak:
    image: jboss/keycloak:4.5.0.Final
    restart: always
    depends_on:
      - keycloak-db
    networks:
      - kong_network
    ports:
      - "8180:8080"
    environment:
      DB_VENDOR:   POSTGRES
      DB_ADDR:     keycloak-db
      DB_PORT:     5432
      DB_DATABASE: keycloak
      DB_USER:     keycloak
      DB_PASSWORD: password
      KEYCLOAK_USER:     admin
      KEYCLOAK_PASSWORD: admin

// Dockerfile

 FROM kong:1.1.2-alpine
 RUN apk update && apk add git unzip curl
 ENV KONG_PLUGINS="bundled, oidc"
 RUN luarocks install kong-oidc

// Конг-конфигурация через Конгу

Konga работает в порту 1337, администратор Kong в 8001 и клиент Kong в 8000

Итак, я сделал создать сервис со следующей конфигурацией:

{
  "host": "192.168.18.247",
  "created_at": 1565303126,
  "connect_timeout": 60000,
  "id": "376ef70a-87af-43ba-92c2-a5d459ccac4f",
  "protocol": "http",
  "name": "ops",
  "read_timeout": 60000,
  "port": 3000,
  "path": "/api",
  "updated_at": 1565303147,
  "retries": 5,
  "write_timeout": 60000,
  "tags": null,
  "extras": {
    "createdUser": null,
    "updatedUser": null,
    "kong_node_id": "1",
    "service_id": "376ef70a-87af-43ba-92c2-a5d459ccac4f",
    "createdAt": "2019-08-08T22:25:26.319Z",
    "updatedAt": "2019-08-08T22:25:47.349Z",
    "id": 1
  }
}

К этому сервису я добавил следующий маршрут:

{
  "updated_at": 1565303167,
  "created_at": 1565303167,
  "strip_path": true,
  "snis": null,
  "hosts": null,
  "name": "ops",
  "methods": null,
  "sources": null,
  "preserve_host": false,
  "regex_priority": 0,
  "service": {
    "host": "192.168.18.247",
    "created_at": 1565303126,
    "connect_timeout": 60000,
    "id": "376ef70a-87af-43ba-92c2-a5d459ccac4f",
    "protocol": "http",
    "name": "ops",
    "read_timeout": 60000,
    "port": 3000,
    "path": "/api",
    "updated_at": 1565303147,
    "retries": 5,
    "write_timeout": 60000,
    "tags": null,
    "extras": {
      "createdUser": null,
      "updatedUser": null,
      "kong_node_id": "1",
      "service_id": "376ef70a-87af-43ba-92c2-a5d459ccac4f",
      "createdAt": "2019-08-08T22:25:26.319Z",
      "updatedAt": "2019-08-08T22:25:47.349Z",
      "id": 1
    }
  },
  "paths": [
    "/ops"
  ],
  "destinations": null,
  "id": "1e0ba28b-da93-44d1-9433-ea2bf03340d6",
  "protocols": [
    "http",
    "https"
  ],
  "tags": null
}

Мой плагин OIDC:

{
  "created_at": 1564164342,
  "config": {
    "response_type": "code",
    "introspection_endpoint": "http://keycloak-host:8180/auth/realms/master/protocol/openid-connect/token/introspect",
    "filters": null,
    "bearer_only": "true",
    "ssl_verify": "no",
    "session_secret": null,
    "introspection_endpoint_auth_method": null,
    "realm": "master",
    "redirect_after_logout_uri": "/",
    "scope": "openid",
    "token_endpoint_auth_method": "client_secret_post",
    "logout_path": "/logout",
    "client_id": "back",
    "client_secret": "b1f34901-becc-4f6a-a586-258fef04569c",
    "discovery": "http://keycloak-host:8180/auth/realms/master/.well-known/openid-configuration",
    "recovery_page_path": null,
    "redirect_uri_path": null
  },
  "id": "bc77d4d7-9fdb-4267-8997-a8187c182ecc",
  "service": null,
  "name": "oidc",
  "protocols": [
    "http",
    "https"
  ],
  "enabled": true,
  "run_on": "first",
  "consumer": null,
  "route": null,
  "tags": null
}


Моя конфигурация в Keycloak следующая:

Я создал двух клиентов, один для внешнего интерфейса, а другой для моего внешнего интерфейса.

//ФРОНТ

{
  "realm": "MyDemo",
  "auth-server-url": "http://localhost:8180/auth",
  "ssl-required": "external",
  "resource": "front",
  "public-client": true,
  "confidential-port": 0
}

// НАЗАД

   {
     "realm": "MyDemo",
     "bearer-only": true,
     "auth-server-url": "http://localhost:8180/auth",
     "ssl-required": "external",
     "resource": "back",
     "credentials": {
     "secret": "20f3bcf1-683d-4e1c-98a6-414877e461db"
      },
     "confidential-port": 0,
     "policy-enforcer": {}
   }

В моем внешнем интерфейсе я настроил свой URL для внутреннего интерфейса:

    export const API = {
      'uri': 'http://localhost:8000/ops/'
    };

И я создал два файла для управления службой keycloak:

//keycloak.service.ts

import { Injectable } from '@angular/core';
declare var Keycloak: any;
@Injectable({
 providedIn: 'root'
})
export class KeycloakService {
 public keycloakAuth: any;
 constructor() { }
 init(): Promise<any> {
 return new Promise((resolve, reject) => {
 const config = {

 'url': 'http://keycloak-host:8180/auth',
 'realm': 'master',
 'clientId': 'front',
 'credentials': {
     'secret': 'd030874e-41bc-4710-b28f-c568e7e66c66'
   },
 };
 this.keycloakAuth = new Keycloak(config);
 this.keycloakAuth.init({ onLoad: 'login-required' })
 .success(() => {
 resolve();
 })
 .error(() => {
 reject();
 });
 });
 }

 getToken(): string {
 return this.keycloakAuth.token;
 }
}

//token.interceptor.ts

import { Injectable } from '@angular/core';
import {
 HttpRequest,
 HttpHandler,
 HttpEvent,
 HttpInterceptor,
 HttpHeaders
} from '@angular/common/http';
import { KeycloakService } from './keycloak.service';
import { Observable } from 'rxjs';

@Injectable()
export class TokenInterceptor implements HttpInterceptor {

 constructor(private kcService: KeycloakService) {}

 intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
 console.log("BIngo!!!!!!!!!");
 const authToken = this.kcService.getToken() || '';
 request = request.clone({
 // setHeaders: {
 // 'Authorization': 'Bearer ' + authToken
 // }
 headers: new HttpHeaders({
 'Content-Type': 'application/json',
 'Authorization': 'Bearer ' + authToken
 })

 });
 console.log(authToken);
 return next.handle(request);
 }
}

0 ответов

Другие вопросы по тегам