Я создаю угловое приложение (чат), которое подключается к Keycloak с angular-oauth2-oidc
и вызывает бэкэнд spring boot WebFlux
как SecurityRessourceServer для получения и отправки сообщений. Когда пользователь входит в приложение, сервис вызывает, чтобы получить некоторые исторические сообщения, а сервис sse вызывает.
С первым GET у меня не было никаких проблем. Маркер-носитель хорошо отправляется в заголовке «Авторизация» и работает нормально. Но для SSE (с классическим источником событий). Маркер не может быть передан как заголовок, но как переменная пути (access_token, как рекомендовано OAuth), но Spring Security не перехватил его и вернул 401.
Чтобы исправить эту проблему, я добавил фильтр, который ловит токен в URI и вставляет его в качестве заголовка. И что удивительно, теперь весенняя загрузка ответила 500 сообщением: «В запросе найдено несколько токенов на предъявителя».
Я попытался изменить имя переменной пути на «tok», и теперь оно работает нормально. Поэтому я понимаю, что Spring хорошо ловит токен в URL с именем access_token, но не очень хорошо. Возможно, это неправильная конфигурация?
Конфигурация безопасности Spring с фильтром:
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.csrf().disable()
.addFilterAt((WebFilter) (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
if(HttpMethod.GET.equals(request.getMethod()) && request.getQueryParams().getFirst("access_token")!=null) {
exchange.getRequest().mutate().headers(httpHeaders ->
httpHeaders.add(
"Authorization",
request.getQueryParams().getFirst("access_token"))
);
}
return chain.filter(exchange);
}, SecurityWebFiltersOrder.FIRST)
.authorizeExchange()
.pathMatchers(HttpMethod.OPTIONS ,"/**").permitAll()
.anyExchange().authenticated()
.and()
.oauth2ResourceServer()
.jwt();
return http.build();
}
И вызов EventSource:
const accessToken = 'Bearer ' + this.oauthService.getAccessToken();
const eventSource = new EventSource(
this.baseUrl + '/messages/subscribe?travelId=cb223637-9290-43e3-a096-2226fab67ee0&access_token=' + accessToken
);
У вас есть идея?
Заранее спасибо.