Add InMemoryReactiveClientRegistrationRepository
Issue: gh-4807
This commit is contained in:
parent
ca9cd20832
commit
a02b0c17f8
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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.registration;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ConcurrentReferenceHashMap;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* A Reactive {@link ClientRegistrationRepository} that stores {@link ClientRegistration}(s) in-memory.
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @since 5.1
|
||||
* @see ClientRegistrationRepository
|
||||
* @see ClientRegistration
|
||||
*/
|
||||
public final class InMemoryReactiveClientRegistrationRepository
|
||||
implements ReactiveClientRegistrationRepository, Iterable<ClientRegistration> {
|
||||
|
||||
private final Map<String, ClientRegistration> clientIdToClientRegistration;
|
||||
|
||||
/**
|
||||
* Constructs an {@code InMemoryReactiveClientRegistrationRepository} using the provided parameters.
|
||||
*
|
||||
* @param registrations the client registration(s)
|
||||
*/
|
||||
public InMemoryReactiveClientRegistrationRepository(ClientRegistration... registrations) {
|
||||
Assert.notEmpty(registrations, "registrations cannot be empty");
|
||||
this.clientIdToClientRegistration = new ConcurrentReferenceHashMap<>();
|
||||
for (ClientRegistration registration : registrations) {
|
||||
Assert.notNull(registration, "registrations cannot contain null values");
|
||||
this.clientIdToClientRegistration.put(registration.getRegistrationId(), registration);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an {@code InMemoryReactiveClientRegistrationRepository} using the provided parameters.
|
||||
*
|
||||
* @param registrations the client registration(s)
|
||||
*/
|
||||
public InMemoryReactiveClientRegistrationRepository(List<ClientRegistration> registrations) {
|
||||
Assert.notEmpty(registrations, "registrations cannot be null or empty");
|
||||
this.clientIdToClientRegistration = registrations.stream()
|
||||
.collect(Collectors.toConcurrentMap(ClientRegistration::getRegistrationId, Function.identity()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Mono<ClientRegistration> findByRegistrationId(String registrationId) {
|
||||
return Mono.justOrEmpty(this.clientIdToClientRegistration.get(registrationId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@code Iterator} of {@link ClientRegistration}.
|
||||
*
|
||||
* @return an {@code Iterator<ClientRegistration>}
|
||||
*/
|
||||
@Override
|
||||
public Iterator<ClientRegistration> iterator() {
|
||||
return this.clientIdToClientRegistration.values().iterator();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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.registration;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* A reactive repository for OAuth 2.0 / OpenID Connect 1.0 {@link ClientRegistration}(s).
|
||||
*
|
||||
* <p>
|
||||
* <b>NOTE:</b> Client registration information is ultimately stored and owned
|
||||
* by the associated Authorization Server.
|
||||
* Therefore, this repository provides the capability to store a sub-set copy
|
||||
* of the <i>primary</i> client registration information
|
||||
* externally from the Authorization Server.
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @since 5.1
|
||||
* @see ClientRegistration
|
||||
*/
|
||||
public interface ReactiveClientRegistrationRepository {
|
||||
|
||||
/**
|
||||
* Returns the client registration identified by the provided {@code registrationId}, or {@code null} if not found.
|
||||
*
|
||||
* @param registrationId the registration identifier
|
||||
* @return the {@link ClientRegistration} if found, otherwise {@code null}
|
||||
*/
|
||||
Mono<ClientRegistration> findByRegistrationId(String registrationId);
|
||||
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* 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.registration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
||||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
|
||||
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
* @since 5.1
|
||||
*/
|
||||
public class InMemoryReactiveClientRegistrationRepositoryTests {
|
||||
|
||||
private ClientRegistration github = ClientRegistration.withRegistrationId("github")
|
||||
.redirectUriTemplate("{baseUrl}/{action}/oauth2/code/{registrationId}")
|
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC)
|
||||
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
|
||||
.scope("read:user")
|
||||
.authorizationUri("https://github.com/login/oauth/authorize")
|
||||
.tokenUri("https://github.com/login/oauth/access_token")
|
||||
.userInfoUri("https://api.github.com/user")
|
||||
.userNameAttributeName("id")
|
||||
.clientName("GitHub")
|
||||
.clientId("clientId")
|
||||
.clientSecret("clientSecret")
|
||||
.build();
|
||||
|
||||
private InMemoryReactiveClientRegistrationRepository repository;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.repository = new InMemoryReactiveClientRegistrationRepository(this.github);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWhenZeroVarArgsThenIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> new InMemoryReactiveClientRegistrationRepository())
|
||||
.isInstanceOf(IllegalArgumentException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWhenClientRegistrationArrayThenIllegalArgumentException() {
|
||||
ClientRegistration[] registrations = null;
|
||||
assertThatThrownBy(() -> new InMemoryReactiveClientRegistrationRepository(registrations))
|
||||
.isInstanceOf(IllegalArgumentException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWhenClientRegistrationListThenIllegalArgumentException() {
|
||||
List<ClientRegistration> registrations = null;
|
||||
assertThatThrownBy(() -> new InMemoryReactiveClientRegistrationRepository(registrations))
|
||||
.isInstanceOf(IllegalArgumentException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWhenClientRegistrationIsNullThenIllegalArgumentException() {
|
||||
ClientRegistration registration = null;
|
||||
assertThatThrownBy(() -> new InMemoryReactiveClientRegistrationRepository(registration))
|
||||
.isInstanceOf(IllegalArgumentException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByRegistrationIdWhenValidIdThenFound() {
|
||||
StepVerifier.create(this.repository.findByRegistrationId(this.github.getRegistrationId()))
|
||||
.expectNext(this.github)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByRegistrationIdWhenNotValidIdThenEmpty() {
|
||||
StepVerifier.create(this.repository.findByRegistrationId(this.github.getRegistrationId() + "invalid"))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void iteratorWhenContainsGithubThenContains() {
|
||||
assertThat(this.repository.iterator())
|
||||
.containsOnly(this.github);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue