Joe Grandja 5 жил өмнө
parent
commit
78f44c7327

+ 11 - 2
core/src/main/java/org/springframework/security/oauth2/server/authorization/Version.java

@@ -19,10 +19,19 @@ package org.springframework.security.oauth2.server.authorization;
  * Internal class used for serialization across Spring Security Authorization Server classes.
  *
  * @author Anoop Garlapati
+ * @since 0.0.1
  */
-public class Version {
+public final class Version {
+	private static final int MAJOR = 0;
+	private static final int MINOR = 0;
+	private static final int PATCH = 1;
+
 	/**
 	 * Global Serialization value for Spring Security Authorization Server classes.
 	 */
-	public static final long SERIAL_VERSION_UID = "0.0.1".hashCode();
+	public static final long SERIAL_VERSION_UID = getVersion().hashCode();
+
+	public static String getVersion() {
+		return MAJOR + "." + MINOR + "." + PATCH;
+	}
 }

+ 3 - 2
core/src/main/java/org/springframework/security/oauth2/server/authorization/client/InMemoryRegisteredClientRepository.java

@@ -28,6 +28,7 @@ import java.util.concurrent.ConcurrentHashMap;
  * @author Anoop Garlapati
  * @see RegisteredClientRepository
  * @see RegisteredClient
+ * @since 0.0.1
  */
 public final class InMemoryRegisteredClientRepository implements RegisteredClientRepository {
 	private final Map<String, RegisteredClient> idRegistrationMap;
@@ -66,8 +67,8 @@ public final class InMemoryRegisteredClientRepository implements RegisteredClien
 			idRegistrationMapResult.put(id, registration);
 			clientIdRegistrationMapResult.put(clientId, registration);
 		}
-		idRegistrationMap = idRegistrationMapResult;
-		clientIdRegistrationMap = clientIdRegistrationMapResult;
+		this.idRegistrationMap = idRegistrationMapResult;
+		this.clientIdRegistrationMap = clientIdRegistrationMapResult;
 	}
 
 	@Override

+ 45 - 40
core/src/main/java/org/springframework/security/oauth2/server/authorization/client/RegisteredClient.java

@@ -25,7 +25,6 @@ import java.io.Serializable;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.Set;
 import java.util.function.Consumer;
@@ -36,17 +35,17 @@ import java.util.function.Consumer;
  * @author Joe Grandja
  * @author Anoop Garlapati
  * @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-2">Section 2 Client Registration</a>
