Как устранить 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??