Настройте Spring Security 5 Oauth 2 для использования параметра uri access_token

Я создаю приложение на основе этого примера -

Фон -

https://github.com/spring-projects/spring-security/tree/master/samples/boot/oauth2resourceserver-webflux

Он отлично работает, если токен OAuth2 находится в заголовке.

Проблема -

Однако я хотел бы изменить его, чтобы использовать в URL-адресе токен OAuth 2. Я пытаюсь создать сервер ресурсов OAuth2.

Анализ-

Кажется, Spring Security поддерживает получение токена из параметра access_token -

https://github.com/spring-projects/spring-security/blob/e3eaa99ad06769cf44ad3e1249f6398077b90834/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oaverource2/serverbutton ServerBearerTokenAuthenticationConverter.java # L57

Однако, по-видимому, по умолчанию он отключен -

https://github.com/spring-projects/spring-security/blob/master/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/server/ ServerBearerTokenAuthenticationConverter.java # L48

Теперь этот класс недоступен за пределами иерархии пружин, которая создается здесь напрямую -

https://github.com/spring-projects/spring-security/blob/master/config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java#L955

Вопрос?

Есть ли в моем коде для этого allowUriQueryParameter значение true?

Обновлять

Я создаю сервер ресурсов OAuth2. К сожалению, OAuth2ResourceServerSpec не позволяет установить authenticationConverter.

2
0
2 048
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Вы можете проверить официальную документацию для Весенняя безопасность

Вы можете создать new ServerBearerTokenAuthenticationConverter(), установить allowUriQueryParameter как регистр в ServerHttpSecurity.

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http
        // ...
        .oauth2Login()
            .authenticationConverter(converter) // set 
            .authenticationManager(manager)
            .authorizedClientRepository(authorizedClients)
            .clientRegistrationRepository(clientRegistrations);
    return http.build();
}

Я пытаюсь создать сервер ресурсов. К сожалению, OAuth2ResourceServerSpec не позволяет установить authenticationConverter.

Pushkar 27.09.2018 22:47

В принципе, вы не можете. Единственный способ (по крайней мере, в Spring 5 и WebFlux 5.1.3) - написать WebFilter и преобразовать параметр запроса в заголовок.

thepanuto 22.03.2019 17:58

В качестве обходного пути вы можете написать WebFilter для преобразования параметра запроса в заголовок.

Это не дает ответа на вопрос. Как только у вас будет достаточная репутация, вы сможете комментировать любой пост; вместо этого дайте ответ

v8-E 04.10.2018 06:01

Spring MVC имеет множество разумных значений по умолчанию, которых не хватает в WebFlux. Это одна из них.

Я решил эту проблему, настроив WebFilter, который принимает токены в строке запроса и добавляет их в заголовок.

@Override
@NonNull
public Mono<Void> filter(
  @NonNull ServerWebExchange serverWebExchange, @NonNull WebFilterChain 
     webFilterChain) {
  ServerHttpRequest request = serverWebExchange.getRequest();
  return webFilterChain.filter(
    serverWebExchange.mutate().request(sanitizeRequest(request)).build());
}

private ServerHttpRequest sanitizeRequest(ServerHttpRequest request) {
  MultiValueMap<String, String> queryParams = request.getQueryParams();
  ServerHttpRequest.Builder newRequest =
    request
        .mutate()
        .headers(
            headers -> {
              if (headerContainsAuthorizationKey(headers)) {
                String token = getAuthorizationBearer(headers);
                if (token != null) {
                  // "bearer" breaks WebFlux OAuth :)
                  headers.set(HttpHeaders.AUTHORIZATION, token.replace("bearer", "Bearer"));
                  return;
                }
              }
              if (pathContainsAccessToken(queryParams)) {
                headers.set(
                    HttpHeaders.AUTHORIZATION,
                    "Bearer " + queryParams.getFirst("access_token"));
              }
            });

  if (pathContainsAccessToken(queryParams)) {
    newRequest.uri(buildNewUriWithoutToken(request.getURI(), queryParams));
  }
  return newRequest.build();
 }
}

Приятно отметить, что строчная буква «bearer» также нарушает работу WebFlux.

После этого вы можете добавить этот фильтр прямо перед вашей спецификацией oauthResourceServer в цепочке безопасности:

@Bean
public SecurityWebFilterChain springSecurityFilterChain(
  ServerHttpSecurity http,
  TokenStore tokenStore,
  AuthorizationHeaderFilter authorizationHeaderFilter) {
    http.csrf()
      .disable()
      .authorizeExchange()
      .anyExchange()
      .authenticated()
      .and()
      .addFilterAt(authorizationHeaderFilter, SecurityWebFiltersOrder.FIRST)
      .oauth2ResourceServer()
      .jwt() // ...  etc
  return http.build();
}
Ответ принят как подходящий

Теперь с Spring Security 5.1.5 мы можем это сделать -

ServerBearerTokenAuthenticationConverter 
authenticationConverter = new ServerBearerTokenAuthenticationConverter();
authenticationConverter.setAllowUriQueryParameter(true);

http.oauth2ResourceServer().bearerTokenConverter(authenticationConverter).jwt();

Я использую Spring Security 5.3.3, и последняя строка этого фрагмента показывает красный цвет для bearerTokenConverter в oauth2ResourceServer, поскольку у него нет такого члена. Вы знаете, что я мог сделать? Спасибо.

Cécile Fecherolle 14.10.2020 10:12

Ответ Пушкаря не сработал для меня, но помог мне найти решение, следующий код помог:

DefaultBearerTokenResolver resolver = new DefaultBearerTokenResolver();
resolver.setAllowUriQueryParameter(true);

http.authorizeRequests()
        .anyRequest().authenticated()
        .and().oauth2ResourceServer().bearerTokenResolver(resolver)
        .jwt();

Спасибо.

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