Как устранить Keycloak CORS Access-Control-Allow-Origin отсутствует при использовании шлюза API для аутентификации

Я создал небольшой проект gitlab для изучения использования lua-resty-openidc в качестве шлюза для аутентификации запросов API перед отправкой в ​​восходящий поток для доступа к защищенным ресурсам, обслуживаемым внутренним API Flask.

Keycloak используется для аутентификации через шлюз с использованием секретной конфигурации клиента OpenID. Идентификационные данные и токены доступа возвращаются шлюзом в виде файлов cookie HTTP Only. API и клиент находятся в одном административном домене.

В итоге рабочий процесс:

                     Keycloak
                        ^
                        |
                        |
Angular Client <---> Gateway <---> Flask API 

Использование серверного компонента для обработки кода аутентификации осуществляется по причинам, изложенным здесь. Использование файлов cookie HTTP только для хранения токена доступа в локальном хранилище выполняется по причинам, указанным в этой статье и здесь.

Статьи, объясняющие дополнительные причины, по которым я решил не использовать традиционные модели потока аутентификации кода с PKCE или неявным потоком:

Естественно, это зависит от характера приложения и требований безопасности, как описано здесь. Для моих требований использование серверного компонента / рендеринга предпочтительнее, чем традиционные потоки oauth2 для SPA.

Когда шлюз перенаправляет на страницу входа в Keycloak, клиент получает ошибку перекрестного источника CORS, касающуюся отсутствия Access-Control-Allow-Origin, т.е.

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://keycloak.example.com:8080/auth/realms/acme/protocol/openid-connect/auth?response_type=code&client_id=acme&state=da75bec9f6099c3d5be8f0aebd3a6a82&redirect_uri=http%3A%2F%2Fgateway.example.com%2Fapi%2Fredirect_uri&nonce=f0d61a23ff1408929846903c1701741c&scope=openid%20email%20profile. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

После прочтения других сообщений, касающихся этой проблемы, я думаю, что проблема заключается в том, что Keycloak не добавляет заголовок Access-Control-Allow-Origin при получении запроса на перенаправление?? Может быть, это делается только с помощью адаптера Keycloak javascript? Однако в этой архитектуре клиентом для Keycloak является шлюз API, реализованный с использованием lua-resty-openidc.

Исходный код проекта доступен на gitlab. Тем не менее, сводная информация о конфигурации выглядит следующим образом:

Keycloak

  • Корневой URL: http://www.gateway.com/
  • Перенаправить Uri's: / api / redirect_uri
  • Веб-происхождение: *

Сервер шлюза

  • Location /api аутентифицирует /api/* клиентские запросы через Keycloak перед отправкой в ​​обратный поток к Flask API. В этом месте добавляются следующие заголовки CORS:
if ($request_method = OPTIONS) {
        add_header "Access-Control-Allow-Origin" "*";
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD, DELETE";
        add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
        return 200;
      }

if ($request_method = 'GET') {
    add_header "Access-Control-Allow-Origin" "*";
    add_header "Access-Control-Allow-Credentials" "true";
    add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD, DELETE";
    add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
}
  • Детали конфигурации Keycloak, включая клиент, секретный и перенаправляющий URL, хранятся на сервере шлюза.

Использование серверного компонента для обработки кода аутентификации осуществляется по причинам, изложенным здесь. Использование файлов cookie HTTP только для хранения токена доступа в локальном хранилище выполняется по причинам, указанным в этой статье и здесь.

Угловой клиент

Следующий код делает запрос к шлюзу:

let headers = new HttpHeaders({'Content-Type': 'text/html', 'Accept': 'text/html'});

this.http.get("/api/protected", { headers: headers, responseType: 'text', withCredentials: true } )
.subscribe(response => this.response = response);

Я использую следующую конфигурацию прокси для клиента:

{
  "/api/*": {
    "target": "http://gateway.example.com",
    "secure": false,
    "logLevel": "debug",
    "changeOrigin": true
  }
}

У кого-нибудь есть опыт решения этой проблемы или, альтернативно, для обеспечения аутентификации для angular через промежуточное ПО сервера?

Обновление Подход, предложенный в этой статье, использует ASP.NET Core для обеспечения аутентификации и управления сеансами с помощью файлов cookie того же сайта. Он также действует как обратный прокси-сервер для частного бэкэнда.NET API и обслуживает статический контент. Здесь он адаптирован для исследования в среде разработки, используя Flask API в качестве частного бэкэнда и Angular 8.

Теперь нет ошибок CORS Access-Control-Allow-Origin. Может быть, причина этих ошибок была связана с неправильной настройкой среды docker-compose??

0 ответов

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