+ * @since 0.0.1
  */
 public class RegisteredClient implements Serializable {
 	private static final long serialVersionUID = Version.SERIAL_VERSION_UID;
 	private String id;
 	private String clientId;
 	private String clientSecret;
-	private Set<ClientAuthenticationMethod> clientAuthenticationMethods =
-			Collections.singleton(ClientAuthenticationMethod.BASIC);
-	private Set<AuthorizationGrantType> authorizationGrantTypes = Collections.emptySet();
-	private Set<String> redirectUris = Collections.emptySet();
-	private Set<String> scopes = Collections.emptySet();
+	private Set<ClientAuthenticationMethod> clientAuthenticationMethods;
+	private Set<AuthorizationGrantType> authorizationGrantTypes;
+	private Set<String> redirectUris;
+	private Set<String> scopes;
 
 	protected RegisteredClient() {
 	}
@@ -157,8 +156,7 @@ public class RegisteredClient implements Serializable {
 		private String id;
 		private String clientId;
 		private String clientSecret;
-		private Set<ClientAuthenticationMethod> clientAuthenticationMethods =
-				new LinkedHashSet<>(Collections.singletonList(ClientAuthenticationMethod.BASIC));
+		private Set<ClientAuthenticationMethod> clientAuthenticationMethods = new LinkedHashSet<>();
 		private Set<AuthorizationGrantType> authorizationGrantTypes = new LinkedHashSet<>();
 		private Set<String> redirectUris = new LinkedHashSet<>();
 		private Set<String> scopes = new LinkedHashSet<>();
@@ -171,13 +169,18 @@ public class RegisteredClient implements Serializable {
 			this.id = registeredClient.id;
 			this.clientId = registeredClient.clientId;
 			this.clientSecret = registeredClient.clientSecret;
-			this.clientAuthenticationMethods = registeredClient.clientAuthenticationMethods == null ? null :
-					new HashSet<>(registeredClient.clientAuthenticationMethods);
-			this.authorizationGrantTypes = registeredClient.authorizationGrantTypes == null ? null :
-					new HashSet<>(registeredClient.authorizationGrantTypes);
-			this.redirectUris = registeredClient.redirectUris == null ? null :
-					new HashSet<>(registeredClient.redirectUris);
-			this.scopes = registeredClient.scopes == null ? null : new HashSet<>(registeredClient.scopes);
+			if (!CollectionUtils.isEmpty(registeredClient.clientAuthenticationMethods)) {
+				this.clientAuthenticationMethods.addAll(registeredClient.clientAuthenticationMethods);
+			}
+			if (!CollectionUtils.isEmpty(registeredClient.authorizationGrantTypes)) {
+				this.authorizationGrantTypes.addAll(registeredClient.authorizationGrantTypes);
+			}
+			if (!CollectionUtils.isEmpty(registeredClient.redirectUris)) {
+				this.redirectUris.addAll(registeredClient.redirectUris);
+			}
+			if (!CollectionUtils.isEmpty(registeredClient.scopes)) {
+				this.scopes.addAll(registeredClient.scopes);
+			}
 		}
 
 		/**
@@ -214,8 +217,8 @@ public class RegisteredClient implements Serializable {
 		}
 
 		/**
-		 * Adds the {@link ClientAuthenticationMethod authentication method} to the set of
-		 * client authentication methods used when authenticating the client with the authorization server.
+		 * Adds an {@link ClientAuthenticationMethod authentication method}
+		 * the client may use when authenticating with the authorization server.
 		 *
 		 * @param clientAuthenticationMethod the authentication method
 		 * @return the {@link Builder}
@@ -226,10 +229,10 @@ public class RegisteredClient implements Serializable {
 		}
 
 		/**
-		 * Sets the {@link ClientAuthenticationMethod authentication method(s)} used
-		 * when authenticating the client with the authorization server.
+		 * A {@code Consumer} of the {@link ClientAuthenticationMethod authentication method(s)}
+		 * allowing the ability to add, replace, or remove.
 		 *
-		 * @param clientAuthenticationMethodsConsumer the authentication method(s) {@link Consumer}
+		 * @param clientAuthenticationMethodsConsumer a {@code Consumer} of the authentication method(s)
 		 * @return the {@link Builder}
 		 */
 		public Builder clientAuthenticationMethods(
@@ -239,8 +242,7 @@ public class RegisteredClient implements Serializable {
 		}
 
 		/**
-		 * Adds the {@link AuthorizationGrantType authorization grant type} to
-		 * the set of authorization grant types that the client may use.
+		 * Adds an {@link AuthorizationGrantType authorization grant type} the client may use.
 		 *
 		 * @param authorizationGrantType the authorization grant type
 		 * @return the {@link Builder}
@@ -251,9 +253,10 @@ public class RegisteredClient implements Serializable {
 		}
 
 		/**
-		 * Sets the {@link AuthorizationGrantType authorization grant type(s)} that the client may use.
+		 * A {@code Consumer} of the {@link AuthorizationGrantType authorization grant type(s)}
+		 * allowing the ability to add, replace, or remove.
 		 *
-		 * @param authorizationGrantTypesConsumer the authorization grant type(s) {@link Consumer}
+		 * @param authorizationGrantTypesConsumer a {@code Consumer} of the authorization grant type(s)
 		 * @return the {@link Builder}
 		 */
 		public Builder authorizationGrantTypes(Consumer<Set<AuthorizationGrantType>> authorizationGrantTypesConsumer) {
@@ -262,9 +265,9 @@ public class RegisteredClient implements Serializable {
 		}
 
 		/**
-		 * Adds the redirect URI to the set of redirect URIs that the client may use in redirect-based flows.
+		 * Adds a redirect URI the client may use in a redirect-based flow.
 		 *
-		 * @param redirectUri the redirect URI to add
+		 * @param redirectUri the redirect URI
 		 * @return the {@link Builder}
 		 */
 		public Builder redirectUri(String redirectUri) {
@@ -273,9 +276,10 @@ public class RegisteredClient implements Serializable {
 		}
 
 		/**
-		 * Sets the redirect URI(s) that the client may use in redirect-based flows.
+		 * A {@code Consumer} of the redirect URI(s)
+		 * allowing the ability to add, replace, or remove.
 		 *
-		 * @param redirectUrisConsumer the redirect URI(s) {@link Consumer}
+		 * @param redirectUrisConsumer a {@link Consumer} of the redirect URI(s)
 		 * @return the {@link Builder}
 		 */
 		public Builder redirectUris(Consumer<Set<String>> redirectUrisConsumer) {
@@ -284,9 +288,9 @@ public class RegisteredClient implements Serializable {
 		}
 
 		/**
-		 * Adds the scope to the set of scopes used by the client.
+		 * Adds a scope the client may use.
 		 *
-		 * @param scope the scope to add
+		 * @param scope the scope
 		 * @return the {@link Builder}
 		 */
 		public Builder scope(String scope) {
@@ -295,9 +299,10 @@ public class RegisteredClient implements Serializable {
 		}
 
 		/**
-		 * Sets the scope(s) used by the client.
+		 * A {@code Consumer} of the scope(s)
+		 * allowing the ability to add, replace, or remove.
 		 *
-		 * @param scopesConsumer the scope(s) {@link Consumer}
+		 * @param scopesConsumer a {@link Consumer} of the scope(s)
 		 * @return the {@link Builder}
 		 */
 		public Builder scopes(Consumer<Set<String>> scopesConsumer) {
@@ -311,17 +316,18 @@ public class RegisteredClient implements Serializable {
 		 * @return a {@link RegisteredClient}
 		 */
 		public RegisteredClient build() {
-			Assert.notEmpty(this.clientAuthenticationMethods, "clientAuthenticationMethods cannot be empty");
+			Assert.hasText(this.clientId, "clientId cannot be empty");
 			Assert.notEmpty(this.authorizationGrantTypes, "authorizationGrantTypes cannot be empty");
-			if (authorizationGrantTypes.contains(AuthorizationGrantType.AUTHORIZATION_CODE)) {
-				Assert.hasText(this.id, "id cannot be empty");
-				Assert.hasText(this.clientId, "clientId cannot be empty");
+			if (this.authorizationGrantTypes.contains(AuthorizationGrantType.AUTHORIZATION_CODE)) {
 				Assert.hasText(this.clientSecret, "clientSecret cannot be empty");
 				Assert.notEmpty(this.redirectUris, "redirectUris cannot be empty");
 			}
-			this.validateScopes();
-			this.validateRedirectUris();
-			return this.create();
+			if (CollectionUtils.isEmpty(this.clientAuthenticationMethods)) {
+				this.clientAuthenticationMethods.add(ClientAuthenticationMethod.BASIC);
+			}
+			validateScopes();
+			validateRedirectUris();
+			return create();
 		}
 
 		private RegisteredClient create() {
@@ -380,5 +386,4 @@ public class RegisteredClient implements Serializable {
 			}
 		}
 	}
-
 }

+ 1 - 0
core/src/main/java/org/springframework/security/oauth2/server/authorization/client/RegisteredClientRepository.java

@@ -21,6 +21,7 @@ package org.springframework.security.oauth2.server.authorization.client;
  * @author Joe Grandja
  * @author Anoop Garlapati
  * @see RegisteredClient
+ * @since 0.0.1
  */
 public interface RegisteredClientRepository {
 

+ 7 - 7
core/src/test/java/org/springframework/security/oauth2/server/authorization/client/InMemoryRegisteredClientRepositoryTests.java

@@ -51,7 +51,7 @@ public class InMemoryRegisteredClientRepositoryTests {
 	}
 
 	@Test
-	public void constructorListClientRegistrationWhenEmptyThenThrowIllegalArgumentException() {
+	public void constructorListRegisteredClientWhenEmptyThenThrowIllegalArgumentException() {
 		assertThatThrownBy(() -> {
 			List<RegisteredClient> registrations = Collections.emptyList();
 			new InMemoryRegisteredClientRepository(registrations);
@@ -82,34 +82,34 @@ public class InMemoryRegisteredClientRepositoryTests {
 	@Test
 	public void findByIdWhenFoundThenFound() {
 		String id = this.registration.getId();
-		assertThat(clients.findById(id)).isEqualTo(this.registration);
+		assertThat(this.clients.findById(id)).isEqualTo(this.registration);
 	}
 
 	@Test
 	public void findByIdWhenNotFoundThenNull() {
 		String missingId = this.registration.getId() + "MISSING";
-		assertThat(clients.findById(missingId)).isNull();
+		assertThat(this.clients.findById(missingId)).isNull();
 	}
 
 	@Test
 	public void findByIdWhenNullThenThrowIllegalArgumentException() {
-		assertThatThrownBy(() -> clients.findById(null)).isInstanceOf(IllegalArgumentException.class);
+		assertThatThrownBy(() -> this.clients.findById(null)).isInstanceOf(IllegalArgumentException.class);
 	}
 
 	@Test
 	public void findByClientIdWhenFoundThenFound() {
 		String clientId = this.registration.getClientId();
-		assertThat(clients.findByClientId(clientId)).isEqualTo(this.registration);
+		assertThat(this.clients.findByClientId(clientId)).isEqualTo(this.registration);
 	}
 
 	@Test
 	public void findByClientIdWhenNotFoundThenNull() {
 		String missingClientId = this.registration.getClientId() + "MISSING";
-		assertThat(clients.findByClientId(missingClientId)).isNull();
+		assertThat(this.clients.findByClientId(missingClientId)).isNull();
 	}
 
 	@Test
 	public void findByClientIdWhenNullThenThrowIllegalArgumentException() {
-		assertThatThrownBy(() -> clients.findByClientId(null)).isInstanceOf(IllegalArgumentException.class);
+		assertThatThrownBy(() -> this.clients.findByClientId(null)).isInstanceOf(IllegalArgumentException.class);
 	}
 }

+ 17 - 53
core/src/test/java/org/springframework/security/oauth2/server/authorization/client/RegisteredClientTests.java

@@ -43,7 +43,7 @@ public class RegisteredClientTests {
 			Collections.singleton(ClientAuthenticationMethod.BASIC);
 
 	@Test
-	public void buildWhenAuthorizationGrantTypesIsNotSetThenThrowIllegalArgumentException() {
+	public void buildWhenAuthorizationGrantTypesNotSetThenThrowIllegalArgumentException() {
 		assertThatThrownBy(() ->
 				RegisteredClient.withId(ID)
 						.clientId(CLIENT_ID)
@@ -56,7 +56,7 @@ public class RegisteredClientTests {
 	}
 
 	@Test
-	public void buildWhenAuthorizationCodeGrantAllAttributesProvidedThenAllAttributesAreSet() {
+	public void buildWhenAllAttributesProvidedThenAllAttributesAreSet() {
 		RegisteredClient registration = RegisteredClient.withId(ID)
 				.clientId(CLIENT_ID)
 				.clientSecret(CLIENT_SECRET)
@@ -77,21 +77,13 @@ public class RegisteredClientTests {
 	}
 
 	@Test
-	public void buildWhenAuthorizationCodeGrantIdIsNullThenThrowIllegalArgumentException() {
-		assertThatThrownBy(() ->
-				RegisteredClient.withId(null)
-						.clientId(CLIENT_ID)
-						.clientSecret(CLIENT_SECRET)
-						.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
-						.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC)
-						.redirectUris(redirectUris -> redirectUris.addAll(REDIRECT_URIS))
-						.scopes(scopes -> scopes.addAll(SCOPES))
-						.build()
-		).isInstanceOf(IllegalArgumentException.class);
+	public void buildWhenIdIsNullThenThrowIllegalArgumentException() {
+		assertThatThrownBy(() -> RegisteredClient.withId(null))
+				.isInstanceOf(IllegalArgumentException.class);
 	}
 
 	@Test
-	public void buildWhenAuthorizationCodeGrantClientIdIsNullThenThrowIllegalArgumentException() {
+	public void buildWhenClientIdIsNullThenThrowIllegalArgumentException() {
 		assertThatThrownBy(() ->
 				RegisteredClient.withId(ID)
 						.clientId(null)
@@ -105,21 +97,7 @@ public class RegisteredClientTests {
 	}
 
 	@Test
-	public void buildWhenAuthorizationCodeGrantClientSecretIsNullThenThrowIllegalArgumentException() {
-		assertThatThrownBy(() ->
-				RegisteredClient.withId(ID)
-						.clientId(null)
-						.clientSecret(CLIENT_SECRET)
-						.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
-						.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC)
-						.redirectUris(redirectUris -> redirectUris.addAll(REDIRECT_URIS))
-						.scopes(scopes -> scopes.addAll(SCOPES))
-						.build()
-		).isInstanceOf(IllegalArgumentException.class);
-	}
-
-	@Test
-	public void buildWhenAuthorizationCodeGrantRedirectUrisNotProvidedThenThrowIllegalArgumentException() {
+	public void buildWhenRedirectUrisNotProvidedThenThrowIllegalArgumentException() {
 		assertThatThrownBy(() ->
 				RegisteredClient.withId(ID)
 						.clientId(CLIENT_ID)
@@ -132,7 +110,7 @@ public class RegisteredClientTests {
 	}
 
 	@Test
-	public void buildWhenAuthorizationCodeGrantRedirectUrisConsumerClearsSetThenThrowIllegalArgumentException() {
+	public void buildWhenRedirectUrisConsumerClearsSetThenThrowIllegalArgumentException() {
 		assertThatThrownBy(() ->
 				RegisteredClient.withId(ID)
 						.clientId(CLIENT_ID)
@@ -147,7 +125,7 @@ public class RegisteredClientTests {
 	}
 
 	@Test
-	public void buildWhenAuthorizationCodeGrantClientAuthenticationMethodNotProvidedThenDefaultToBasic() {
+	public void buildWhenClientAuthenticationMethodNotProvidedThenDefaultToBasic() {
 		RegisteredClient registration = RegisteredClient.withId(ID)
 				.clientId(CLIENT_ID)
 				.clientSecret(CLIENT_SECRET)
@@ -161,7 +139,7 @@ public class RegisteredClientTests {
 	}
 
 	@Test
-	public void buildWhenAuthorizationCodeGrantScopeIsEmptyThenScopeNotRequired() {
+	public void buildWhenScopeIsEmptyThenScopeNotRequired() {
 		RegisteredClient.withId(ID)
 				.clientId(CLIENT_ID)
 				.clientSecret(CLIENT_SECRET)
@@ -172,7 +150,7 @@ public class RegisteredClientTests {
 	}
 
 	@Test
-	public void buildWhenAuthorizationCodeGrantScopeConsumerIsProvidedThenConsumerAccepted() {
+	public void buildWhenScopeConsumerIsProvidedThenConsumerAccepted() {
 		RegisteredClient registration = RegisteredClient.withId(ID)
 				.clientId(CLIENT_ID)
 				.clientSecret(CLIENT_SECRET)
@@ -186,11 +164,10 @@ public class RegisteredClientTests {
 	}
 
 	@Test
-	public void buildWhenScopeContainsASpaceThenThrowIllegalArgumentException() {
+	public void buildWhenScopeContainsSpaceThenThrowIllegalArgumentException() {
 		assertThatThrownBy(() ->
 				RegisteredClient.withId(ID)
 						.clientId(CLIENT_ID)
-						.clientSecret(null)
 						.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
 						.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC)
 						.redirectUris(redirectUris -> redirectUris.addAll(REDIRECT_URIS))
@@ -200,7 +177,7 @@ public class RegisteredClientTests {
 	}
 
 	@Test
-	public void buildWhenScopesContainsAnInvalidCharacterThenThrowIllegalArgumentException() {
+	public void buildWhenScopeContainsInvalidCharacterThenThrowIllegalArgumentException() {
 		assertThatThrownBy(() ->
 				RegisteredClient.withId(ID)
 						.clientId(CLIENT_ID)
@@ -214,7 +191,7 @@ public class RegisteredClientTests {
 	}
 
 	@Test
-	public void buildWhenRedirectUrisContainInvalidUriThenThrowIllegalArgumentException() {
+	public void buildWhenRedirectUriInvalidThenThrowIllegalArgumentException() {
 		assertThatThrownBy(() ->
 				RegisteredClient.withId(ID)
 						.clientId(CLIENT_ID)
@@ -228,7 +205,7 @@ public class RegisteredClientTests {
 	}
 
 	@Test
-	public void buildWhenRedirectUrisContainUriWithFragmentThenThrowIllegalArgumentException() {
+	public void buildWhenRedirectUriContainsFragmentThenThrowIllegalArgumentException() {
 		assertThatThrownBy(() ->
 				RegisteredClient.withId(ID)
 						.clientId(CLIENT_ID)
@@ -281,6 +258,7 @@ public class RegisteredClientTests {
 			RegisteredClient.withId(ID)
 					.clientId(CLIENT_ID)
 					.clientSecret(CLIENT_SECRET)
+					.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
 					.authorizationGrantTypes(Set::clear)
 					.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC)
 					.redirectUris(redirectUris -> redirectUris.addAll(REDIRECT_URIS))
@@ -323,20 +301,6 @@ public class RegisteredClientTests {
 				.containsExactly(ClientAuthenticationMethod.BASIC, ClientAuthenticationMethod.POST);
 	}
 
-	@Test
-	public void buildWhenClientAuthenticationMethodsConsumerClearsSetThenThrowIllegalArgumentException() {
-		assertThatThrownBy(() -> {
-			RegisteredClient.withId(ID)
-					.clientId(CLIENT_ID)
-					.clientSecret(CLIENT_SECRET)
-					.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
-					.clientAuthenticationMethods(Set::clear)
-					.redirectUris(redirectUris -> redirectUris.addAll(REDIRECT_URIS))
-					.scopes(scopes -> scopes.addAll(SCOPES))
-					.build();
-		}).isInstanceOf(IllegalArgumentException.class);
-	}
-
 	@Test
 	public void buildWhenOverrideIdThenOverridden() {
 		String overriddenId = "override";
@@ -383,7 +347,7 @@ public class RegisteredClientTests {
 	}
 
 	@Test
-	public void buildWhenClientRegistrationValuesOverriddenThenPropagated() {
+	public void buildWhenRegisteredClientValuesOverriddenThenPropagated() {
 		RegisteredClient registration = TestRegisteredClients.registeredClient().build();
 		String newSecret = "new-secret";
 		String newScope = "new-scope";