Адаптер Spring Boot Keycloak с интерфейсом Angular - PullRequest
0 голосов
/ 06 августа 2020

У меня есть интерфейс Angular с сервером Spring Boot, который аутентифицируется через сервер Keycloak. Я не могу пройти аутентификацию с помощью PKCE непосредственно из внешнего интерфейса, потому что Keycloak компании не поддерживает PKCE.

Существует два способа использования внешнего интерфейса:

  1. Объединен как ресурс stati c в приложении Spring Boot на localhost:8080.
  2. В качестве автономного внешнего интерфейса, например, localhost:4200 и внутреннего интерфейса localhost:8080.

Если я свяжу приложение Angular в бэкэнд Spring Boot как ресурс stati c, все будет работать нормально.

  • Angular отправляет http.get бэкэнду (localhost:8080/contextRoot/api/login)

  • Мой OncePerRequestFilter пытается получить Authentication

    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    
  • Сначала Authentication недоступен, поэтому я получаю перенаправление 302 на свой Angular интерфейс. По сути, это моя первая маленькая проблема. Я действительно не хочу перенаправлять XHR на сервер Keycloak, но вместо этого перенаправляю мой браузер на Keycloak UI. Чтобы обойти это, я ловлю проблему CORS (которая сопровождается отправкой XHR на Keycloak, потому что она не включена) в коде внешнего интерфейса и перенаправляю приложение на URL-адрес входа:

    window.location.href = this.loginURL;
    
  • URL-адрес входа localhost:8080/contextRoot/api/login, и теперь серверная часть правильно перенаправляет меня на пользовательский интерфейс Keycloak.

  • После входа я меня перенаправляют на серверную часть, которая показывает мне интерфейс. Он начинается снова, вызывая http.get логин

  • Теперь фильтр имеет Authentication, KeycloakSecurityContext и устанавливает токен носителя в заголовок ответа. Вместо кода ответа 302 я получаю 200 с токеном Bearer в заголовке запроса Authorization.

    KeycloakSecurityContext context = (KeycloakSecurityContext) request
              .getAttribute(KeycloakSecurityContext.class.getName());
    response.setHeader("Authorization", "Bearer " + context.getTokenString());
    
  • Я получаю ответ на интерфейс и может получить go с помощью токена.

Это ожидается и действительно работает.

Теперь для разработки я запускаю свой Angular интерфейс с ng serve на localhost:4200. Поведение немного отличается, и я не знаю, как это обойти.

Когда я запрашиваю данные для входа из localhost:4200, процесс остается таким же.

  • Я также go с window.location.href = this.loginURL; до localhost:8080/contextRoot/api/login. Переадресуйтесь в пользовательский интерфейс Keycloak и войдите в систему с моими учетными данными.
  • Интерфейс снова начинает вызывать логин.
  • Но теперь Authentication и KeycloakSecurityContext всегда нулевые. Таким образом, я не верну ожидаемые 200 с токеном Bearer. Вместо этого я снова перенаправляюсь на свой URL-адрес входа, что приводит к перенаправлению на пользовательский интерфейс Keycloak. На этот раз сервер Keycloak знает меня, и я напрямую возвращаюсь к бэкэнду, который снова отправляет меня во фронтенд. Это бесконечное l oop, потому что Authentication и KeycloakSecurityContext недоступны.

Привязаны ли Authentication и KeycloakSecurityContext в моем варианте использования к localhost:8080? Как мне заставить это работать?

Заранее спасибо.

...