Consistent .server package for ServerWebExchange OAuth2
Fixes: gh-5663
This commit is contained in:
parent
cbd28cfd1e
commit
5ddb25fff8
|
@ -53,8 +53,8 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio
|
||||||
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
||||||
import org.springframework.security.oauth2.client.userinfo.DefaultReactiveOAuth2UserService;
|
import org.springframework.security.oauth2.client.userinfo.DefaultReactiveOAuth2UserService;
|
||||||
import org.springframework.security.oauth2.client.userinfo.ReactiveOAuth2UserService;
|
import org.springframework.security.oauth2.client.userinfo.ReactiveOAuth2UserService;
|
||||||
import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectWebFilter;
|
import org.springframework.security.oauth2.client.web.server.OAuth2AuthorizationRequestRedirectWebFilter;
|
||||||
import org.springframework.security.oauth2.client.web.ServerOAuth2LoginAuthenticationTokenConverter;
|
import org.springframework.security.oauth2.client.web.server.ServerOAuth2LoginAuthenticationTokenConverter;
|
||||||
import org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder;
|
import org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder;
|
||||||
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
|
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
|
||||||
import org.springframework.security.oauth2.server.resource.authentication.JwtReactiveAuthenticationManager;
|
import org.springframework.security.oauth2.server.resource.authentication.JwtReactiveAuthenticationManager;
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.security.oauth2.client.web;
|
package org.springframework.security.oauth2.client.web.server;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
|
@ -29,6 +29,7 @@ import org.springframework.security.oauth2.client.ClientAuthorizationRequiredExc
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
||||||
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
||||||
|
import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository;
|
||||||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
||||||
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
|
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
|
||||||
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
||||||
|
@ -89,8 +90,8 @@ public class OAuth2AuthorizationRequestRedirectWebFilter implements WebFilter {
|
||||||
private final ReactiveClientRegistrationRepository clientRegistrationRepository;
|
private final ReactiveClientRegistrationRepository clientRegistrationRepository;
|
||||||
private final ServerRedirectStrategy authorizationRedirectStrategy = new DefaultServerRedirectStrategy();
|
private final ServerRedirectStrategy authorizationRedirectStrategy = new DefaultServerRedirectStrategy();
|
||||||
private final StringKeyGenerator stateGenerator = new Base64StringKeyGenerator(Base64.getUrlEncoder());
|
private final StringKeyGenerator stateGenerator = new Base64StringKeyGenerator(Base64.getUrlEncoder());
|
||||||
private ReactiveAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository =
|
private ServerAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository =
|
||||||
new WebSessionOAuth2ReactiveAuthorizationRequestRepository();
|
new WebSessionOAuth2ServerAuthorizationRequestRepository();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an {@code OAuth2AuthorizationRequestRedirectFilter} using the provided parameters.
|
* Constructs an {@code OAuth2AuthorizationRequestRedirectFilter} using the provided parameters.
|
||||||
|
@ -122,7 +123,8 @@ public class OAuth2AuthorizationRequestRedirectWebFilter implements WebFilter {
|
||||||
*
|
*
|
||||||
* @param authorizationRequestRepository the repository used for storing {@link OAuth2AuthorizationRequest}'s
|
* @param authorizationRequestRepository the repository used for storing {@link OAuth2AuthorizationRequest}'s
|
||||||
*/
|
*/
|
||||||
public final void setAuthorizationRequestRepository(ReactiveAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository) {
|
public final void setAuthorizationRequestRepository(
|
||||||
|
ServerAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository) {
|
||||||
Assert.notNull(authorizationRequestRepository, "authorizationRequestRepository cannot be null");
|
Assert.notNull(authorizationRequestRepository, "authorizationRequestRepository cannot be null");
|
||||||
this.authorizationRequestRepository = authorizationRequestRepository;
|
this.authorizationRequestRepository = authorizationRequestRepository;
|
||||||
}
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2018 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.security.oauth2.client.web.server;
|
||||||
|
|
||||||
|
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponse;
|
||||||
|
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
||||||
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility methods for an OAuth 2.0 Authorization Response.
|
||||||
|
*
|
||||||
|
* @author Joe Grandja
|
||||||
|
* @since 5.1
|
||||||
|
* @see OAuth2AuthorizationResponse
|
||||||
|
*/
|
||||||
|
final class OAuth2AuthorizationResponseUtils {
|
||||||
|
|
||||||
|
private OAuth2AuthorizationResponseUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
static MultiValueMap<String, String> toMultiMap(Map<String, String[]> map) {
|
||||||
|
MultiValueMap<String, String> params = new LinkedMultiValueMap<>(map.size());
|
||||||
|
map.forEach((key, values) -> {
|
||||||
|
if (values.length > 0) {
|
||||||
|
for (String value : values) {
|
||||||
|
params.add(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean isAuthorizationResponse(MultiValueMap<String, String> request) {
|
||||||
|
return isAuthorizationResponseSuccess(request) || isAuthorizationResponseError(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean isAuthorizationResponseSuccess(MultiValueMap<String, String> request) {
|
||||||
|
return StringUtils.hasText(request.getFirst(OAuth2ParameterNames.CODE)) &&
|
||||||
|
StringUtils.hasText(request.getFirst(OAuth2ParameterNames.STATE));
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean isAuthorizationResponseError(MultiValueMap<String, String> request) {
|
||||||
|
return StringUtils.hasText(request.getFirst(OAuth2ParameterNames.ERROR)) &&
|
||||||
|
StringUtils.hasText(request.getFirst(OAuth2ParameterNames.STATE));
|
||||||
|
}
|
||||||
|
|
||||||
|
static OAuth2AuthorizationResponse convert(MultiValueMap<String, String> request, String redirectUri) {
|
||||||
|
String code = request.getFirst(OAuth2ParameterNames.CODE);
|
||||||
|
String errorCode = request.getFirst(OAuth2ParameterNames.ERROR);
|
||||||
|
String state = request.getFirst(OAuth2ParameterNames.STATE);
|
||||||
|
|
||||||
|
if (StringUtils.hasText(code)) {
|
||||||
|
return OAuth2AuthorizationResponse.success(code)
|
||||||
|
.redirectUri(redirectUri)
|
||||||
|
.state(state)
|
||||||
|
.build();
|
||||||
|
} else {
|
||||||
|
String errorDescription = request.getFirst(OAuth2ParameterNames.ERROR_DESCRIPTION);
|
||||||
|
String errorUri = request.getFirst(OAuth2ParameterNames.ERROR_URI);
|
||||||
|
return OAuth2AuthorizationResponse.error(errorCode)
|
||||||
|
.redirectUri(redirectUri)
|
||||||
|
.errorDescription(errorDescription)
|
||||||
|
.errorUri(errorUri)
|
||||||
|
.state(state)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,8 +14,11 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.security.oauth2.client.web;
|
package org.springframework.security.oauth2.client.web.server;
|
||||||
|
|
||||||
|
import org.springframework.security.oauth2.client.web.HttpSessionOAuth2AuthorizationRequestRepository;
|
||||||
|
import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter;
|
||||||
|
import org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter;
|
||||||
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
|
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
|
|
||||||
|
@ -38,7 +41,7 @@ import reactor.core.publisher.Mono;
|
||||||
*
|
*
|
||||||
* @param <T> The type of OAuth 2.0 Authorization Request
|
* @param <T> The type of OAuth 2.0 Authorization Request
|
||||||
*/
|
*/
|
||||||
public interface ReactiveAuthorizationRequestRepository<T extends OAuth2AuthorizationRequest> {
|
public interface ServerAuthorizationRequestRepository<T extends OAuth2AuthorizationRequest> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link OAuth2AuthorizationRequest} associated to the provided {@code HttpServletRequest}
|
* Returns the {@link OAuth2AuthorizationRequest} associated to the provided {@code HttpServletRequest}
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.security.oauth2.client.web;
|
package org.springframework.security.oauth2.client.web.server;
|
||||||
|
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationToken;
|
import org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationToken;
|
||||||
|
@ -47,8 +47,8 @@ public class ServerOAuth2LoginAuthenticationTokenConverter
|
||||||
|
|
||||||
static final String CLIENT_REGISTRATION_NOT_FOUND_ERROR_CODE = "client_registration_not_found";
|
static final String CLIENT_REGISTRATION_NOT_FOUND_ERROR_CODE = "client_registration_not_found";
|
||||||
|
|
||||||
private ReactiveAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository =
|
private ServerAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository =
|
||||||
new WebSessionOAuth2ReactiveAuthorizationRequestRepository();
|
new WebSessionOAuth2ServerAuthorizationRequestRepository();
|
||||||
|
|
||||||
private final ReactiveClientRegistrationRepository clientRegistrationRepository;
|
private final ReactiveClientRegistrationRepository clientRegistrationRepository;
|
||||||
|
|
||||||
|
@ -59,12 +59,12 @@ public class ServerOAuth2LoginAuthenticationTokenConverter
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@link ReactiveAuthorizationRequestRepository} to be used. The default is
|
* Sets the {@link ServerAuthorizationRequestRepository} to be used. The default is
|
||||||
* {@link WebSessionOAuth2ReactiveAuthorizationRequestRepository}.
|
* {@link WebSessionOAuth2ServerAuthorizationRequestRepository}.
|
||||||
* @param authorizationRequestRepository the repository to use.
|
* @param authorizationRequestRepository the repository to use.
|
||||||
*/
|
*/
|
||||||
public void setAuthorizationRequestRepository(
|
public void setAuthorizationRequestRepository(
|
||||||
ReactiveAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository) {
|
ServerAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository) {
|
||||||
Assert.notNull(authorizationRequestRepository, "authorizationRequestRepository cannot be null");
|
Assert.notNull(authorizationRequestRepository, "authorizationRequestRepository cannot be null");
|
||||||
this.authorizationRequestRepository = authorizationRequestRepository;
|
this.authorizationRequestRepository = authorizationRequestRepository;
|
||||||
}
|
}
|
||||||
|
@ -110,6 +110,7 @@ public class ServerOAuth2LoginAuthenticationTokenConverter
|
||||||
.build()
|
.build()
|
||||||
.toUriString();
|
.toUriString();
|
||||||
|
|
||||||
return OAuth2AuthorizationResponseUtils.convert(queryParams, redirectUri);
|
return OAuth2AuthorizationResponseUtils
|
||||||
|
.convert(queryParams, redirectUri);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -14,12 +14,13 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.security.oauth2.client.web;
|
package org.springframework.security.oauth2.client.web.server;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||||
|
import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository;
|
||||||
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
|
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
|
||||||
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
@ -29,7 +30,7 @@ import org.springframework.web.server.WebSession;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of an {@link ReactiveAuthorizationRequestRepository} that stores
|
* An implementation of an {@link ServerAuthorizationRequestRepository} that stores
|
||||||
* {@link OAuth2AuthorizationRequest} in the {@code WebSession}.
|
* {@link OAuth2AuthorizationRequest} in the {@code WebSession}.
|
||||||
*
|
*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
|
@ -37,10 +38,11 @@ import reactor.core.publisher.Mono;
|
||||||
* @see AuthorizationRequestRepository
|
* @see AuthorizationRequestRepository
|
||||||
* @see OAuth2AuthorizationRequest
|
* @see OAuth2AuthorizationRequest
|
||||||
*/
|
*/
|
||||||
public final class WebSessionOAuth2ReactiveAuthorizationRequestRepository implements ReactiveAuthorizationRequestRepository<OAuth2AuthorizationRequest> {
|
public final class WebSessionOAuth2ServerAuthorizationRequestRepository
|
||||||
|
implements ServerAuthorizationRequestRepository<OAuth2AuthorizationRequest> {
|
||||||
|
|
||||||
private static final String DEFAULT_AUTHORIZATION_REQUEST_ATTR_NAME =
|
private static final String DEFAULT_AUTHORIZATION_REQUEST_ATTR_NAME =
|
||||||
WebSessionOAuth2ReactiveAuthorizationRequestRepository.class.getName() + ".AUTHORIZATION_REQUEST";
|
WebSessionOAuth2ServerAuthorizationRequestRepository.class.getName() + ".AUTHORIZATION_REQUEST";
|
||||||
|
|
||||||
private final String sessionAttributeName = DEFAULT_AUTHORIZATION_REQUEST_ATTR_NAME;
|
private final String sessionAttributeName = DEFAULT_AUTHORIZATION_REQUEST_ATTR_NAME;
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.security.oauth2.client.web;
|
package org.springframework.security.oauth2.client.web.server;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -52,7 +52,7 @@ public class OAuth2AuthorizationRequestRedirectWebFilterTests {
|
||||||
private ReactiveClientRegistrationRepository clientRepository;
|
private ReactiveClientRegistrationRepository clientRepository;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private ReactiveAuthorizationRequestRepository<OAuth2AuthorizationRequest> authzRequestRepository;
|
private ServerAuthorizationRequestRepository<OAuth2AuthorizationRequest> authzRequestRepository;
|
||||||
|
|
||||||
private ClientRegistration github = ClientRegistration.withRegistrationId("github")
|
private ClientRegistration github = ClientRegistration.withRegistrationId("github")
|
||||||
.redirectUriTemplate("{baseUrl}/{action}/oauth2/code/{registrationId}")
|
.redirectUriTemplate("{baseUrl}/{action}/oauth2/code/{registrationId}")
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.security.oauth2.client.web;
|
package org.springframework.security.oauth2.client.web.server;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
@ -52,7 +52,7 @@ public class ServerOAuth2LoginAuthenticationTokenConverterTest {
|
||||||
private ReactiveClientRegistrationRepository clientRegistrationRepository;
|
private ReactiveClientRegistrationRepository clientRegistrationRepository;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private ReactiveAuthorizationRequestRepository authorizationRequestRepository;
|
private ServerAuthorizationRequestRepository authorizationRequestRepository;
|
||||||
|
|
||||||
private String clientRegistrationId = "github";
|
private String clientRegistrationId = "github";
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.security.oauth2.client.web;
|
package org.springframework.security.oauth2.client.web.server;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
|
||||||
|
@ -40,10 +40,10 @@ import reactor.test.StepVerifier;
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
* @since 5.1
|
* @since 5.1
|
||||||
*/
|
*/
|
||||||
public class WebSessionOAuth2ReactiveAuthorizationRequestRepositoryTests {
|
public class WebSessionOAuth2ServerAuthorizationRequestRepositoryTests {
|
||||||
|
|
||||||
private WebSessionOAuth2ReactiveAuthorizationRequestRepository repository =
|
private WebSessionOAuth2ServerAuthorizationRequestRepository repository =
|
||||||
new WebSessionOAuth2ReactiveAuthorizationRequestRepository();
|
new WebSessionOAuth2ServerAuthorizationRequestRepository();
|
||||||
|
|
||||||
private OAuth2AuthorizationRequest authorizationRequest = OAuth2AuthorizationRequest.authorizationCode()
|
private OAuth2AuthorizationRequest authorizationRequest = OAuth2AuthorizationRequest.authorizationCode()
|
||||||
.authorizationUri("https://example.com/oauth2/authorize")
|
.authorizationUri("https://example.com/oauth2/authorize")
|
Loading…
Reference in New Issue