Переглянути джерело

Polish OAuth2AuthorizedClientService

Fixes gh-4746
Joe Grandja 7 роки тому
батько
коміт
c3d2effc1d

+ 5 - 6
config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurer.java

@@ -20,12 +20,11 @@ import org.springframework.core.ResolvableType;
 import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
 import org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer;
 import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
-import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
 import org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationProvider;
-import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
 import org.springframework.security.oauth2.client.endpoint.AuthorizationRequestUriBuilder;
 import org.springframework.security.oauth2.client.endpoint.NimbusAuthorizationCodeTokenResponseClient;
+import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
 import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest;
 import org.springframework.security.oauth2.client.jwt.JwtDecoderRegistry;
 import org.springframework.security.oauth2.client.jwt.NimbusJwtDecoderRegistry;
@@ -79,7 +78,7 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>> exten
 		return this;
 	}
 
-	public OAuth2LoginConfigurer<B> authorizedClientService(OAuth2AuthorizedClientService<OAuth2AuthorizedClient> authorizedClientService) {
+	public OAuth2LoginConfigurer<B> authorizedClientService(OAuth2AuthorizedClientService authorizedClientService) {
 		Assert.notNull(authorizedClientService, "authorizedClientService cannot be null");
 		this.getBuilder().setSharedObject(OAuth2AuthorizedClientService.class, authorizedClientService);
 		return this;
@@ -318,8 +317,8 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>> exten
 		return this.getBuilder().getSharedObject(ApplicationContext.class).getBean(ClientRegistrationRepository.class);
 	}
 
-	private OAuth2AuthorizedClientService<OAuth2AuthorizedClient> getAuthorizedClientService() {
-		OAuth2AuthorizedClientService<OAuth2AuthorizedClient> authorizedClientService =
+	private OAuth2AuthorizedClientService getAuthorizedClientService() {
+		OAuth2AuthorizedClientService authorizedClientService =
 			this.getBuilder().getSharedObject(OAuth2AuthorizedClientService.class);
 		if (authorizedClientService == null) {
 			authorizedClientService = this.getAuthorizedClientServiceBean();
@@ -328,7 +327,7 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>> exten
 		return authorizedClientService;
 	}
 
-	private OAuth2AuthorizedClientService<OAuth2AuthorizedClient> getAuthorizedClientServiceBean() {
+	private OAuth2AuthorizedClientService getAuthorizedClientServiceBean() {
 		return this.getBuilder().getSharedObject(ApplicationContext.class).getBean(OAuth2AuthorizedClientService.class);
 	}
 

+ 13 - 18
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/InMemoryOAuth2AuthorizedClientService.java

@@ -16,7 +16,6 @@
 package org.springframework.security.oauth2.client;
 
 import org.springframework.security.core.Authentication;
-import org.springframework.security.oauth2.client.oidc.OidcAuthorizedClient;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
 import org.springframework.util.Assert;
@@ -33,14 +32,11 @@ import java.util.concurrent.ConcurrentHashMap;
  * @since 5.0
  * @see OAuth2AuthorizedClientService
  * @see OAuth2AuthorizedClient
- * @see OidcAuthorizedClient
  * @see ClientRegistration
  * @see Authentication
- *
- * @param <T> The type of <i>OAuth 2.0 Authorized Client</i>
  */
-public final class InMemoryOAuth2AuthorizedClientService<T extends OAuth2AuthorizedClient> implements OAuth2AuthorizedClientService<T> {
-	private final Map<String, T> authorizedClients = new ConcurrentHashMap<>();
+public final class InMemoryOAuth2AuthorizedClientService implements OAuth2AuthorizedClientService {
+	private final Map<String, OAuth2AuthorizedClient> authorizedClients = new ConcurrentHashMap<>();
 	private final ClientRegistrationRepository clientRegistrationRepository;
 
 	public InMemoryOAuth2AuthorizedClientService(ClientRegistrationRepository clientRegistrationRepository) {
@@ -49,37 +45,36 @@ public final class InMemoryOAuth2AuthorizedClientService<T extends OAuth2Authori
 	}
 
 	@Override
-	public T loadAuthorizedClient(String clientRegistrationId, Authentication principal) {
+	public <T extends OAuth2AuthorizedClient> T loadAuthorizedClient(String clientRegistrationId, String principalName) {
 		Assert.hasText(clientRegistrationId, "clientRegistrationId cannot be empty");
-		Assert.notNull(principal, "principal cannot be null");
+		Assert.hasText(principalName, "principalName cannot be empty");
 		ClientRegistration registration = this.clientRegistrationRepository.findByRegistrationId(clientRegistrationId);
 		if (registration == null) {
 			return null;
 		}
-		return this.authorizedClients.get(this.getIdentifier(registration, principal));
+		return (T) this.authorizedClients.get(this.getIdentifier(registration, principalName));
 	}
 
 	@Override
-	public void saveAuthorizedClient(T authorizedClient, Authentication principal) {
+	public void saveAuthorizedClient(OAuth2AuthorizedClient authorizedClient, Authentication principal) {
 		Assert.notNull(authorizedClient, "authorizedClient cannot be null");
 		Assert.notNull(principal, "principal cannot be null");
 		this.authorizedClients.put(this.getIdentifier(
-			authorizedClient.getClientRegistration(), principal), authorizedClient);
+			authorizedClient.getClientRegistration(), principal.getName()), authorizedClient);
 	}
 
 	@Override
-	public T removeAuthorizedClient(String clientRegistrationId, Authentication principal) {
+	public void removeAuthorizedClient(String clientRegistrationId, String principalName) {
 		Assert.hasText(clientRegistrationId, "clientRegistrationId cannot be empty");
-		Assert.notNull(principal, "principal cannot be null");
+		Assert.hasText(principalName, "principalName cannot be empty");
 		ClientRegistration registration = this.clientRegistrationRepository.findByRegistrationId(clientRegistrationId);
-		if (registration == null) {
-			return null;
+		if (registration != null) {
+			this.authorizedClients.remove(this.getIdentifier(registration, principalName));
 		}
-		return this.authorizedClients.remove(this.getIdentifier(registration, principal));
 	}
 
-	private String getIdentifier(ClientRegistration registration, Authentication principal) {
-		String identifier = "[" + registration.getRegistrationId() + "][" + principal.getName() + "]";
+	private String getIdentifier(ClientRegistration registration, String principalName) {
+		String identifier = "[" + registration.getRegistrationId() + "][" + principalName + "]";
 		return Base64.getEncoder().encodeToString(identifier.getBytes());
 	}
 }

+ 6 - 8
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/OAuth2AuthorizedClientService.java

@@ -16,8 +16,8 @@
 package org.springframework.security.oauth2.client;
 
 import org.springframework.security.core.Authentication;
-import org.springframework.security.oauth2.client.oidc.OidcAuthorizedClient;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
+import org.springframework.security.oauth2.core.OAuth2AccessToken;
 
 /**
  * Implementations of this interface are responsible for the management
@@ -30,18 +30,16 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio
  * @author Joe Grandja
  * @since 5.0
  * @see OAuth2AuthorizedClient
- * @see OidcAuthorizedClient
  * @see ClientRegistration
  * @see Authentication
- *
- * @param <T> The type of <i>OAuth 2.0 Authorized Client</i>
+ * @see OAuth2AccessToken
  */
-public interface OAuth2AuthorizedClientService<T extends OAuth2AuthorizedClient> {
+public interface OAuth2AuthorizedClientService {
 
-	T loadAuthorizedClient(String clientRegistrationId, Authentication principal);
+	<T extends OAuth2AuthorizedClient> T loadAuthorizedClient(String clientRegistrationId, String principalName);
 
-	void saveAuthorizedClient(T authorizedClient, Authentication principal);
+	void saveAuthorizedClient(OAuth2AuthorizedClient authorizedClient, Authentication principal);
 
-	T removeAuthorizedClient(String clientRegistrationId, Authentication principal);
+	void removeAuthorizedClient(String clientRegistrationId, String principalName);
 
 }

+ 0 - 54
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/OidcAuthorizedClient.java

@@ -1,54 +0,0 @@
-/*
- * Copyright 2002-2017 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.oidc;
-
-import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
-import org.springframework.security.oauth2.client.registration.ClientRegistration;
-import org.springframework.security.oauth2.core.OAuth2AccessToken;
-import org.springframework.security.oauth2.core.oidc.OidcIdToken;
-import org.springframework.util.Assert;
-
-/**
- * A representation of an OpenID Connect 1.0 <i>&quot;Authorized Client&quot;</i>.
- * <p>
- * A client is considered <i>&quot;authorized&quot;</i> when the End-User (Resource Owner)
- * grants authorization to the Client to access its protected resources.
- * <p>
- * This class associates the {@link #getClientRegistration() Client}
- * to the {@link #getAccessToken() Access Token}
- * granted/authorized by the {@link #getPrincipalName() Resource Owner}, along with
- * the {@link #getIdToken() ID Token} which contains Claims about the authentication of the End-User.
- *
- * @author Joe Grandja
- * @since 5.0
- * @see OAuth2AuthorizedClient
- * @see OidcIdToken
- */
-public class OidcAuthorizedClient extends OAuth2AuthorizedClient {
-	private final OidcIdToken idToken;
-
-	public OidcAuthorizedClient(ClientRegistration clientRegistration, String principalName,
-								OAuth2AccessToken accessToken, OidcIdToken idToken) {
-
-		super(clientRegistration, principalName, accessToken);
-		Assert.notNull(idToken, "idToken cannot be null");
-		this.idToken = idToken;
-	}
-
-	public OidcIdToken getIdToken() {
-		return this.idToken;
-	}
-}

+ 3 - 4
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/authentication/OidcAuthorizationCodeAuthenticationProvider.java

@@ -62,7 +62,7 @@ import java.util.List;
  *
  * @author Joe Grandja
  * @since 5.0
- * @see OidcAuthorizationCodeAuthenticationToken
+ * @see OAuth2LoginAuthenticationToken
  * @see OAuth2AccessTokenResponseClient
  * @see OidcUserService
  * @see OidcUser
@@ -158,13 +158,12 @@ public class OidcAuthorizationCodeAuthenticationProvider implements Authenticati
 		Collection<? extends GrantedAuthority> mappedAuthorities =
 			this.authoritiesMapper.mapAuthorities(oidcUser.getAuthorities());
 
-		OidcAuthorizationCodeAuthenticationToken authenticationResult = new OidcAuthorizationCodeAuthenticationToken(
+		OAuth2LoginAuthenticationToken authenticationResult = new OAuth2LoginAuthenticationToken(
 			authorizationCodeAuthentication.getClientRegistration(),
 			authorizationCodeAuthentication.getAuthorizationExchange(),
 			oidcUser,
 			mappedAuthorities,
-			accessToken,
-			idToken);
+			accessToken);
 		authenticationResult.setDetails(authorizationCodeAuthentication.getDetails());
 
 		return authenticationResult;

+ 0 - 81
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/authentication/OidcAuthorizationCodeAuthenticationToken.java

@@ -1,81 +0,0 @@
-/*
- * Copyright 2012-2017 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.oidc.authentication;
-
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationToken;
-import org.springframework.security.oauth2.client.registration.ClientRegistration;
-import org.springframework.security.oauth2.core.OAuth2AccessToken;
-import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationExchange;
-import org.springframework.security.oauth2.core.oidc.OidcIdToken;
-import org.springframework.security.oauth2.core.oidc.user.OidcUser;
-import org.springframework.util.Assert;
-
-import java.util.Collection;
-
-/**
- * An {@link OAuth2LoginAuthenticationToken} for <i>OpenID Connect 1.0 Authentication</i>,
- * which leverages the <i>Authorization Code Flow</i>.
- *
- * @author Joe Grandja
- * @since 5.0
- * @see OAuth2LoginAuthenticationToken
- * @see OidcIdToken
- * @see <a target="_blank" href="http://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth">3.1 Authorization Code Flow</a>
- */
-public class OidcAuthorizationCodeAuthenticationToken extends OAuth2LoginAuthenticationToken {
-	private OidcIdToken idToken;
-
-	/**
-	 * This constructor should be used when the Authentication Request/Response is complete.
-	 *
-	 * @param clientRegistration
-	 * @param authorizationExchange
-	 */
-	public OidcAuthorizationCodeAuthenticationToken(ClientRegistration clientRegistration,
-													OAuth2AuthorizationExchange authorizationExchange) {
-
-		super(clientRegistration, authorizationExchange);
-	}
-
-	/**
-	 * This constructor should be used when the Token Request/Response is complete,
-	 * which indicates that the Authorization Code Flow has fully completed
-	 * and OpenID Connect 1.0 Authentication has been achieved.
-	 *
-	 * @param clientRegistration
-	 * @param authorizationExchange
-	 * @param principal
-	 * @param authorities
-	 * @param accessToken
-	 * @param idToken
-	 */
-	public OidcAuthorizationCodeAuthenticationToken(ClientRegistration clientRegistration,
-													OAuth2AuthorizationExchange authorizationExchange,
-													OidcUser principal,
-													Collection<? extends GrantedAuthority> authorities,
-													OAuth2AccessToken accessToken,
-													OidcIdToken idToken) {
-
-		super(clientRegistration, authorizationExchange, principal, authorities, accessToken);
-		Assert.notNull(idToken, "idToken cannot be null");
-		this.idToken = idToken;
-	}
-
-	public OidcIdToken getIdToken() {
-		return this.idToken;
-	}
-}

+ 4 - 5
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/OAuth2LoginAuthenticationFilter.java

@@ -81,18 +81,18 @@ public class OAuth2LoginAuthenticationFilter extends AbstractAuthenticationProce
 	public static final String DEFAULT_FILTER_PROCESSES_URI = "/login/oauth2/code/*";
 	private static final String AUTHORIZATION_REQUEST_NOT_FOUND_ERROR_CODE = "authorization_request_not_found";
 	private ClientRegistrationRepository clientRegistrationRepository;
-	private OAuth2AuthorizedClientService<OAuth2AuthorizedClient> authorizedClientService;
+	private OAuth2AuthorizedClientService authorizedClientService;
 	private AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository =
 		new HttpSessionOAuth2AuthorizationRequestRepository();
 
 	public OAuth2LoginAuthenticationFilter(ClientRegistrationRepository clientRegistrationRepository,
-											OAuth2AuthorizedClientService<OAuth2AuthorizedClient> authorizedClientService) {
+											OAuth2AuthorizedClientService authorizedClientService) {
 		this(DEFAULT_FILTER_PROCESSES_URI, clientRegistrationRepository, authorizedClientService);
 	}
 
 	public OAuth2LoginAuthenticationFilter(String filterProcessesUrl,
 											ClientRegistrationRepository clientRegistrationRepository,
-											OAuth2AuthorizedClientService<OAuth2AuthorizedClient> authorizedClientService) {
+											OAuth2AuthorizedClientService authorizedClientService) {
 		super(filterProcessesUrl);
 		Assert.notNull(clientRegistrationRepository, "clientRegistrationRepository cannot be null");
 		Assert.notNull(authorizedClientService, "authorizedClientService cannot be null");
@@ -137,8 +137,7 @@ public class OAuth2LoginAuthenticationFilter extends AbstractAuthenticationProce
 			oauth2Authentication.getName(),
 			authenticationResult.getAccessToken());
 
-		this.authorizedClientService.saveAuthorizedClient(
-			authorizedClient, oauth2Authentication);
+		this.authorizedClientService.saveAuthorizedClient(authorizedClient, oauth2Authentication);
 
 		return oauth2Authentication;
 	}

+ 2 - 3
samples/boot/oauth2login/src/integration-test/java/org/springframework/security/samples/OAuth2LoginApplicationTests.java

@@ -38,7 +38,6 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.oauth2.client.InMemoryOAuth2AuthorizedClientService;
-import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
 import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
 import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest;
@@ -397,8 +396,8 @@ public class OAuth2LoginApplicationTests {
 		private ClientRegistrationRepository clientRegistrationRepository;
 
 		@Bean
-		public OAuth2AuthorizedClientService<OAuth2AuthorizedClient> authorizedClientService() {
-			return new InMemoryOAuth2AuthorizedClientService<>(this.clientRegistrationRepository);
+		public OAuth2AuthorizedClientService authorizedClientService() {
+			return new InMemoryOAuth2AuthorizedClientService(this.clientRegistrationRepository);
 		}
 	}
 }

+ 2 - 3
samples/boot/oauth2login/src/main/java/sample/config/OAuth2LoginConfig.java

@@ -19,7 +19,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.security.oauth2.client.InMemoryOAuth2AuthorizedClientService;
-import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
 import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
 
@@ -33,7 +32,7 @@ public class OAuth2LoginConfig {
 	private ClientRegistrationRepository clientRegistrationRepository;
 
 	@Bean
-	public OAuth2AuthorizedClientService<OAuth2AuthorizedClient> authorizedClientService() {
-		return new InMemoryOAuth2AuthorizedClientService<>(this.clientRegistrationRepository);
+	public OAuth2AuthorizedClientService authorizedClientService() {
+		return new InMemoryOAuth2AuthorizedClientService(this.clientRegistrationRepository);
 	}
 }

+ 1 - 1
samples/boot/oauth2login/src/main/java/sample/web/MainController.java

@@ -71,7 +71,7 @@ public class MainController {
 
 	private OAuth2AuthorizedClient getAuthorizedClient(OAuth2AuthenticationToken authentication) {
 		return this.authorizedClientService.loadAuthorizedClient(
-			authentication.getAuthorizedClientRegistrationId(), authentication);
+			authentication.getAuthorizedClientRegistrationId(), authentication.getName());
 	}
 
 	private ExchangeFilterFunction oauth2Credentials(OAuth2AuthorizedClient authorizedClient) {