8 changed files with 1054 additions and 3 deletions
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
/* |
||||
* Copyright 2020 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 |
||||
* |
||||
* https://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.server.authorization; |
||||
|
||||
/** |
||||
* Internal class used for serialization across Spring Security Authorization Server classes. |
||||
* |
||||
* @author Anoop Garlapati |
||||
*/ |
||||
public class Version { |
||||
/** |
||||
* Global Serialization value for Spring Security Authorization Server classes. |
||||
*/ |
||||
public static final long SERIAL_VERSION_UID = "0.0.1".hashCode(); |
||||
} |
||||
@ -0,0 +1,84 @@
@@ -0,0 +1,84 @@
|
||||
/* |
||||
* Copyright 2020 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 |
||||
* |
||||
* https://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.server.authorization.client; |
||||
|
||||
import org.springframework.util.Assert; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.concurrent.ConcurrentHashMap; |
||||
|
||||
/** |
||||
* A {@link RegisteredClientRepository} that stores {@link RegisteredClient}(s) in-memory. |
||||
* |
||||
* @author Anoop Garlapati |
||||
* @see RegisteredClientRepository |
||||
* @see RegisteredClient |
||||
*/ |
||||
public final class InMemoryRegisteredClientRepository implements RegisteredClientRepository { |
||||
private final Map<String, RegisteredClient> idRegistrationMap; |
||||
private final Map<String, RegisteredClient> clientIdRegistrationMap; |
||||
|
||||
/** |
||||
* Constructs an {@code InMemoryRegisteredClientRepository} using the provided parameters. |
||||
* |
||||
* @param registrations the client registration(s) |
||||
*/ |
||||
public InMemoryRegisteredClientRepository(RegisteredClient... registrations) { |
||||
this(Arrays.asList(registrations)); |
||||
} |
||||
|
||||
/** |
||||
* Constructs an {@code InMemoryRegisteredClientRepository} using the provided parameters. |
||||
* |
||||
* @param registrations the client registration(s) |
||||
*/ |
||||
public InMemoryRegisteredClientRepository(List<RegisteredClient> registrations) { |
||||
Assert.notEmpty(registrations, "registrations cannot be empty"); |
||||
ConcurrentHashMap<String, RegisteredClient> idRegistrationMapResult = new ConcurrentHashMap<>(); |
||||
ConcurrentHashMap<String, RegisteredClient> clientIdRegistrationMapResult = new ConcurrentHashMap<>(); |
||||
for (RegisteredClient registration : registrations) { |
||||
Assert.notNull(registration, "registration cannot be null"); |
||||
String id = registration.getId(); |
||||
if (idRegistrationMapResult.containsKey(id)) { |
||||
throw new IllegalArgumentException("Registered client must be unique. " + |
||||
"Found duplicate identifier: " + id); |
||||
} |
||||
String clientId = registration.getClientId(); |
||||
if (clientIdRegistrationMapResult.containsKey(clientId)) { |
||||
throw new IllegalArgumentException("Registered client must be unique. " + |
||||
"Found duplicate client identifier: " + clientId); |
||||
} |
||||
idRegistrationMapResult.put(id, registration); |
||||
clientIdRegistrationMapResult.put(clientId, registration); |
||||
} |
||||
idRegistrationMap = idRegistrationMapResult; |
||||
clientIdRegistrationMap = clientIdRegistrationMapResult; |
||||
} |
||||
|
||||
@Override |
||||
public RegisteredClient findById(String id) { |
||||
Assert.hasText(id, "id cannot be empty"); |
||||
return this.idRegistrationMap.get(id); |
||||
} |
||||
|
||||
@Override |
||||
public RegisteredClient findByClientId(String clientId) { |
||||
Assert.hasText(clientId, "clientId cannot be empty"); |
||||
return this.clientIdRegistrationMap.get(clientId); |
||||
} |
||||
} |
||||
@ -0,0 +1,115 @@
@@ -0,0 +1,115 @@
|
||||
/* |
||||
* Copyright 2020 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 |
||||
* |
||||
* https://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.server.authorization.client; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy; |
||||
|
||||
/** |
||||
* Tests for {@link InMemoryRegisteredClientRepository}. |
||||
* |
||||
* @author Anoop Garlapati |
||||
*/ |
||||
public class InMemoryRegisteredClientRepositoryTests { |
||||
private RegisteredClient registration = TestRegisteredClients.registeredClient().build(); |
||||
|
||||
private InMemoryRegisteredClientRepository clients = new InMemoryRegisteredClientRepository(this.registration); |
||||
|
||||
@Test |
||||
public void constructorVarargsRegisteredClientWhenNullThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> { |
||||
RegisteredClient registration = null; |
||||
new InMemoryRegisteredClientRepository(registration); |
||||
}).isInstanceOf(IllegalArgumentException.class); |
||||
} |
||||
|
||||
@Test |
||||
public void constructorListRegisteredClientWhenNullThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> { |
||||
List<RegisteredClient> registrations = null; |
||||
new InMemoryRegisteredClientRepository(registrations); |
||||
}).isInstanceOf(IllegalArgumentException.class); |
||||
} |
||||
|
||||
@Test |
||||
public void constructorListClientRegistrationWhenEmptyThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> { |
||||
List<RegisteredClient> registrations = Collections.emptyList(); |
||||
new InMemoryRegisteredClientRepository(registrations); |
||||
}).isInstanceOf(IllegalArgumentException.class); |
||||
} |
||||
|
||||
@Test |
||||
public void constructorListRegisteredClientWhenDuplicateIdThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> { |
||||
RegisteredClient anotherRegistrationWithSameId = TestRegisteredClients.registeredClient2() |
||||
.id(this.registration.getId()).build(); |
||||
List<RegisteredClient> registrations = Arrays.asList(this.registration, anotherRegistrationWithSameId); |
||||
new InMemoryRegisteredClientRepository(registrations); |
||||
}).isInstanceOf(IllegalArgumentException.class); |
||||
} |
||||
|
||||
@Test |
||||
public void constructorListRegisteredClientWhenDuplicateClientIdThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> { |
||||
RegisteredClient anotherRegistrationWithSameClientId = TestRegisteredClients.registeredClient2() |
||||
.clientId(this.registration.getClientId()).build(); |
||||
List<RegisteredClient> registrations = Arrays.asList(this.registration, |
||||
anotherRegistrationWithSameClientId); |
||||
new InMemoryRegisteredClientRepository(registrations); |
||||
}).isInstanceOf(IllegalArgumentException.class); |
||||
} |
||||
|
||||
@Test |
||||
public void findByIdWhenFoundThenFound() { |
||||
String id = this.registration.getId(); |
||||
assertThat(clients.findById(id)).isEqualTo(this.registration); |
||||
} |
||||
|
||||
@Test |
||||
public void findByIdWhenNotFoundThenNull() { |
||||
String missingId = this.registration.getId() + "MISSING"; |
||||
assertThat(clients.findById(missingId)).isNull(); |
||||
} |
||||
|
||||
@Test |
||||
public void findByIdWhenNullThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> clients.findById(null)).isInstanceOf(IllegalArgumentException.class); |
||||
} |
||||
|
||||
@Test |
||||
public void findByClientIdWhenFoundThenFound() { |
||||
String clientId = this.registration.getClientId(); |
||||
assertThat(clients.findByClientId(clientId)).isEqualTo(this.registration); |
||||
} |
||||
|
||||
@Test |
||||
public void findByClientIdWhenNotFoundThenNull() { |
||||
String missingClientId = this.registration.getClientId() + "MISSING"; |
||||
assertThat(clients.findByClientId(missingClientId)).isNull(); |
||||
} |
||||
|
||||
@Test |
||||
public void findByClientIdWhenNullThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> clients.findByClientId(null)).isInstanceOf(IllegalArgumentException.class); |
||||
} |
||||
} |
||||
@ -0,0 +1,410 @@
@@ -0,0 +1,410 @@
|
||||
/* |
||||
* Copyright 2020 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 |
||||
* |
||||
* https://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.server.authorization.client; |
||||
|
||||
import org.junit.Test; |
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType; |
||||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.Set; |
||||
import java.util.stream.Collectors; |
||||
import java.util.stream.Stream; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy; |
||||
|
||||
/** |
||||
* Tests for {@link RegisteredClient}. |
||||
* |
||||
* @author Anoop Garlapati |
||||
*/ |
||||
public class RegisteredClientTests { |
||||
private static final String ID = "registration-1"; |
||||
private static final String CLIENT_ID = "client-1"; |
||||
private static final String CLIENT_SECRET = "secret"; |
||||
private static final Set<String> REDIRECT_URIS = Collections.singleton("https://example.com"); |
||||
private static final Set<String> SCOPES = Collections.unmodifiableSet( |
||||
Stream.of("openid", "profile", "email").collect(Collectors.toSet())); |
||||
private static final Set<ClientAuthenticationMethod> CLIENT_AUTHENTICATION_METHODS = |
||||
Collections.singleton(ClientAuthenticationMethod.BASIC); |
||||
|
||||
@Test |
||||
public void buildWhenAuthorizationGrantTypesIsNotSetThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> |
||||
RegisteredClient.withId(ID) |
||||
.clientId(CLIENT_ID) |
||||
.clientSecret(CLIENT_SECRET) |
||||
.redirectUris(redirectUris -> redirectUris.addAll(REDIRECT_URIS)) |
||||
.scopes(scopes -> scopes.addAll(SCOPES)) |
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) |
||||
.build() |
||||
).isInstanceOf(IllegalArgumentException.class); |
||||
} |
||||
|
||||
@Test |
||||
public void buildWhenAuthorizationCodeGrantAllAttributesProvidedThenAllAttributesAreSet() { |
||||
RegisteredClient registration = RegisteredClient.withId(ID) |
||||
.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(); |
||||
|
||||
assertThat(registration.getId()).isEqualTo(ID); |
||||
assertThat(registration.getClientId()).isEqualTo(CLIENT_ID); |
||||
assertThat(registration.getClientSecret()).isEqualTo(CLIENT_SECRET); |
||||
assertThat(registration.getAuthorizationGrantTypes()) |
||||
.isEqualTo(Collections.singleton(AuthorizationGrantType.AUTHORIZATION_CODE)); |
||||
assertThat(registration.getClientAuthenticationMethods()).isEqualTo(CLIENT_AUTHENTICATION_METHODS); |
||||
assertThat(registration.getRedirectUris()).isEqualTo(REDIRECT_URIS); |
||||
assertThat(registration.getScopes()).isEqualTo(SCOPES); |
||||
} |
||||
|
||||
@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); |
||||
} |
||||
|
||||
@Test |
||||
public void buildWhenAuthorizationCodeGrantClientIdIsNullThenThrowIllegalArgumentException() { |
||||
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 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() { |
||||
assertThatThrownBy(() -> |
||||
RegisteredClient.withId(ID) |
||||
.clientId(CLIENT_ID) |
||||
.clientSecret(CLIENT_SECRET) |
||||
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) |
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) |
||||
.scopes(scopes -> scopes.addAll(SCOPES)) |
||||
.build() |
||||
).isInstanceOf(IllegalArgumentException.class); |
||||
} |
||||
|
||||
@Test |
||||
public void buildWhenAuthorizationCodeGrantRedirectUrisConsumerClearsSetThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> |
||||
RegisteredClient.withId(ID) |
||||
.clientId(CLIENT_ID) |
||||
.clientSecret(CLIENT_SECRET) |
||||
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) |
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) |
||||
.redirectUri("https://example.com") |
||||
.redirectUris(Set::clear) |
||||
.scopes(scopes -> scopes.addAll(SCOPES)) |
||||
.build() |
||||
).isInstanceOf(IllegalArgumentException.class); |
||||
} |
||||
|
||||
@Test |
||||
public void buildWhenAuthorizationCodeGrantClientAuthenticationMethodNotProvidedThenDefaultToBasic() { |
||||
RegisteredClient registration = RegisteredClient.withId(ID) |
||||
.clientId(CLIENT_ID) |
||||
.clientSecret(CLIENT_SECRET) |
||||
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) |
||||
.redirectUris(redirectUris -> redirectUris.addAll(REDIRECT_URIS)) |
||||
.scopes(scopes -> scopes.addAll(SCOPES)) |
||||
.build(); |
||||
|
||||
assertThat(registration.getClientAuthenticationMethods()) |
||||
.isEqualTo(Collections.singleton(ClientAuthenticationMethod.BASIC)); |
||||
} |
||||
|
||||
@Test |
||||
public void buildWhenAuthorizationCodeGrantScopeIsEmptyThenScopeNotRequired() { |
||||
RegisteredClient.withId(ID) |
||||
.clientId(CLIENT_ID) |
||||
.clientSecret(CLIENT_SECRET) |
||||
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) |
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) |
||||
.redirectUris(redirectUris -> redirectUris.addAll(REDIRECT_URIS)) |
||||
.build(); |
||||
} |
||||
|
||||
@Test |
||||
public void buildWhenAuthorizationCodeGrantScopeConsumerIsProvidedThenConsumerAccepted() { |
||||
RegisteredClient registration = RegisteredClient.withId(ID) |
||||
.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(); |
||||
|
||||
assertThat(registration.getScopes()).isEqualTo(SCOPES); |
||||
} |
||||
|
||||
@Test |
||||
public void buildWhenScopeContainsASpaceThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> |
||||
RegisteredClient.withId(ID) |
||||
.clientId(CLIENT_ID) |
||||
.clientSecret(null) |
||||
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) |
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) |
||||
.redirectUris(redirectUris -> redirectUris.addAll(REDIRECT_URIS)) |
||||
.scope("openid profile") |
||||
.build() |
||||
).isInstanceOf(IllegalArgumentException.class); |
||||
} |
||||
|
||||
@Test |
||||
public void buildWhenScopesContainsAnInvalidCharacterThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> |
||||
RegisteredClient.withId(ID) |
||||
.clientId(CLIENT_ID) |
||||
.clientSecret(CLIENT_SECRET) |
||||
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) |
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) |
||||
.redirectUris(redirectUris -> redirectUris.addAll(REDIRECT_URIS)) |
||||
.scope("an\"invalid\"scope") |
||||
.build() |
||||
).isInstanceOf(IllegalArgumentException.class); |
||||
} |
||||
|
||||
@Test |
||||
public void buildWhenRedirectUrisContainInvalidUriThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> |
||||
RegisteredClient.withId(ID) |
||||
.clientId(CLIENT_ID) |
||||
.clientSecret(CLIENT_SECRET) |
||||
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) |
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) |
||||
.redirectUri("invalid URI") |
||||
.scopes(scopes -> scopes.addAll(SCOPES)) |
||||
.build() |
||||
).isInstanceOf(IllegalArgumentException.class); |
||||
} |
||||
|
||||
@Test |
||||
public void buildWhenRedirectUrisContainUriWithFragmentThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> |
||||
RegisteredClient.withId(ID) |
||||
.clientId(CLIENT_ID) |
||||
.clientSecret(CLIENT_SECRET) |
||||
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) |
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) |
||||
.redirectUri("https://example.com/page#fragment") |
||||
.scopes(scopes -> scopes.addAll(SCOPES)) |
||||
.build() |
||||
).isInstanceOf(IllegalArgumentException.class); |
||||
} |
||||
|
||||
@Test |
||||
public void buildWhenTwoAuthorizationGrantTypesAreProvidedThenBothAreRegistered() { |
||||
RegisteredClient registration = RegisteredClient.withId(ID) |
||||
.clientId(CLIENT_ID) |
||||
.clientSecret(CLIENT_SECRET) |
||||
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) |
||||
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) |
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) |
||||
.redirectUris(redirectUris -> redirectUris.addAll(REDIRECT_URIS)) |
||||
.scopes(scopes -> scopes.addAll(SCOPES)) |
||||
.build(); |
||||
|
||||
assertThat(registration.getAuthorizationGrantTypes()) |
||||
.containsExactly(AuthorizationGrantType.AUTHORIZATION_CODE, AuthorizationGrantType.CLIENT_CREDENTIALS); |
||||
} |
||||
|
||||
@Test |
||||
public void buildWhenAuthorizationGrantTypesConsumerIsProvidedThenConsumerAccepted() { |
||||
RegisteredClient registration = RegisteredClient.withId(ID) |
||||
.clientId(CLIENT_ID) |
||||
.clientSecret(CLIENT_SECRET) |
||||
.authorizationGrantTypes(authorizationGrantTypes -> { |
||||
authorizationGrantTypes.add(AuthorizationGrantType.AUTHORIZATION_CODE); |
||||
authorizationGrantTypes.add(AuthorizationGrantType.CLIENT_CREDENTIALS); |
||||
}) |
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) |
||||
.redirectUris(redirectUris -> redirectUris.addAll(REDIRECT_URIS)) |
||||
.scopes(scopes -> scopes.addAll(SCOPES)) |
||||
.build(); |
||||
|
||||
assertThat(registration.getAuthorizationGrantTypes()) |
||||
.containsExactly(AuthorizationGrantType.AUTHORIZATION_CODE, AuthorizationGrantType.CLIENT_CREDENTIALS); |
||||
} |
||||
|
||||
@Test |
||||
public void buildWhenAuthorizationGrantTypesConsumerClearsSetThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> { |
||||
RegisteredClient.withId(ID) |
||||
.clientId(CLIENT_ID) |
||||
.clientSecret(CLIENT_SECRET) |
||||
.authorizationGrantTypes(Set::clear) |
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) |
||||
.redirectUris(redirectUris -> redirectUris.addAll(REDIRECT_URIS)) |
||||
.scopes(scopes -> scopes.addAll(SCOPES)) |
||||
.build(); |
||||
}).isInstanceOf(IllegalArgumentException.class); |
||||
} |
||||
|
||||
@Test |
||||
public void buildWhenTwoClientAuthenticationMethodsAreProvidedThenBothAreRegistered() { |
||||
RegisteredClient registration = RegisteredClient.withId(ID) |
||||
.clientId(CLIENT_ID) |
||||
.clientSecret(CLIENT_SECRET) |
||||
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) |
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) |
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.POST) |
||||
.redirectUris(redirectUris -> redirectUris.addAll(REDIRECT_URIS)) |
||||
.scopes(scopes -> scopes.addAll(SCOPES)) |
||||
.build(); |
||||
|
||||
assertThat(registration.getClientAuthenticationMethods()) |
||||
.containsExactly(ClientAuthenticationMethod.BASIC, ClientAuthenticationMethod.POST); |
||||
} |
||||
|
||||
@Test |
||||
public void buildWhenClientAuthenticationMethodsConsumerIsProvidedThenConsumerAccepted() { |
||||
RegisteredClient registration = RegisteredClient.withId(ID) |
||||
.clientId(CLIENT_ID) |
||||
.clientSecret(CLIENT_SECRET) |
||||
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) |
||||
.clientAuthenticationMethods(clientAuthenticationMethods -> { |
||||
clientAuthenticationMethods.add(ClientAuthenticationMethod.BASIC); |
||||
clientAuthenticationMethods.add(ClientAuthenticationMethod.POST); |
||||
}) |
||||
.redirectUris(redirectUris -> redirectUris.addAll(REDIRECT_URIS)) |
||||
.scopes(scopes -> scopes.addAll(SCOPES)) |
||||
.build(); |
||||
|
||||
assertThat(registration.getClientAuthenticationMethods()) |
||||
.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"; |
||||
RegisteredClient registration = RegisteredClient.withId(ID) |
||||
.id(overriddenId) |
||||
.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(); |
||||
|
||||
assertThat(registration.getId()).isEqualTo(overriddenId); |
||||
} |
||||
|
||||
@Test |
||||
public void buildWhenRegisteredClientProvidedThenMakesACopy() { |
||||
RegisteredClient registration = TestRegisteredClients.registeredClient().build(); |
||||
RegisteredClient updated = RegisteredClient.withRegisteredClient(registration).build(); |
||||
|
||||
assertThat(registration.getClientAuthenticationMethods()).isEqualTo(updated.getClientAuthenticationMethods()); |
||||
assertThat(registration.getClientAuthenticationMethods()).isNotSameAs(updated.getClientAuthenticationMethods()); |
||||
assertThat(registration.getAuthorizationGrantTypes()).isEqualTo(updated.getAuthorizationGrantTypes()); |
||||
assertThat(registration.getAuthorizationGrantTypes()).isNotSameAs(updated.getAuthorizationGrantTypes()); |
||||
assertThat(registration.getRedirectUris()).isEqualTo(updated.getRedirectUris()); |
||||
assertThat(registration.getRedirectUris()).isNotSameAs(updated.getRedirectUris()); |
||||
assertThat(registration.getScopes()).isEqualTo(updated.getScopes()); |
||||
assertThat(registration.getScopes()).isNotSameAs(updated.getScopes()); |
||||
} |
||||
|
||||
@Test |
||||
public void buildWhenRegisteredClientProvidedThenEachPropertyMatches() { |
||||
RegisteredClient registration = TestRegisteredClients.registeredClient().build(); |
||||
RegisteredClient updated = RegisteredClient.withRegisteredClient(registration).build(); |
||||
|
||||
assertThat(registration.getId()).isEqualTo(updated.getId()); |
||||
assertThat(registration.getClientId()).isEqualTo(updated.getClientId()); |
||||
assertThat(registration.getClientSecret()).isEqualTo(updated.getClientSecret()); |
||||
assertThat(registration.getClientAuthenticationMethods()).isEqualTo(updated.getClientAuthenticationMethods()); |
||||
assertThat(registration.getAuthorizationGrantTypes()).isEqualTo(updated.getAuthorizationGrantTypes()); |
||||
assertThat(registration.getRedirectUris()).isEqualTo(updated.getRedirectUris()); |
||||
assertThat(registration.getScopes()).isEqualTo(updated.getScopes()); |
||||
} |
||||
|
||||
@Test |
||||
public void buildWhenClientRegistrationValuesOverriddenThenPropagated() { |
||||
RegisteredClient registration = TestRegisteredClients.registeredClient().build(); |
||||
String newSecret = "new-secret"; |
||||
String newScope = "new-scope"; |
||||
String newRedirectUri = "https://another-redirect-uri.com"; |
||||
RegisteredClient updated = RegisteredClient.withRegisteredClient(registration) |
||||
.clientSecret(newSecret) |
||||
.scopes(scopes -> { |
||||
scopes.clear(); |
||||
scopes.add(newScope); |
||||
}) |
||||
.redirectUris(redirectUris -> { |
||||
redirectUris.clear(); |
||||
redirectUris.add(newRedirectUri); |
||||
}) |
||||
.build(); |
||||
|
||||
assertThat(registration.getClientSecret()).isNotEqualTo(newSecret); |
||||
assertThat(updated.getClientSecret()).isEqualTo(newSecret); |
||||
assertThat(registration.getScopes()).doesNotContain(newScope); |
||||
assertThat(updated.getScopes()).containsExactly(newScope); |
||||
assertThat(registration.getRedirectUris()).doesNotContain(newRedirectUri); |
||||
assertThat(updated.getRedirectUris()).containsExactly(newRedirectUri); |
||||
} |
||||
} |
||||
@ -0,0 +1,49 @@
@@ -0,0 +1,49 @@
|
||||
/* |
||||
* Copyright 2020 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 |
||||
* |
||||
* https://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.server.authorization.client; |
||||
|
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType; |
||||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod; |
||||
|
||||
/** |
||||
* @author Anoop Garlapati |
||||
*/ |
||||
public class TestRegisteredClients { |
||||
|
||||
public static RegisteredClient.Builder registeredClient() { |
||||
return RegisteredClient.withId("registration-1") |
||||
.clientId("client-1") |
||||
.clientSecret("secret") |
||||
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) |
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) |
||||
.redirectUri("https://example.com") |
||||
.scope("openid") |
||||
.scope("profile") |
||||
.scope("email"); |
||||
} |
||||
|
||||
public static RegisteredClient.Builder registeredClient2() { |
||||
return RegisteredClient.withId("registration-2") |
||||
.clientId("client-2") |
||||
.clientSecret("secret") |
||||
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) |
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) |
||||
.redirectUri("https://example.com") |
||||
.scope("openid") |
||||
.scope("profile") |
||||
.scope("email"); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue