Polish "Add Spring Authorization Server support"
See gh-34003
This commit is contained in:
@@ -31,7 +31,6 @@ import org.springframework.security.oauth2.server.authorization.client.Registere
|
||||
import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
|
||||
import org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat;
|
||||
import org.springframework.security.oauth2.server.authorization.settings.TokenSettings;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* Adapter class to convert {@link Client} to a {@link RegisteredClient}.
|
||||
@@ -58,66 +57,23 @@ public final class OAuth2AuthorizationServerPropertiesRegistrationAdapter {
|
||||
map.from(registration::getClientId).to(builder::clientId);
|
||||
map.from(registration::getClientSecret).to(builder::clientSecret);
|
||||
map.from(registration::getClientName).to(builder::clientName);
|
||||
if (!CollectionUtils.isEmpty(registration.getClientAuthenticationMethods())) {
|
||||
registration.getClientAuthenticationMethods()
|
||||
.forEach((clientAuthenticationMethod) -> map.from(clientAuthenticationMethod)
|
||||
.as(OAuth2AuthorizationServerPropertiesRegistrationAdapter::clientAuthenticationMethod)
|
||||
.to(builder::clientAuthenticationMethod));
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(registration.getAuthorizationGrantTypes())) {
|
||||
registration.getAuthorizationGrantTypes()
|
||||
.forEach((authorizationGrantType) -> map.from(authorizationGrantType)
|
||||
.as(OAuth2AuthorizationServerPropertiesRegistrationAdapter::authorizationGrantType)
|
||||
.to(builder::authorizationGrantType));
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(registration.getRedirectUris())) {
|
||||
registration.getRedirectUris().forEach((redirectUri) -> map.from(redirectUri).to(builder::redirectUri));
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(registration.getPostLogoutRedirectUris())) {
|
||||
registration.getPostLogoutRedirectUris()
|
||||
.forEach((redirectUri) -> map.from(redirectUri).to(builder::postLogoutRedirectUri));
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(registration.getScopes())) {
|
||||
registration.getScopes().forEach((scope) -> map.from(scope).to(builder::scope));
|
||||
}
|
||||
registration.getClientAuthenticationMethods()
|
||||
.forEach((clientAuthenticationMethod) -> map.from(clientAuthenticationMethod)
|
||||
.as(ClientAuthenticationMethod::new)
|
||||
.to(builder::clientAuthenticationMethod));
|
||||
registration.getAuthorizationGrantTypes()
|
||||
.forEach((authorizationGrantType) -> map.from(authorizationGrantType)
|
||||
.as(AuthorizationGrantType::new)
|
||||
.to(builder::authorizationGrantType));
|
||||
registration.getRedirectUris().forEach((redirectUri) -> map.from(redirectUri).to(builder::redirectUri));
|
||||
registration.getPostLogoutRedirectUris()
|
||||
.forEach((redirectUri) -> map.from(redirectUri).to(builder::postLogoutRedirectUri));
|
||||
registration.getScopes().forEach((scope) -> map.from(scope).to(builder::scope));
|
||||
builder.clientSettings(getClientSettings(client, map));
|
||||
builder.tokenSettings(getTokenSettings(client, map));
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private static ClientAuthenticationMethod clientAuthenticationMethod(String clientAuthenticationMethod) {
|
||||
if (ClientAuthenticationMethod.CLIENT_SECRET_BASIC.getValue().equals(clientAuthenticationMethod)) {
|
||||
return ClientAuthenticationMethod.CLIENT_SECRET_BASIC;
|
||||
}
|
||||
else if (ClientAuthenticationMethod.CLIENT_SECRET_POST.getValue().equals(clientAuthenticationMethod)) {
|
||||
return ClientAuthenticationMethod.CLIENT_SECRET_POST;
|
||||
}
|
||||
else if (ClientAuthenticationMethod.CLIENT_SECRET_JWT.getValue().equals(clientAuthenticationMethod)) {
|
||||
return ClientAuthenticationMethod.CLIENT_SECRET_JWT;
|
||||
}
|
||||
else if (ClientAuthenticationMethod.PRIVATE_KEY_JWT.getValue().equals(clientAuthenticationMethod)) {
|
||||
return ClientAuthenticationMethod.PRIVATE_KEY_JWT;
|
||||
}
|
||||
else if (ClientAuthenticationMethod.NONE.getValue().equals(clientAuthenticationMethod)) {
|
||||
return ClientAuthenticationMethod.NONE;
|
||||
}
|
||||
else {
|
||||
return new ClientAuthenticationMethod(clientAuthenticationMethod);
|
||||
}
|
||||
}
|
||||
|
||||
private static AuthorizationGrantType authorizationGrantType(String authorizationGrantType) {
|
||||
if (AuthorizationGrantType.AUTHORIZATION_CODE.getValue().equals(authorizationGrantType)) {
|
||||
return AuthorizationGrantType.AUTHORIZATION_CODE;
|
||||
}
|
||||
else if (AuthorizationGrantType.CLIENT_CREDENTIALS.getValue().equals(authorizationGrantType)) {
|
||||
return AuthorizationGrantType.CLIENT_CREDENTIALS;
|
||||
}
|
||||
else {
|
||||
return new AuthorizationGrantType(authorizationGrantType);
|
||||
}
|
||||
}
|
||||
|
||||
private static ClientSettings getClientSettings(Client client, PropertyMapper map) {
|
||||
ClientSettings.Builder builder = ClientSettings.builder();
|
||||
map.from(client::isRequireProofKey).to(builder::requireProofKey);
|
||||
|
||||
@@ -21,10 +21,9 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
|
||||
|
||||
/**
|
||||
@@ -43,11 +42,11 @@ import org.springframework.security.oauth2.server.authorization.OAuth2Authorizat
|
||||
* @since 3.1.0
|
||||
* @see OAuth2AuthorizationServerJwtAutoConfiguration
|
||||
*/
|
||||
@AutoConfiguration(before = { OAuth2ResourceServerAutoConfiguration.class, SecurityFilterAutoConfiguration.class })
|
||||
@AutoConfiguration(before = { OAuth2ResourceServerAutoConfiguration.class, SecurityAutoConfiguration.class,
|
||||
UserDetailsServiceAutoConfiguration.class })
|
||||
@ConditionalOnClass(OAuth2Authorization.class)
|
||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
|
||||
@Import({ OAuth2AuthorizationServerPropertiesConfiguration.class,
|
||||
OAuth2AuthorizationServerWebSecurityConfiguration.class, ObjectPostProcessorConfiguration.class })
|
||||
@Import({ OAuth2AuthorizationServerConfiguration.class, OAuth2AuthorizationServerWebSecurityConfiguration.class })
|
||||
public class OAuth2AuthorizationServerAutoConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ import org.springframework.security.oauth2.server.authorization.settings.Authori
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties(OAuth2AuthorizationServerProperties.class)
|
||||
class OAuth2AuthorizationServerPropertiesConfiguration {
|
||||
class OAuth2AuthorizationServerConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@@ -16,13 +16,30 @@
|
||||
|
||||
package org.springframework.boot.autoconfigure.security.oauth2.server.servlet;
|
||||
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.nimbusds.jose.jwk.JWKSet;
|
||||
import com.nimbusds.jose.jwk.RSAKey;
|
||||
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
|
||||
import com.nimbusds.jose.jwk.source.JWKSource;
|
||||
import com.nimbusds.jose.proc.SecurityContext;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Role;
|
||||
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
|
||||
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for JWT support for endpoints of the
|
||||
@@ -30,12 +47,52 @@ import org.springframework.security.oauth2.server.authorization.OAuth2Authorizat
|
||||
*
|
||||
* @author Steve Riesenberg
|
||||
* @since 3.1.0
|
||||
* @see OAuth2AuthorizationServerAutoConfiguration
|
||||
*/
|
||||
@AutoConfiguration(after = { UserDetailsServiceAutoConfiguration.class })
|
||||
@AutoConfiguration(after = UserDetailsServiceAutoConfiguration.class)
|
||||
@ConditionalOnClass(OAuth2Authorization.class)
|
||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
|
||||
@Import(OAuth2AuthorizationServerJwtConfiguration.class)
|
||||
public class OAuth2AuthorizationServerJwtAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnClass(JwtDecoder.class)
|
||||
@ConditionalOnMissingBean
|
||||
JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
|
||||
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
@ConditionalOnMissingBean
|
||||
JWKSource<SecurityContext> jwkSource() {
|
||||
RSAKey rsaKey = getRsaKey();
|
||||
JWKSet jwkSet = new JWKSet(rsaKey);
|
||||
return new ImmutableJWKSet<>(jwkSet);
|
||||
}
|
||||
|
||||
private static RSAKey getRsaKey() {
|
||||
KeyPair keyPair = generateRsaKey();
|
||||
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
|
||||
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
|
||||
// @formatter:off
|
||||
RSAKey rsaKey = new RSAKey.Builder(publicKey)
|
||||
.privateKey(privateKey)
|
||||
.keyID(UUID.randomUUID().toString())
|
||||
.build();
|
||||
// @formatter:on
|
||||
return rsaKey;
|
||||
}
|
||||
|
||||
private static KeyPair generateRsaKey() {
|
||||
KeyPair keyPair;
|
||||
try {
|
||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
|
||||
keyPairGenerator.initialize(2048);
|
||||
keyPair = keyPairGenerator.generateKeyPair();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
return keyPair;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2023 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.boot.autoconfigure.security.oauth2.server.servlet;
|
||||
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.nimbusds.jose.jwk.JWKSet;
|
||||
import com.nimbusds.jose.jwk.RSAKey;
|
||||
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
|
||||
import com.nimbusds.jose.jwk.source.JWKSource;
|
||||
import com.nimbusds.jose.proc.SecurityContext;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Role;
|
||||
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
|
||||
|
||||
/**
|
||||
* {@link Configuration @Configuration} for JWT support for endpoints of the OAuth2
|
||||
* authorization server that require it (e.g. User Info, Client Registration).
|
||||
*
|
||||
* @author Steve Riesenberg
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
class OAuth2AuthorizationServerJwtConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnClass(JwtDecoder.class)
|
||||
@ConditionalOnMissingBean
|
||||
JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
|
||||
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
@ConditionalOnClass(JWKSource.class)
|
||||
@ConditionalOnMissingBean
|
||||
JWKSource<SecurityContext> jwkSource() {
|
||||
KeyPair keyPair = generateRsaKey();
|
||||
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
|
||||
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
|
||||
// @formatter:off
|
||||
RSAKey rsaKey = new RSAKey.Builder(publicKey)
|
||||
.privateKey(privateKey)
|
||||
.keyID(UUID.randomUUID().toString())
|
||||
.build();
|
||||
// @formatter:on
|
||||
JWKSet jwkSet = new JWKSet(rsaKey);
|
||||
return new ImmutableJWKSet<>(jwkSet);
|
||||
}
|
||||
|
||||
private static KeyPair generateRsaKey() {
|
||||
KeyPair keyPair;
|
||||
try {
|
||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
|
||||
keyPairGenerator.initialize(2048);
|
||||
keyPair = keyPairGenerator.generateKeyPair();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
return keyPair;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.boot.autoconfigure.security.oauth2.server.servlet;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.security.ConditionalOnDefaultWebSecurity;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -25,8 +26,10 @@ import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
|
||||
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
|
||||
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
|
||||
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
||||
|
||||
@@ -37,6 +40,7 @@ import org.springframework.security.web.authentication.LoginUrlAuthenticationEnt
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnDefaultWebSecurity
|
||||
@ConditionalOnBean({ RegisteredClientRepository.class, AuthorizationServerSettings.class })
|
||||
class OAuth2AuthorizationServerWebSecurityConfiguration {
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -37,7 +37,7 @@ import org.springframework.security.authentication.DefaultAuthenticationEventPub
|
||||
* @author Madhura Bhave
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@AutoConfiguration(before = UserDetailsServiceAutoConfiguration.class)
|
||||
@ConditionalOnClass(DefaultAuthenticationEventPublisher.class)
|
||||
@EnableConfigurationProperties(SecurityProperties.class)
|
||||
@Import({ SpringBootWebSecurityConfiguration.class, SecurityDataConfiguration.class })
|
||||
|
||||
@@ -34,18 +34,16 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*
|
||||
* @author Steve Riesenberg
|
||||
*/
|
||||
public class OAuth2AuthorizationServerPropertiesRegistrationAdapterTests {
|
||||
class OAuth2AuthorizationServerPropertiesRegistrationAdapterTests {
|
||||
|
||||
@Test
|
||||
void getRegisteredClientsWhenValidParametersShouldAdapt() {
|
||||
OAuth2AuthorizationServerProperties properties = new OAuth2AuthorizationServerProperties();
|
||||
OAuth2AuthorizationServerProperties.Client client = createClient();
|
||||
properties.getClient().put("foo", client);
|
||||
|
||||
List<RegisteredClient> registeredClients = OAuth2AuthorizationServerPropertiesRegistrationAdapter
|
||||
.getRegisteredClients(properties);
|
||||
assertThat(registeredClients).hasSize(1);
|
||||
|
||||
RegisteredClient registeredClient = registeredClients.get(0);
|
||||
assertThat(registeredClient.getClientId()).isEqualTo("foo");
|
||||
assertThat(registeredClient.getClientSecret()).isEqualTo("secret");
|
||||
@@ -56,13 +54,11 @@ public class OAuth2AuthorizationServerPropertiesRegistrationAdapterTests {
|
||||
assertThat(registeredClient.getRedirectUris()).containsExactly("https://example.com/redirect");
|
||||
assertThat(registeredClient.getPostLogoutRedirectUris()).containsExactly("https://example.com/logout");
|
||||
assertThat(registeredClient.getScopes()).containsExactly("user.read");
|
||||
|
||||
assertThat(registeredClient.getClientSettings().isRequireProofKey()).isTrue();
|
||||
assertThat(registeredClient.getClientSettings().isRequireAuthorizationConsent()).isTrue();
|
||||
assertThat(registeredClient.getClientSettings().getJwkSetUrl()).isEqualTo("https://example.com/jwks");
|
||||
assertThat(registeredClient.getClientSettings().getTokenEndpointAuthenticationSigningAlgorithm())
|
||||
.isEqualTo(SignatureAlgorithm.RS256);
|
||||
|
||||
assertThat(registeredClient.getTokenSettings().getAccessTokenFormat()).isEqualTo(OAuth2TokenFormat.REFERENCE);
|
||||
assertThat(registeredClient.getTokenSettings().getAccessTokenTimeToLive()).isEqualTo(Duration.ofSeconds(300));
|
||||
assertThat(registeredClient.getTokenSettings().getRefreshTokenTimeToLive()).isEqualTo(Duration.ofHours(24));
|
||||
@@ -77,7 +73,6 @@ public class OAuth2AuthorizationServerPropertiesRegistrationAdapterTests {
|
||||
client.setRequireAuthorizationConsent(true);
|
||||
client.setJwkSetUri("https://example.com/jwks");
|
||||
client.setTokenEndpointAuthenticationSigningAlgorithm("rs256");
|
||||
|
||||
OAuth2AuthorizationServerProperties.Registration registration = client.getRegistration();
|
||||
registration.setClientId("foo");
|
||||
registration.setClientSecret("secret");
|
||||
@@ -86,14 +81,12 @@ public class OAuth2AuthorizationServerPropertiesRegistrationAdapterTests {
|
||||
registration.getRedirectUris().add("https://example.com/redirect");
|
||||
registration.getPostLogoutRedirectUris().add("https://example.com/logout");
|
||||
registration.getScopes().add("user.read");
|
||||
|
||||
OAuth2AuthorizationServerProperties.Token token = client.getToken();
|
||||
token.setAccessTokenFormat("reference");
|
||||
token.setAccessTokenTimeToLive(Duration.ofSeconds(300));
|
||||
token.setRefreshTokenTimeToLive(Duration.ofHours(24));
|
||||
token.setReuseRefreshTokens(true);
|
||||
token.setIdTokenSignatureAlgorithm("rs512");
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,12 +27,11 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*
|
||||
* @author Steve Riesenberg
|
||||
*/
|
||||
public class OAuth2AuthorizationServerPropertiesSettingsAdapterTests {
|
||||
class OAuth2AuthorizationServerPropertiesSettingsAdapterTests {
|
||||
|
||||
@Test
|
||||
void getAuthorizationServerSettingsWhenValidParametersShouldAdapt() {
|
||||
OAuth2AuthorizationServerProperties properties = createAuthorizationServerProperties();
|
||||
|
||||
AuthorizationServerSettings settings = OAuth2AuthorizationServerPropertiesSettingsAdapter
|
||||
.getAuthorizationServerSettings(properties);
|
||||
assertThat(settings.getIssuer()).isEqualTo("https://example.com");
|
||||
@@ -49,14 +48,12 @@ public class OAuth2AuthorizationServerPropertiesSettingsAdapterTests {
|
||||
private OAuth2AuthorizationServerProperties createAuthorizationServerProperties() {
|
||||
OAuth2AuthorizationServerProperties properties = new OAuth2AuthorizationServerProperties();
|
||||
properties.setIssuer("https://example.com");
|
||||
|
||||
OAuth2AuthorizationServerProperties.Endpoint endpoints = properties.getEndpoint();
|
||||
endpoints.setAuthorizationUri("/authorize");
|
||||
endpoints.setTokenUri("/token");
|
||||
endpoints.setJwkSetUri("/jwks");
|
||||
endpoints.setTokenRevocationUri("/revoke");
|
||||
endpoints.setTokenIntrospectionUri("/introspect");
|
||||
|
||||
OAuth2AuthorizationServerProperties.OidcEndpoint oidc = endpoints.getOidc();
|
||||
oidc.setLogoutUri("/logout");
|
||||
oidc.setClientRegistrationUri("/register");
|
||||
|
||||
@@ -25,7 +25,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
*
|
||||
* @author Steve Riesenberg
|
||||
*/
|
||||
public class OAuth2AuthorizationServerPropertiesTests {
|
||||
class OAuth2AuthorizationServerPropertiesTests {
|
||||
|
||||
private final OAuth2AuthorizationServerProperties properties = new OAuth2AuthorizationServerProperties();
|
||||
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright 2012-2023 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.boot.autoconfigure.security.oauth2.server.servlet;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
||||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
|
||||
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
|
||||
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Test for {@link OAuth2AuthorizationServerAutoConfiguration}.
|
||||
*
|
||||
* @author Steve Riesenberg
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
class OAuth2AuthorizationServerAutoConfigurationTests {
|
||||
|
||||
private static final String PROPERTIES_PREFIX = "spring.security.oauth2.authorizationserver";
|
||||
|
||||
private static final String CLIENT_PREFIX = PROPERTIES_PREFIX + ".client";
|
||||
|
||||
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(OAuth2AuthorizationServerAutoConfiguration.class,
|
||||
OAuth2AuthorizationServerJwtAutoConfiguration.class, SecurityAutoConfiguration.class,
|
||||
UserDetailsServiceAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void autoConfigurationConditionalOnClassOauth2Authorization() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader(OAuth2Authorization.class))
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(OAuth2AuthorizationServerAutoConfiguration.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void autoConfigurationDoesNotCauseUserDetailsServiceToBackOff() {
|
||||
this.contextRunner.run((context) -> assertThat(context).hasBean("inMemoryUserDetailsManager"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void registeredClientRepositoryBeanShouldNotBeCreatedWhenPropertiesAbsent() {
|
||||
this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(RegisteredClientRepository.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void registeredClientRepositoryBeanShouldBeCreatedWhenPropertiesPresent() {
|
||||
this.contextRunner
|
||||
.withPropertyValues(CLIENT_PREFIX + ".foo.registration.client-id=abcd",
|
||||
CLIENT_PREFIX + ".foo.registration.client-secret=secret",
|
||||
CLIENT_PREFIX + ".foo.registration.client-authentication-methods=client_secret_basic",
|
||||
CLIENT_PREFIX + ".foo.registration.authorization-grant-types=client_credentials",
|
||||
CLIENT_PREFIX + ".foo.registration.scopes=test")
|
||||
.run((context) -> {
|
||||
RegisteredClientRepository registeredClientRepository = context
|
||||
.getBean(RegisteredClientRepository.class);
|
||||
RegisteredClient registeredClient = registeredClientRepository.findById("foo");
|
||||
assertThat(registeredClient).isNotNull();
|
||||
assertThat(registeredClient.getClientId()).isEqualTo("abcd");
|
||||
assertThat(registeredClient.getClientSecret()).isEqualTo("secret");
|
||||
assertThat(registeredClient.getClientAuthenticationMethods())
|
||||
.containsOnly(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
|
||||
assertThat(registeredClient.getAuthorizationGrantTypes())
|
||||
.containsOnly(AuthorizationGrantType.CLIENT_CREDENTIALS);
|
||||
assertThat(registeredClient.getScopes()).containsOnly("test");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void registeredClientRepositoryBacksOffWhenRegisteredClientRepositoryBeanPresent() {
|
||||
this.contextRunner.withUserConfiguration(TestRegisteredClientRepositoryConfiguration.class)
|
||||
.withPropertyValues(CLIENT_PREFIX + ".foo.registration.client-id=abcd",
|
||||
CLIENT_PREFIX + ".foo.registration.client-secret=secret",
|
||||
CLIENT_PREFIX + ".foo.registration.client-authentication-methods=client_secret_basic",
|
||||
CLIENT_PREFIX + ".foo.registration.authorization-grant-types=client_credentials",
|
||||
CLIENT_PREFIX + ".foo.registration.scope=test")
|
||||
.run((context) -> {
|
||||
RegisteredClientRepository registeredClientRepository = context
|
||||
.getBean(RegisteredClientRepository.class);
|
||||
RegisteredClient registeredClient = registeredClientRepository.findById("test");
|
||||
assertThat(registeredClient).isNotNull();
|
||||
assertThat(registeredClient.getClientId()).isEqualTo("abcd");
|
||||
assertThat(registeredClient.getClientSecret()).isEqualTo("secret");
|
||||
assertThat(registeredClient.getClientAuthenticationMethods())
|
||||
.containsOnly(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
|
||||
assertThat(registeredClient.getAuthorizationGrantTypes())
|
||||
.containsOnly(AuthorizationGrantType.CLIENT_CREDENTIALS);
|
||||
assertThat(registeredClient.getScopes()).containsOnly("test");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void authorizationServerSettingsBeanShouldBeCreatedWhenPropertiesAbsent() {
|
||||
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(AuthorizationServerSettings.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void authorizationServerSettingsBeanShouldBeCreatedWhenPropertiesPresent() {
|
||||
this.contextRunner
|
||||
.withPropertyValues(PROPERTIES_PREFIX + ".issuer=https://example.com",
|
||||
PROPERTIES_PREFIX + ".endpoint.authorization-uri=/authorize",
|
||||
PROPERTIES_PREFIX + ".endpoint.token-uri=/token", PROPERTIES_PREFIX + ".endpoint.jwk-set-uri=/jwks",
|
||||
PROPERTIES_PREFIX + ".endpoint.token-revocation-uri=/revoke",
|
||||
PROPERTIES_PREFIX + ".endpoint.token-introspection-uri=/introspect",
|
||||
PROPERTIES_PREFIX + ".endpoint.oidc.logout-uri=/logout",
|
||||
PROPERTIES_PREFIX + ".endpoint.oidc.client-registration-uri=/register",
|
||||
PROPERTIES_PREFIX + ".endpoint.oidc.user-info-uri=/user")
|
||||
.run((context) -> {
|
||||
AuthorizationServerSettings settings = context.getBean(AuthorizationServerSettings.class);
|
||||
assertThat(settings.getIssuer()).isEqualTo("https://example.com");
|
||||
assertThat(settings.getAuthorizationEndpoint()).isEqualTo("/authorize");
|
||||
assertThat(settings.getTokenEndpoint()).isEqualTo("/token");
|
||||
assertThat(settings.getJwkSetEndpoint()).isEqualTo("/jwks");
|
||||
assertThat(settings.getTokenRevocationEndpoint()).isEqualTo("/revoke");
|
||||
assertThat(settings.getTokenIntrospectionEndpoint()).isEqualTo("/introspect");
|
||||
assertThat(settings.getOidcLogoutEndpoint()).isEqualTo("/logout");
|
||||
assertThat(settings.getOidcClientRegistrationEndpoint()).isEqualTo("/register");
|
||||
assertThat(settings.getOidcUserInfoEndpoint()).isEqualTo("/user");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void authorizationServerSettingsBacksOffWhenAuthorizationServerSettingsBeanPresent() {
|
||||
this.contextRunner.withUserConfiguration(TestAuthorizationServerSettingsConfiguration.class)
|
||||
.withPropertyValues(PROPERTIES_PREFIX + ".issuer=https://test.com")
|
||||
.run((context) -> {
|
||||
AuthorizationServerSettings settings = context.getBean(AuthorizationServerSettings.class);
|
||||
assertThat(settings.getIssuer()).isEqualTo("https://example.com");
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class TestRegisteredClientRepositoryConfiguration {
|
||||
|
||||
@Bean
|
||||
RegisteredClientRepository registeredClientRepository() {
|
||||
RegisteredClient registeredClient = RegisteredClient.withId("test")
|
||||
.clientId("abcd")
|
||||
.clientSecret("secret")
|
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
|
||||
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
|
||||
.scope("test")
|
||||
.build();
|
||||
return new InMemoryRegisteredClientRepository(registeredClient);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class TestAuthorizationServerSettingsConfiguration {
|
||||
|
||||
@Bean
|
||||
AuthorizationServerSettings authorizationServerSettings() {
|
||||
return AuthorizationServerSettings.builder().issuer("https://example.com").build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2012-2023 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.boot.autoconfigure.security.oauth2.server.servlet;
|
||||
|
||||
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
|
||||
import com.nimbusds.jose.jwk.source.JWKSource;
|
||||
import com.nimbusds.jose.proc.SecurityContext;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link OAuth2AuthorizationServerJwtAutoConfiguration}.
|
||||
*
|
||||
* @author Steve Riesenberg
|
||||
*/
|
||||
class OAuth2AuthorizationServerJwtAutoConfigurationTests {
|
||||
|
||||
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(OAuth2AuthorizationServerJwtAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void autoConfigurationConditionalOnClassOauth2Authorization() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader(OAuth2Authorization.class))
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(OAuth2AuthorizationServerJwtAutoConfiguration.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void jwtDecoderConditionalOnClassJwtDecoder() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader(JwtDecoder.class))
|
||||
.run((context) -> assertThat(context).doesNotHaveBean("jwtDecoder"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void jwtConfigurationConfiguresJwtDecoderWithGeneratedKey() {
|
||||
this.contextRunner.run((context) -> {
|
||||
assertThat(context).hasBean("jwtDecoder");
|
||||
assertThat(context.getBean("jwtDecoder")).isInstanceOf(NimbusJwtDecoder.class);
|
||||
assertThat(context).hasBean("jwkSource");
|
||||
assertThat(context.getBean("jwkSource")).isInstanceOf(ImmutableJWKSet.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void jwtDecoderBacksOffWhenBeanPresent() {
|
||||
this.contextRunner.withUserConfiguration(TestJwtDecoderConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasBean("jwtDecoder");
|
||||
assertThat(context.getBean("jwtDecoder")).isNotInstanceOf(NimbusJwtDecoder.class);
|
||||
assertThat(context).hasBean("jwkSource");
|
||||
assertThat(context.getBean("jwkSource")).isInstanceOf(ImmutableJWKSet.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void jwkSourceBacksOffWhenBeanPresent() {
|
||||
this.contextRunner.withUserConfiguration(TestJwkSourceConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasBean("jwtDecoder");
|
||||
assertThat(context.getBean("jwtDecoder")).isInstanceOf(NimbusJwtDecoder.class);
|
||||
assertThat(context).hasBean("jwkSource");
|
||||
assertThat(context.getBean("jwkSource")).isNotInstanceOf(ImmutableJWKSet.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class TestJwtDecoderConfiguration {
|
||||
|
||||
@Bean
|
||||
JwtDecoder jwtDecoder() {
|
||||
return (token) -> null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class TestJwkSourceConfiguration {
|
||||
|
||||
@Bean
|
||||
JWKSource<SecurityContext> jwkSource() {
|
||||
return (jwkSelector, context) -> null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2023 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.boot.autoconfigure.security.oauth2.server.servlet;
|
||||
|
||||
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
|
||||
import com.nimbusds.jose.jwk.source.JWKSource;
|
||||
import com.nimbusds.jose.proc.SecurityContext;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link OAuth2AuthorizationServerJwtConfiguration}.
|
||||
*
|
||||
* @author Steve Riesenberg
|
||||
*/
|
||||
public class OAuth2AuthorizationServerJwtConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
|
||||
|
||||
@Test
|
||||
void jwtConfigurationConfiguresJwtDecoderWithGeneratedKey() {
|
||||
// @formatter:off
|
||||
this.contextRunner.withUserConfiguration(TestJwtConfiguration.class)
|
||||
.run((context) -> {
|
||||
assertThat(context).hasBean("jwtDecoder");
|
||||
assertThat(context).hasBean("jwkSource");
|
||||
|
||||
assertThat(context.getBean("jwtDecoder")).isInstanceOf(NimbusJwtDecoder.class);
|
||||
assertThat(context.getBean("jwkSource")).isInstanceOf(ImmutableJWKSet.class);
|
||||
});
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
void jwtDecoderBacksOffWhenBeanPresent() {
|
||||
// @formatter:off
|
||||
this.contextRunner.withUserConfiguration(TestJwtDecoderConfiguration.class, TestJwtConfiguration.class)
|
||||
.run((context) -> {
|
||||
assertThat(context).hasBean("jwtDecoder");
|
||||
assertThat(context).hasBean("jwkSource");
|
||||
|
||||
assertThat(context.getBean("jwtDecoder")).isNotInstanceOf(NimbusJwtDecoder.class);
|
||||
assertThat(context.getBean("jwkSource")).isInstanceOf(ImmutableJWKSet.class);
|
||||
});
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
void jwkSourceBacksOffWhenBeanPresent() {
|
||||
// @formatter:off
|
||||
this.contextRunner.withUserConfiguration(TestJwkSourceConfiguration.class, TestJwtConfiguration.class)
|
||||
.run((context) -> {
|
||||
assertThat(context).hasBean("jwtDecoder");
|
||||
assertThat(context).hasBean("jwkSource");
|
||||
|
||||
assertThat(context.getBean("jwtDecoder")).isInstanceOf(NimbusJwtDecoder.class);
|
||||
assertThat(context.getBean("jwkSource")).isNotInstanceOf(ImmutableJWKSet.class);
|
||||
});
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(OAuth2AuthorizationServerJwtConfiguration.class)
|
||||
static class TestJwtConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class TestJwtDecoderConfiguration {
|
||||
|
||||
@Bean
|
||||
JwtDecoder jwtDecoder() {
|
||||
return (token) -> null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class TestJwkSourceConfiguration {
|
||||
|
||||
@Bean
|
||||
JWKSource<SecurityContext> jwkSource() {
|
||||
return (jwkSelector, context) -> null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2023 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.boot.autoconfigure.security.oauth2.server.servlet;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
||||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
|
||||
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
|
||||
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Steve Riesenberg
|
||||
*/
|
||||
public class OAuth2AuthorizationServerPropertiesConfigurationTests {
|
||||
|
||||
private static final String PROPERTIES_PREFIX = "spring.security.oauth2.authorizationserver";
|
||||
|
||||
private static final String CLIENT_PREFIX = PROPERTIES_PREFIX + ".client";
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
|
||||
|
||||
@Test
|
||||
void registeredClientRepositoryBeanShouldNotBeCreatedWhenPropertiesAbsent() {
|
||||
// @formatter:off
|
||||
this.contextRunner.withUserConfiguration(TestOAuth2AuthorizationServerConfiguration.class)
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(RegisteredClientRepository.class));
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
void registeredClientRepositoryBeanShouldBeCreatedWhenPropertiesPresent() {
|
||||
// @formatter:off
|
||||
this.contextRunner.withUserConfiguration(TestOAuth2AuthorizationServerConfiguration.class)
|
||||
.withPropertyValues(
|
||||
CLIENT_PREFIX + ".foo.registration.client-id=abcd",
|
||||
CLIENT_PREFIX + ".foo.registration.client-secret=secret",
|
||||
CLIENT_PREFIX + ".foo.registration.client-authentication-methods=client_secret_basic",
|
||||
CLIENT_PREFIX + ".foo.registration.authorization-grant-types=client_credentials",
|
||||
CLIENT_PREFIX + ".foo.registration.scopes=test")
|
||||
.run((context) -> {
|
||||
RegisteredClientRepository registeredClientRepository = context.getBean(RegisteredClientRepository.class);
|
||||
RegisteredClient registeredClient = registeredClientRepository.findById("foo");
|
||||
assertThat(registeredClient).isNotNull();
|
||||
assertThat(registeredClient.getClientId()).isEqualTo("abcd");
|
||||
assertThat(registeredClient.getClientSecret()).isEqualTo("secret");
|
||||
assertThat(registeredClient.getClientAuthenticationMethods())
|
||||
.containsOnly(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
|
||||
assertThat(registeredClient.getAuthorizationGrantTypes())
|
||||
.containsOnly(AuthorizationGrantType.CLIENT_CREDENTIALS);
|
||||
assertThat(registeredClient.getScopes()).containsOnly("test");
|
||||
});
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
void registeredClientRepositoryBacksOffWhenRegisteredClientRepositoryBeanPresent() {
|
||||
// @formatter:off
|
||||
this.contextRunner.withUserConfiguration(TestRegisteredClientRepositoryConfiguration.class,
|
||||
TestOAuth2AuthorizationServerConfiguration.class)
|
||||
.withPropertyValues(
|
||||
CLIENT_PREFIX + ".foo.registration.client-id=abcd",
|
||||
CLIENT_PREFIX + ".foo.registration.client-secret=secret",
|
||||
CLIENT_PREFIX + ".foo.registration.client-authentication-methods=client_secret_basic",
|
||||
CLIENT_PREFIX + ".foo.registration.authorization-grant-types=client_credentials",
|
||||
CLIENT_PREFIX + ".foo.registration.scope=test")
|
||||
.run((context) -> {
|
||||
RegisteredClientRepository registeredClientRepository = context.getBean(RegisteredClientRepository.class);
|
||||
RegisteredClient registeredClient = registeredClientRepository.findById("test");
|
||||
assertThat(registeredClient).isNotNull();
|
||||
assertThat(registeredClient.getClientId()).isEqualTo("abcd");
|
||||
assertThat(registeredClient.getClientSecret()).isEqualTo("secret");
|
||||
assertThat(registeredClient.getClientAuthenticationMethods())
|
||||
.containsOnly(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
|
||||
assertThat(registeredClient.getAuthorizationGrantTypes())
|
||||
.containsOnly(AuthorizationGrantType.CLIENT_CREDENTIALS);
|
||||
assertThat(registeredClient.getScopes()).containsOnly("test");
|
||||
});
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
void authorizationServerSettingsBeanShouldBeCreatedWhenPropertiesAbsent() {
|
||||
// @formatter:off
|
||||
this.contextRunner.withUserConfiguration(TestOAuth2AuthorizationServerConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(AuthorizationServerSettings.class));
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
void authorizationServerSettingsBeanShouldBeCreatedWhenPropertiesPresent() {
|
||||
// @formatter:off
|
||||
this.contextRunner.withUserConfiguration(TestOAuth2AuthorizationServerConfiguration.class)
|
||||
.withPropertyValues(
|
||||
PROPERTIES_PREFIX + ".issuer=https://example.com",
|
||||
PROPERTIES_PREFIX + ".endpoint.authorization-uri=/authorize",
|
||||
PROPERTIES_PREFIX + ".endpoint.token-uri=/token",
|
||||
PROPERTIES_PREFIX + ".endpoint.jwk-set-uri=/jwks",
|
||||
PROPERTIES_PREFIX + ".endpoint.token-revocation-uri=/revoke",
|
||||
PROPERTIES_PREFIX + ".endpoint.token-introspection-uri=/introspect",
|
||||
PROPERTIES_PREFIX + ".endpoint.oidc.logout-uri=/logout",
|
||||
PROPERTIES_PREFIX + ".endpoint.oidc.client-registration-uri=/register",
|
||||
PROPERTIES_PREFIX + ".endpoint.oidc.user-info-uri=/user")
|
||||
.run((context) -> {
|
||||
AuthorizationServerSettings settings = context.getBean(AuthorizationServerSettings.class);
|
||||
assertThat(settings.getIssuer()).isEqualTo("https://example.com");
|
||||
assertThat(settings.getAuthorizationEndpoint()).isEqualTo("/authorize");
|
||||
assertThat(settings.getTokenEndpoint()).isEqualTo("/token");
|
||||
assertThat(settings.getJwkSetEndpoint()).isEqualTo("/jwks");
|
||||
assertThat(settings.getTokenRevocationEndpoint()).isEqualTo("/revoke");
|
||||
assertThat(settings.getTokenIntrospectionEndpoint()).isEqualTo("/introspect");
|
||||
assertThat(settings.getOidcLogoutEndpoint()).isEqualTo("/logout");
|
||||
assertThat(settings.getOidcClientRegistrationEndpoint()).isEqualTo("/register");
|
||||
assertThat(settings.getOidcUserInfoEndpoint()).isEqualTo("/user");
|
||||
});
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
void authorizationServerSettingsBacksOffWhenAuthorizationServerSettingsBeanPresent() {
|
||||
// @formatter:off
|
||||
this.contextRunner.withUserConfiguration(TestAuthorizationServerSettingsConfiguration.class,
|
||||
TestOAuth2AuthorizationServerConfiguration.class)
|
||||
.withPropertyValues(PROPERTIES_PREFIX + ".issuer=https://test.com")
|
||||
.run((context) -> {
|
||||
AuthorizationServerSettings settings = context.getBean(AuthorizationServerSettings.class);
|
||||
assertThat(settings.getIssuer()).isEqualTo("https://example.com");
|
||||
});
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@Import({ OAuth2AuthorizationServerPropertiesConfiguration.class })
|
||||
static class TestOAuth2AuthorizationServerConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class TestRegisteredClientRepositoryConfiguration {
|
||||
|
||||
@Bean
|
||||
RegisteredClientRepository registeredClientRepository() {
|
||||
RegisteredClient registeredClient = RegisteredClient.withId("test")
|
||||
.clientId("abcd")
|
||||
.clientSecret("secret")
|
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
|
||||
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
|
||||
.scope("test")
|
||||
.build();
|
||||
return new InMemoryRegisteredClientRepository(registeredClient);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class TestAuthorizationServerSettingsConfiguration {
|
||||
|
||||
@Bean
|
||||
AuthorizationServerSettings authorizationServerSettings() {
|
||||
return AuthorizationServerSettings.builder().issuer("https://example.com").build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,8 +21,8 @@ import java.util.List;
|
||||
import jakarta.servlet.Filter;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
@@ -31,10 +31,16 @@ import org.springframework.security.config.BeanIds;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
||||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
|
||||
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
|
||||
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
|
||||
import org.springframework.security.oauth2.server.authorization.oidc.web.OidcClientRegistrationEndpointFilter;
|
||||
import org.springframework.security.oauth2.server.authorization.oidc.web.OidcProviderConfigurationEndpointFilter;
|
||||
import org.springframework.security.oauth2.server.authorization.oidc.web.OidcUserInfoEndpointFilter;
|
||||
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
|
||||
import org.springframework.security.oauth2.server.authorization.web.OAuth2AuthorizationEndpointFilter;
|
||||
import org.springframework.security.oauth2.server.authorization.web.OAuth2AuthorizationServerMetadataEndpointFilter;
|
||||
import org.springframework.security.oauth2.server.authorization.web.OAuth2TokenEndpointFilter;
|
||||
@@ -49,74 +55,69 @@ import org.springframework.security.web.authentication.ui.DefaultLoginPageGenera
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link OAuth2AuthorizationServerWebSecurityConfiguration}.
|
||||
*
|
||||
* @author Steve Riesenberg
|
||||
*/
|
||||
public class OAuth2AuthorizationServerWebSecurityConfigurationTests {
|
||||
class OAuth2AuthorizationServerWebSecurityConfigurationTests {
|
||||
|
||||
private static final String PROPERTIES_PREFIX = "spring.security.oauth2.authorizationserver";
|
||||
|
||||
private static final String CLIENT_PREFIX = PROPERTIES_PREFIX + ".client";
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
|
||||
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner();
|
||||
|
||||
@Test
|
||||
void webSecurityConfigurationConfiguresAuthorizationServerWithFormLogin() {
|
||||
// @formatter:off
|
||||
this.contextRunner.withUserConfiguration(TestOAuth2AuthorizationServerConfiguration.class)
|
||||
.withPropertyValues(
|
||||
CLIENT_PREFIX + ".foo.registration.client-id=abcd",
|
||||
CLIENT_PREFIX + ".foo.registration.client-secret=secret",
|
||||
CLIENT_PREFIX + ".foo.registration.client-authentication-methods=client_secret_basic",
|
||||
CLIENT_PREFIX + ".foo.registration.authorization-grant-types=client_credentials",
|
||||
CLIENT_PREFIX + ".foo.registration.scopes=test")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasBean("authorizationServerSecurityFilterChain");
|
||||
assertThat(context).hasBean("defaultSecurityFilterChain");
|
||||
assertThat(context).hasBean("registeredClientRepository");
|
||||
assertThat(context).hasBean("authorizationServerSettings");
|
||||
|
||||
assertThat(findFilter(context, OAuth2AuthorizationEndpointFilter.class, 0)).isNotNull();
|
||||
assertThat(findFilter(context, OAuth2TokenEndpointFilter.class, 0)).isNotNull();
|
||||
assertThat(findFilter(context, OAuth2TokenIntrospectionEndpointFilter.class, 0)).isNotNull();
|
||||
assertThat(findFilter(context, OAuth2TokenRevocationEndpointFilter.class, 0)).isNotNull();
|
||||
assertThat(findFilter(context, OAuth2AuthorizationServerMetadataEndpointFilter.class, 0)).isNotNull();
|
||||
assertThat(findFilter(context, OidcProviderConfigurationEndpointFilter.class, 0)).isNotNull();
|
||||
assertThat(findFilter(context, OidcUserInfoEndpointFilter.class, 0)).isNotNull();
|
||||
assertThat(findFilter(context, BearerTokenAuthenticationFilter.class, 0)).isNotNull();
|
||||
assertThat(findFilter(context, OidcClientRegistrationEndpointFilter.class, 0)).isNull();
|
||||
assertThat(findFilter(context, UsernamePasswordAuthenticationFilter.class, 0)).isNull();
|
||||
assertThat(findFilter(context, DefaultLoginPageGeneratingFilter.class, 1)).isNotNull();
|
||||
assertThat(findFilter(context, UsernamePasswordAuthenticationFilter.class, 1)).isNotNull();
|
||||
});
|
||||
// @formatter:on
|
||||
.withPropertyValues(CLIENT_PREFIX + ".foo.registration.client-id=abcd",
|
||||
CLIENT_PREFIX + ".foo.registration.client-secret=secret",
|
||||
CLIENT_PREFIX + ".foo.registration.client-authentication-methods=client_secret_basic",
|
||||
CLIENT_PREFIX + ".foo.registration.authorization-grant-types=client_credentials",
|
||||
CLIENT_PREFIX + ".foo.registration.scopes=test")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasBean("authorizationServerSecurityFilterChain");
|
||||
assertThat(context).hasBean("defaultSecurityFilterChain");
|
||||
assertThat(context).hasBean("registeredClientRepository");
|
||||
assertThat(context).hasBean("authorizationServerSettings");
|
||||
assertThat(findFilter(context, OAuth2AuthorizationEndpointFilter.class, 0)).isNotNull();
|
||||
assertThat(findFilter(context, OAuth2TokenEndpointFilter.class, 0)).isNotNull();
|
||||
assertThat(findFilter(context, OAuth2TokenIntrospectionEndpointFilter.class, 0)).isNotNull();
|
||||
assertThat(findFilter(context, OAuth2TokenRevocationEndpointFilter.class, 0)).isNotNull();
|
||||
assertThat(findFilter(context, OAuth2AuthorizationServerMetadataEndpointFilter.class, 0)).isNotNull();
|
||||
assertThat(findFilter(context, OidcProviderConfigurationEndpointFilter.class, 0)).isNotNull();
|
||||
assertThat(findFilter(context, OidcUserInfoEndpointFilter.class, 0)).isNotNull();
|
||||
assertThat(findFilter(context, BearerTokenAuthenticationFilter.class, 0)).isNotNull();
|
||||
assertThat(findFilter(context, OidcClientRegistrationEndpointFilter.class, 0)).isNull();
|
||||
assertThat(findFilter(context, UsernamePasswordAuthenticationFilter.class, 0)).isNull();
|
||||
assertThat(findFilter(context, DefaultLoginPageGeneratingFilter.class, 1)).isNotNull();
|
||||
assertThat(findFilter(context, UsernamePasswordAuthenticationFilter.class, 1)).isNotNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void securityFilterChainsBackOffWhenSecurityFilterChainBeanPresent() {
|
||||
// @formatter:off
|
||||
this.contextRunner.withUserConfiguration(TestSecurityFilterChainConfiguration.class,
|
||||
TestOAuth2AuthorizationServerConfiguration.class)
|
||||
.withPropertyValues(
|
||||
CLIENT_PREFIX + ".foo.registration.client-id=abcd",
|
||||
CLIENT_PREFIX + ".foo.registration.client-secret=secret",
|
||||
CLIENT_PREFIX + ".foo.registration.client-authentication-methods=client_secret_basic",
|
||||
CLIENT_PREFIX + ".foo.registration.authorization-grant-types=client_credentials",
|
||||
CLIENT_PREFIX + ".foo.registration.scopes=test")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasBean("authServerSecurityFilterChain");
|
||||
assertThat(context).doesNotHaveBean("authorizationServerSecurityFilterChain");
|
||||
assertThat(context).hasBean("securityFilterChain");
|
||||
assertThat(context).doesNotHaveBean("defaultSecurityFilterChain");
|
||||
assertThat(context).hasBean("registeredClientRepository");
|
||||
assertThat(context).hasBean("authorizationServerSettings");
|
||||
|
||||
assertThat(findFilter(context, BearerTokenAuthenticationFilter.class, 0)).isNull();
|
||||
assertThat(findFilter(context, UsernamePasswordAuthenticationFilter.class, 1)).isNull();
|
||||
});
|
||||
// @formatter:on
|
||||
this.contextRunner
|
||||
.withUserConfiguration(TestSecurityFilterChainConfiguration.class,
|
||||
TestOAuth2AuthorizationServerConfiguration.class)
|
||||
.withPropertyValues(CLIENT_PREFIX + ".foo.registration.client-id=abcd",
|
||||
CLIENT_PREFIX + ".foo.registration.client-secret=secret",
|
||||
CLIENT_PREFIX + ".foo.registration.client-authentication-methods=client_secret_basic",
|
||||
CLIENT_PREFIX + ".foo.registration.authorization-grant-types=client_credentials",
|
||||
CLIENT_PREFIX + ".foo.registration.scopes=test")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasBean("authServerSecurityFilterChain");
|
||||
assertThat(context).doesNotHaveBean("authorizationServerSecurityFilterChain");
|
||||
assertThat(context).hasBean("securityFilterChain");
|
||||
assertThat(context).doesNotHaveBean("defaultSecurityFilterChain");
|
||||
assertThat(context).hasBean("registeredClientRepository");
|
||||
assertThat(context).hasBean("authorizationServerSettings");
|
||||
assertThat(findFilter(context, BearerTokenAuthenticationFilter.class, 0)).isNull();
|
||||
assertThat(findFilter(context, UsernamePasswordAuthenticationFilter.class, 1)).isNull();
|
||||
});
|
||||
}
|
||||
|
||||
private Filter findFilter(AssertableApplicationContext context, Class<? extends Filter> filter,
|
||||
private Filter findFilter(AssertableWebApplicationContext context, Class<? extends Filter> filter,
|
||||
int filterChainIndex) {
|
||||
FilterChainProxy filterChain = (FilterChainProxy) context.getBean(BeanIds.SPRING_SECURITY_FILTER_CHAIN);
|
||||
List<SecurityFilterChain> filterChains = filterChain.getFilterChains();
|
||||
@@ -126,12 +127,35 @@ public class OAuth2AuthorizationServerWebSecurityConfigurationTests {
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@Import({ OAuth2AuthorizationServerPropertiesConfiguration.class,
|
||||
OAuth2AuthorizationServerWebSecurityConfiguration.class, OAuth2AuthorizationServerJwtConfiguration.class })
|
||||
@Import({ TestRegisteredClientRepositoryConfiguration.class,
|
||||
OAuth2AuthorizationServerWebSecurityConfiguration.class,
|
||||
OAuth2AuthorizationServerJwtAutoConfiguration.class })
|
||||
static class TestOAuth2AuthorizationServerConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class TestRegisteredClientRepositoryConfiguration {
|
||||
|
||||
@Bean
|
||||
RegisteredClientRepository registeredClientRepository() {
|
||||
RegisteredClient registeredClient = RegisteredClient.withId("test")
|
||||
.clientId("abcd")
|
||||
.clientSecret("secret")
|
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
|
||||
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
|
||||
.scope("test")
|
||||
.build();
|
||||
return new InMemoryRegisteredClientRepository(registeredClient);
|
||||
}
|
||||
|
||||
@Bean
|
||||
AuthorizationServerSettings authorizationServerSettings() {
|
||||
return AuthorizationServerSettings.builder().issuer("https://example.com").build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
static class TestSecurityFilterChainConfiguration {
|
||||
|
||||
@@ -1336,7 +1336,7 @@ bom {
|
||||
]
|
||||
}
|
||||
}
|
||||
library("Spring Authorization Server", "1.1.0-M1") {
|
||||
library("Spring Authorization Server", "1.1.0-M2") {
|
||||
group("org.springframework.security") {
|
||||
modules = [
|
||||
"spring-security-oauth2-authorization-server"
|
||||
|
||||
@@ -102,18 +102,14 @@ class SampleOAuth2AuthorizationServerApplicationTests {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setBasicAuth("messaging-client", "secret");
|
||||
HttpEntity<Object> request = new HttpEntity<>(headers);
|
||||
// @formatter:off
|
||||
String requestUri = UriComponentsBuilder.fromUriString("/token")
|
||||
.queryParam(OAuth2ParameterNames.CLIENT_ID, "messaging-client")
|
||||
.queryParam(OAuth2ParameterNames.GRANT_TYPE, AuthorizationGrantType.CLIENT_CREDENTIALS.getValue())
|
||||
.queryParam(OAuth2ParameterNames.SCOPE, "message.read+message.write")
|
||||
.toUriString();
|
||||
// @formatter:on
|
||||
|
||||
.queryParam(OAuth2ParameterNames.CLIENT_ID, "messaging-client")
|
||||
.queryParam(OAuth2ParameterNames.GRANT_TYPE, AuthorizationGrantType.CLIENT_CREDENTIALS.getValue())
|
||||
.queryParam(OAuth2ParameterNames.SCOPE, "message.read+message.write")
|
||||
.toUriString();
|
||||
ResponseEntity<Map<String, Object>> entity = this.restTemplate.exchange(requestUri, HttpMethod.POST, request,
|
||||
MAP_TYPE_REFERENCE);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
||||
Map<String, Object> tokenResponse = Objects.requireNonNull(entity.getBody());
|
||||
assertThat(tokenResponse.get(OAuth2ParameterNames.ACCESS_TOKEN)).isNotNull();
|
||||
assertThat(tokenResponse.get(OAuth2ParameterNames.EXPIRES_IN)).isNotNull();
|
||||
|
||||
Reference in New Issue
Block a user