1
0
mirror of synced 2026-08-05 17:57:15 +00:00

Add ServerAuthenticationConverter interface

- Adding an ServerAuthenticationConverter interface
- Retro-fitting ServerOAuth2LoginAuthenticationTokenConverter,
 ServerBearerTokenAuthentivationConverter, ServerFormLoginAuthenticationConverter,
 and ServerHttpBasicAuthenticationConverter to implement ServerAuthenticationConverter
- Deprecate existing AuthenticationWebFilter.setAuthenticationConverter
and add overloaded one which takes ServerAuthenticationConverter

Fixes gh-5338
This commit is contained in:
Eric Deandrea
2018-08-17 18:53:28 -04:00
committed by Rob Winch
parent 34c8d66017
commit b6afe66d32
11 changed files with 88 additions and 44 deletions
@@ -16,8 +16,6 @@
package org.springframework.security.oauth2.client.web;
import java.util.function.Function;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationToken;
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
@@ -27,6 +25,7 @@ import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationExch
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponse;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.web.server.authentication.ServerAuthenticationConverter;
import org.springframework.util.Assert;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
@@ -34,16 +33,14 @@ import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;
/**
* Converts from a {@link ServerWebExchange} to an {@link OAuth2LoginAuthenticationToken} that can be authenticated. The
* converter does not validate any errors it only performs a conversion.
* @author Rob Winch
* @since 5.1
* @see org.springframework.security.web.server.authentication.AuthenticationWebFilter#setAuthenticationConverter(Function)
* @see org.springframework.security.web.server.authentication.AuthenticationWebFilter#setAuthenticationConverter(ServerAuthenticationConverter)
*/
public class ServerOAuth2LoginAuthenticationTokenConverter implements
Function<ServerWebExchange, Mono<Authentication>> {
public class ServerOAuth2LoginAuthenticationTokenConverter implements ServerAuthenticationConverter {
static final String AUTHORIZATION_REQUEST_NOT_FOUND_ERROR_CODE = "authorization_request_not_found";
@@ -72,7 +69,7 @@ public class ServerOAuth2LoginAuthenticationTokenConverter implements
}
@Override
public Mono<Authentication> apply(ServerWebExchange serverWebExchange) {
public Mono<Authentication> convert(ServerWebExchange serverWebExchange) {
return this.authorizationRequestRepository.removeAuthorizationRequest(serverWebExchange)
.switchIfEmpty(oauth2AuthenticationException(AUTHORIZATION_REQUEST_NOT_FOUND_ERROR_CODE))
.flatMap(authorizationRequest -> authenticationRequest(serverWebExchange, authorizationRequest));
@@ -97,14 +94,14 @@ public class ServerOAuth2LoginAuthenticationTokenConverter implements
})
.switchIfEmpty(oauth2AuthenticationException(CLIENT_REGISTRATION_NOT_FOUND_ERROR_CODE))
.map(clientRegistration -> {
OAuth2AuthorizationResponse authorizationResponse = convert(exchange);
OAuth2AuthorizationResponse authorizationResponse = convertResponse(exchange);
OAuth2LoginAuthenticationToken authenticationRequest = new OAuth2LoginAuthenticationToken(
clientRegistration, new OAuth2AuthorizationExchange(authorizationRequest, authorizationResponse));
return authenticationRequest;
});
}
private static OAuth2AuthorizationResponse convert(ServerWebExchange exchange) {
private static OAuth2AuthorizationResponse convertResponse(ServerWebExchange exchange) {
MultiValueMap<String, String> queryParams = exchange.getRequest()
.getQueryParams();
String redirectUri = UriComponentsBuilder.fromUri(exchange.getRequest().getURI())
@@ -141,6 +141,6 @@ public class ServerOAuth2LoginAuthenticationTokenConverterTest {
private OAuth2LoginAuthenticationToken applyConverter() {
MockServerWebExchange exchange = MockServerWebExchange.from(this.request);
return (OAuth2LoginAuthenticationToken) this.converter.apply(exchange).block();
return (OAuth2LoginAuthenticationToken) this.converter.convert(exchange).block();
}
}
@@ -25,11 +25,11 @@ import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
import org.springframework.security.oauth2.server.resource.BearerTokenError;
import org.springframework.security.oauth2.server.resource.BearerTokenErrorCodes;
import org.springframework.security.web.server.authentication.ServerAuthenticationConverter;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -41,13 +41,12 @@ import java.util.regex.Pattern;
* @since 5.1
* @see <a href="https://tools.ietf.org/html/rfc6750#section-2" target="_blank">RFC 6750 Section 2: Authenticated Requests</a>
*/
public class ServerBearerTokenAuthenticationConverter implements
Function<ServerWebExchange, Mono<Authentication>> {
public class ServerBearerTokenAuthenticationConverter implements ServerAuthenticationConverter {
private static final Pattern authorizationPattern = Pattern.compile("^Bearer (?<token>[a-zA-Z0-9-._~+/]+)=*$");
private boolean allowUriQueryParameter = false;
public Mono<Authentication> apply(ServerWebExchange exchange) {
public Mono<Authentication> convert(ServerWebExchange exchange) {
return Mono.justOrEmpty(this.token(exchange.getRequest()))
.map(BearerTokenAuthenticationToken::new);
}
@@ -129,6 +129,6 @@ public class ServerBearerTokenAuthenticationConverterTests {
private BearerTokenAuthenticationToken convertToToken(MockServerHttpRequest request) {
MockServerWebExchange exchange = MockServerWebExchange.from(request);
return this.converter.apply(exchange).cast(BearerTokenAuthenticationToken.class).block();
return this.converter.convert(exchange).cast(BearerTokenAuthenticationToken.class).block();
}
}