浏览代码

Consistent .server package for ServerWebExchange OAuth2

Fixes: gh-5663
Rob Winch 7 年之前
父节点
当前提交
5ddb25fff8

+ 2 - 2
config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java

@@ -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.userinfo.DefaultReactiveOAuth2UserService;
 import org.springframework.security.oauth2.client.userinfo.ReactiveOAuth2UserService;
-import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectWebFilter;
-import org.springframework.security.oauth2.client.web.ServerOAuth2LoginAuthenticationTokenConverter;
+import org.springframework.security.oauth2.client.web.server.OAuth2AuthorizationRequestRedirectWebFilter;
+import org.springframework.security.oauth2.client.web.server.ServerOAuth2LoginAuthenticationTokenConverter;
 import org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder;
 import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
 import org.springframework.security.oauth2.server.resource.authentication.JwtReactiveAuthenticationManager;

+ 6 - 4
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/OAuth2AuthorizationRequestRedirectWebFilter.java → oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/OAuth2AuthorizationRequestRedirectWebFilter.java

@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * 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.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.ClientRegistrationRepository;
 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.endpoint.OAuth2AuthorizationRequest;
 import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
@@ -89,8 +90,8 @@ public class OAuth2AuthorizationRequestRedirectWebFilter implements WebFilter {
 	private final ReactiveClientRegistrationRepository clientRegistrationRepository;
 	private final ServerRedirectStrategy authorizationRedirectStrategy = new DefaultServerRedirectStrategy();
 	private final StringKeyGenerator stateGenerator = new Base64StringKeyGenerator(Base64.getUrlEncoder());
-	private ReactiveAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository =
-		new WebSessionOAuth2ReactiveAuthorizationRequestRepository();
+	private ServerAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository =
+		new WebSessionOAuth2ServerAuthorizationRequestRepository();
 
 	/**
 	 * 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
 	 */
-	public final void setAuthorizationRequestRepository(ReactiveAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository) {
+	public final void setAuthorizationRequestRepository(
+			ServerAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository) {
 		Assert.notNull(authorizationRequestRepository, "authorizationRequestRepository cannot be null");
 		this.authorizationRequestRepository = authorizationRequestRepository;
 	}

+ 85 - 0
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/OAuth2AuthorizationResponseUtils.java

@@ -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();
+		}
+	}
+}

+ 5 - 2
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/ReactiveAuthorizationRequestRepository.java → oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/ServerAuthorizationRequestRepository.java

@@ -14,8 +14,11 @@
  * 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.web.server.ServerWebExchange;
 
@@ -38,7 +41,7 @@ import reactor.core.publisher.Mono;
  *
  * @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}

+ 8 - 7
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/ServerOAuth2LoginAuthenticationTokenConverter.java → oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/ServerOAuth2LoginAuthenticationTokenConverter.java

@@ -14,7 +14,7 @@
  * 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.oauth2.client.authentication.OAuth2LoginAuthenticationToken;
@@ -47,8 +47,8 @@ public class ServerOAuth2LoginAuthenticationTokenConverter
 
 	static final String CLIENT_REGISTRATION_NOT_FOUND_ERROR_CODE = "client_registration_not_found";
 
-	private ReactiveAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository =
-			new WebSessionOAuth2ReactiveAuthorizationRequestRepository();
+	private ServerAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository =
+			new WebSessionOAuth2ServerAuthorizationRequestRepository();
 
 	private final ReactiveClientRegistrationRepository clientRegistrationRepository;
 
@@ -59,12 +59,12 @@ public class ServerOAuth2LoginAuthenticationTokenConverter
 	}
 
 	/**
-	 * Sets the {@link ReactiveAuthorizationRequestRepository} to be used. The default is
-	 * {@link WebSessionOAuth2ReactiveAuthorizationRequestRepository}.
+	 * Sets the {@link ServerAuthorizationRequestRepository} to be used. The default is
+	 * {@link WebSessionOAuth2ServerAuthorizationRequestRepository}.
 	 * @param authorizationRequestRepository the repository to use.
 	 */
 	public void setAuthorizationRequestRepository(
-			ReactiveAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository) {
+			ServerAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository) {
 		Assert.notNull(authorizationRequestRepository, "authorizationRequestRepository cannot be null");
 		this.authorizationRequestRepository = authorizationRequestRepository;
 	}
