Я создаю приложение на основе этого примера -
Фон -
Он отлично работает, если токен OAuth2 находится в заголовке.
Проблема -
Однако я хотел бы изменить его, чтобы использовать в URL-адресе токен OAuth 2. Я пытаюсь создать сервер ресурсов OAuth2.
Анализ-
Кажется, Spring Security поддерживает получение токена из параметра access_token -
Однако, по-видимому, по умолчанию он отключен -
Теперь этот класс недоступен за пределами иерархии пружин, которая создается здесь напрямую -
Вопрос?
Есть ли в моем коде для этого allowUriQueryParameter значение true?
Обновлять
Я создаю сервер ресурсов OAuth2. К сожалению, OAuth2ResourceServerSpec не позволяет установить authenticationConverter.
Вы можете проверить официальную документацию для Весенняя безопасность
Вы можете создать new ServerBearerTokenAuthenticationConverter(), установить allowUriQueryParameter как регистр в ServerHttpSecurity.
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
// ...
.oauth2Login()
.authenticationConverter(converter) // set
.authenticationManager(manager)
.authorizedClientRepository(authorizedClients)
.clientRegistrationRepository(clientRegistrations);
return http.build();
}
В принципе, вы не можете. Единственный способ (по крайней мере, в Spring 5 и WebFlux 5.1.3) - написать WebFilter и преобразовать параметр запроса в заголовок.
В качестве обходного пути вы можете написать WebFilter для преобразования параметра запроса в заголовок.
Это не дает ответа на вопрос. Как только у вас будет достаточная репутация, вы сможете комментировать любой пост; вместо этого дайте ответ
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, поскольку у него нет такого члена. Вы знаете, что я мог сделать? Спасибо.
Ответ Пушкаря не сработал для меня, но помог мне найти решение, следующий код помог:
DefaultBearerTokenResolver resolver = new DefaultBearerTokenResolver();
resolver.setAllowUriQueryParameter(true);
http.authorizeRequests()
.anyRequest().authenticated()
.and().oauth2ResourceServer().bearerTokenResolver(resolver)
.jwt();
Спасибо.
Я пытаюсь создать сервер ресурсов. К сожалению, OAuth2ResourceServerSpec не позволяет установить authenticationConverter.