@@ -110,6 +110,7 @@ public class ServerOAuth2LoginAuthenticationTokenConverter
 				.build()
 				.toUriString();
 
-		return OAuth2AuthorizationResponseUtils.convert(queryParams, redirectUri);
+		return OAuth2AuthorizationResponseUtils
+				.convert(queryParams, redirectUri);
 	}
 }

+ 6 - 4
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/WebSessionOAuth2ReactiveAuthorizationRequestRepository.java → oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/WebSessionOAuth2ServerAuthorizationRequestRepository.java

@@ -14,12 +14,13 @@
  * 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.Map;
 
 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.OAuth2ParameterNames;
 import org.springframework.util.Assert;
@@ -29,7 +30,7 @@ import org.springframework.web.server.WebSession;
 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}.
  *
  * @author Rob Winch
@@ -37,10 +38,11 @@ import reactor.core.publisher.Mono;
  * @see AuthorizationRequestRepository
  * @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 =
-			WebSessionOAuth2ReactiveAuthorizationRequestRepository.class.getName() +  ".AUTHORIZATION_REQUEST";
+			WebSessionOAuth2ServerAuthorizationRequestRepository.class.getName() +  ".AUTHORIZATION_REQUEST";
 
 	private final String sessionAttributeName = DEFAULT_AUTHORIZATION_REQUEST_ATTR_NAME;
 

+ 2 - 2
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/OAuth2AuthorizationRequestRedirectWebFilterTests.java → oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/server/OAuth2AuthorizationRequestRedirectWebFilterTests.java

@@ -14,7 +14,7 @@
  * 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.Test;
@@ -52,7 +52,7 @@ public class OAuth2AuthorizationRequestRedirectWebFilterTests {
 	private ReactiveClientRegistrationRepository clientRepository;
 
 	@Mock
-	private ReactiveAuthorizationRequestRepository<OAuth2AuthorizationRequest> authzRequestRepository;
+	private ServerAuthorizationRequestRepository<OAuth2AuthorizationRequest> authzRequestRepository;
 
 	private ClientRegistration github = ClientRegistration.withRegistrationId("github")
 			.redirectUriTemplate("{baseUrl}/{action}/oauth2/code/{registrationId}")

+ 2 - 2
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/ServerOAuth2LoginAuthenticationTokenConverterTest.java → oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/server/ServerOAuth2LoginAuthenticationTokenConverterTest.java

@@ -14,7 +14,7 @@
  * 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.assertThatThrownBy;
@@ -52,7 +52,7 @@ public class ServerOAuth2LoginAuthenticationTokenConverterTest {
 	private ReactiveClientRegistrationRepository clientRegistrationRepository;
 
 	@Mock
-	private ReactiveAuthorizationRequestRepository authorizationRequestRepository;
+	private ServerAuthorizationRequestRepository authorizationRequestRepository;
 
 	private String clientRegistrationId = "github";
 

+ 4 - 4
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/WebSessionOAuth2ReactiveAuthorizationRequestRepositoryTests.java → oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/server/WebSessionOAuth2ServerAuthorizationRequestRepositoryTests.java

@@ -14,7 +14,7 @@
  * 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;
 
@@ -40,10 +40,10 @@ import reactor.test.StepVerifier;
  * @author Rob Winch
  * @since 5.1
  */
-public class WebSessionOAuth2ReactiveAuthorizationRequestRepositoryTests {
+public class WebSessionOAuth2ServerAuthorizationRequestRepositoryTests {
 
-	private WebSessionOAuth2ReactiveAuthorizationRequestRepository repository =
-			new WebSessionOAuth2ReactiveAuthorizationRequestRepository();
+	private WebSessionOAuth2ServerAuthorizationRequestRepository repository =
+			new WebSessionOAuth2ServerAuthorizationRequestRepository();
 
 	private OAuth2AuthorizationRequest authorizationRequest = OAuth2AuthorizationRequest.authorizationCode()
 			.authorizationUri("https://example.com/oauth2/authorize")