|
|
|
|
@ -24,7 +24,6 @@ import java.util.Base64;
@@ -24,7 +24,6 @@ import java.util.Base64;
|
|
|
|
|
import java.util.HashSet; |
|
|
|
|
import java.util.List; |
|
|
|
|
import java.util.Set; |
|
|
|
|
import java.util.function.Consumer; |
|
|
|
|
|
|
|
|
|
import com.nimbusds.jose.jwk.JWKSet; |
|
|
|
|
import com.nimbusds.jose.jwk.source.JWKSource; |
|
|
|
|
@ -37,7 +36,6 @@ import org.junit.Test;
@@ -37,7 +36,6 @@ import org.junit.Test;
|
|
|
|
|
|
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
|
import org.springframework.context.annotation.Bean; |
|
|
|
|
import org.springframework.context.annotation.Configuration; |
|
|
|
|
import org.springframework.context.annotation.Import; |
|
|
|
|
import org.springframework.http.HttpHeaders; |
|
|
|
|
import org.springframework.http.HttpStatus; |
|
|
|
|
@ -71,7 +69,6 @@ import org.springframework.security.oauth2.jwt.NimbusJwtEncoder;
@@ -71,7 +69,6 @@ import org.springframework.security.oauth2.jwt.NimbusJwtEncoder;
|
|
|
|
|
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService; |
|
|
|
|
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; |
|
|
|
|
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationCode; |
|
|
|
|
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationServerMetadataClaimNames; |
|
|
|
|
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; |
|
|
|
|
import org.springframework.security.oauth2.server.authorization.OAuth2TokenType; |
|
|
|
|
import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations; |
|
|
|
|
@ -82,8 +79,6 @@ import org.springframework.security.oauth2.server.authorization.client.Registere
@@ -82,8 +79,6 @@ import org.springframework.security.oauth2.server.authorization.client.Registere
|
|
|
|
|
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients; |
|
|
|
|
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; |
|
|
|
|
import org.springframework.security.oauth2.server.authorization.jackson2.TestingAuthenticationTokenMixin; |
|
|
|
|
import org.springframework.security.oauth2.server.authorization.oidc.OidcProviderConfiguration; |
|
|
|
|
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings; |
|
|
|
|
import org.springframework.security.oauth2.server.authorization.test.SpringTestRule; |
|
|
|
|
import org.springframework.security.oauth2.server.authorization.token.DelegatingOAuth2TokenGenerator; |
|
|
|
|
import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext; |
|
|
|
|
@ -103,9 +98,7 @@ import org.springframework.web.util.UriComponents;
@@ -103,9 +98,7 @@ import org.springframework.web.util.UriComponents;
|
|
|
|
|
import org.springframework.web.util.UriComponentsBuilder; |
|
|
|
|
|
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat; |
|
|
|
|
import static org.assertj.core.api.Assertions.assertThatThrownBy; |
|
|
|
|
import static org.hamcrest.CoreMatchers.containsString; |
|
|
|
|
import static org.hamcrest.CoreMatchers.hasItems; |
|
|
|
|
import static org.mockito.ArgumentMatchers.any; |
|
|
|
|
import static org.mockito.Mockito.spy; |
|
|
|
|
import static org.mockito.Mockito.times; |
|
|
|
|
@ -126,8 +119,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@@ -126,8 +119,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|
|
|
|
public class OidcTests { |
|
|
|
|
private static final String DEFAULT_AUTHORIZATION_ENDPOINT_URI = "/oauth2/authorize"; |
|
|
|
|
private static final String DEFAULT_TOKEN_ENDPOINT_URI = "/oauth2/token"; |
|
|
|
|
private static final String DEFAULT_OIDC_PROVIDER_CONFIGURATION_ENDPOINT_URI = "/.well-known/openid-configuration"; |
|
|
|
|
private static final String ISSUER_URL = "https://example.com/issuer1"; |
|
|
|
|
private static final String AUTHORITIES_CLAIM = "authorities"; |
|
|
|
|
private static final OAuth2TokenType AUTHORIZATION_CODE_TOKEN_TYPE = new OAuth2TokenType(OAuth2ParameterNames.CODE); |
|
|
|
|
private static EmbeddedDatabase db; |
|
|
|
|
@ -182,85 +173,6 @@ public class OidcTests {
@@ -182,85 +173,6 @@ public class OidcTests {
|
|
|
|
|
db.shutdown(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
public void requestWhenConfigurationRequestAndIssuerSetThenReturnConfigurationResponse() throws Exception { |
|
|
|
|
this.spring.register(AuthorizationServerConfigurationWithIssuer.class).autowire(); |
|
|
|
|
|
|
|
|
|
this.mvc.perform(get(DEFAULT_OIDC_PROVIDER_CONFIGURATION_ENDPOINT_URI)) |
|
|
|
|
.andExpect(status().is2xxSuccessful()) |
|
|
|
|
.andExpect(jsonPath("issuer").value(ISSUER_URL)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// gh-632
|
|
|
|
|
@Test |
|
|
|
|
public void requestWhenConfigurationRequestAndUserAuthenticatedThenReturnConfigurationResponse() throws Exception { |
|
|
|
|
this.spring.register(AuthorizationServerConfiguration.class).autowire(); |
|
|
|
|
|
|
|
|
|
this.mvc.perform(get(DEFAULT_OIDC_PROVIDER_CONFIGURATION_ENDPOINT_URI) |
|
|
|
|
.with(user("user"))) |
|
|
|
|
.andExpect(status().is2xxSuccessful()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// gh-616
|
|
|
|
|
@Test |
|
|
|
|
public void requestWhenConfigurationRequestAndConfigurationCustomizerSetThenReturnCustomConfigurationResponse() throws Exception { |
|
|
|
|
this.spring.register(AuthorizationServerConfigurationWithProviderConfigurationCustomizer.class).autowire(); |
|
|
|
|
|
|
|
|
|
this.mvc.perform(get(DEFAULT_OIDC_PROVIDER_CONFIGURATION_ENDPOINT_URI)) |
|
|
|
|
.andExpect(status().is2xxSuccessful()) |
|
|
|
|
.andExpect(jsonPath(OAuth2AuthorizationServerMetadataClaimNames.SCOPES_SUPPORTED, |
|
|
|
|
hasItems(OidcScopes.OPENID, OidcScopes.PROFILE, OidcScopes.EMAIL))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
public void loadContextWhenIssuerNotValidUrlThenThrowException() { |
|
|
|
|
assertThatThrownBy( |
|
|
|
|
() -> this.spring.register(AuthorizationServerConfigurationWithInvalidIssuerUrl.class).autowire() |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
public void loadContextWhenIssuerNotValidUriThenThrowException() { |
|
|
|
|
assertThatThrownBy( |
|
|
|
|
() -> this.spring.register(AuthorizationServerConfigurationWithInvalidIssuerUri.class).autowire() |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
public void loadContextWhenIssuerWithQueryThenThrowException() { |
|
|
|
|
assertThatThrownBy( |
|
|
|
|
() -> this.spring.register(AuthorizationServerConfigurationWithIssuerQuery.class).autowire() |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
public void loadContextWhenIssuerWithFragmentThenThrowException() { |
|
|
|
|
assertThatThrownBy( |
|
|
|
|
() -> this.spring.register(AuthorizationServerConfigurationWithIssuerFragment.class).autowire() |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
public void loadContextWhenIssuerWithQueryAndFragmentThenThrowException() { |
|
|
|
|
assertThatThrownBy( |
|
|
|
|
() -> this.spring.register(AuthorizationServerConfigurationWithIssuerQueryAndFragment.class).autowire() |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
public void loadContextWhenIssuerWithEmptyQueryThenThrowException() { |
|
|
|
|
assertThatThrownBy( |
|
|
|
|
() -> this.spring.register(AuthorizationServerConfigurationWithIssuerEmptyQuery.class).autowire() |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
public void loadContextWhenIssuerWithEmptyFragmentThenThrowException() { |
|
|
|
|
assertThatThrownBy( |
|
|
|
|
() -> this.spring.register(AuthorizationServerConfigurationWithIssuerEmptyFragment.class).autowire() |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
public void requestWhenAuthenticationRequestThenTokenResponseIncludesIdToken() throws Exception { |
|
|
|
|
this.spring.register(AuthorizationServerConfiguration.class).autowire(); |
|
|
|
|
@ -480,121 +392,4 @@ public class OidcTests {
@@ -480,121 +392,4 @@ public class OidcTests {
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Configuration |
|
|
|
|
@EnableWebSecurity |
|
|
|
|
static class AuthorizationServerConfigurationWithProviderConfigurationCustomizer extends AuthorizationServerConfiguration { |
|
|
|
|
|
|
|
|
|
// @formatter:off
|
|
|
|
|
@Bean |
|
|
|
|
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { |
|
|
|
|
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = |
|
|
|
|
new OAuth2AuthorizationServerConfigurer(); |
|
|
|
|
http.apply(authorizationServerConfigurer); |
|
|
|
|
|
|
|
|
|
authorizationServerConfigurer |
|
|
|
|
.oidc(oidc -> |
|
|
|
|
oidc.providerConfigurationEndpoint(providerConfigurationEndpoint -> |
|
|
|
|
providerConfigurationEndpoint |
|
|
|
|
.providerConfigurationCustomizer(providerConfigurationCustomizer()))); |
|
|
|
|
|
|
|
|
|
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher(); |
|
|
|
|
|
|
|
|
|
http |
|
|
|
|
.requestMatcher(endpointsMatcher) |
|
|
|
|
.authorizeRequests(authorizeRequests -> |
|
|
|
|
authorizeRequests.anyRequest().authenticated() |
|
|
|
|
) |
|
|
|
|
.csrf(csrf -> csrf.ignoringRequestMatchers(endpointsMatcher)); |
|
|
|
|
|
|
|
|
|
return http.build(); |
|
|
|
|
} |
|
|
|
|
// @formatter:on
|
|
|
|
|
|
|
|
|
|
private Consumer<OidcProviderConfiguration.Builder> providerConfigurationCustomizer() { |
|
|
|
|
return (providerConfiguration) -> |
|
|
|
|
providerConfiguration.scope(OidcScopes.PROFILE).scope(OidcScopes.EMAIL); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@EnableWebSecurity |
|
|
|
|
@Import(OAuth2AuthorizationServerConfiguration.class) |
|
|
|
|
static class AuthorizationServerConfigurationWithIssuer extends AuthorizationServerConfiguration { |
|
|
|
|
|
|
|
|
|
@Bean |
|
|
|
|
AuthorizationServerSettings authorizationServerSettings() { |
|
|
|
|
return AuthorizationServerSettings.builder().issuer(ISSUER_URL).build(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@EnableWebSecurity |
|
|
|
|
@Import(OAuth2AuthorizationServerConfiguration.class) |
|
|
|
|
static class AuthorizationServerConfigurationWithInvalidIssuerUrl extends AuthorizationServerConfiguration { |
|
|
|
|
|
|
|
|
|
@Bean |
|
|
|
|
AuthorizationServerSettings authorizationServerSettings() { |
|
|
|
|
return AuthorizationServerSettings.builder().issuer("urn:example").build(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@EnableWebSecurity |
|
|
|
|
@Import(OAuth2AuthorizationServerConfiguration.class) |
|
|
|
|
static class AuthorizationServerConfigurationWithInvalidIssuerUri extends AuthorizationServerConfiguration { |
|
|
|
|
|
|
|
|
|
@Bean |
|
|
|
|
AuthorizationServerSettings authorizationServerSettings() { |
|
|
|
|
return AuthorizationServerSettings.builder().issuer("https://not a valid uri").build(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@EnableWebSecurity |
|
|
|
|
@Import(OAuth2AuthorizationServerConfiguration.class) |
|
|
|
|
static class AuthorizationServerConfigurationWithIssuerQuery extends AuthorizationServerConfiguration { |
|
|
|
|
|
|
|
|
|
@Bean |
|
|
|
|
AuthorizationServerSettings authorizationServerSettings() { |
|
|
|
|
return AuthorizationServerSettings.builder().issuer(ISSUER_URL + "?param=value").build(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@EnableWebSecurity |
|
|
|
|
@Import(OAuth2AuthorizationServerConfiguration.class) |
|
|
|
|
static class AuthorizationServerConfigurationWithIssuerFragment extends AuthorizationServerConfiguration { |
|
|
|
|
|
|
|
|
|
@Bean |
|
|
|
|
AuthorizationServerSettings authorizationServerSettings() { |
|
|
|
|
return AuthorizationServerSettings.builder().issuer(ISSUER_URL + "#fragment").build(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@EnableWebSecurity |
|
|
|
|
@Import(OAuth2AuthorizationServerConfiguration.class) |
|
|
|
|
static class AuthorizationServerConfigurationWithIssuerQueryAndFragment extends AuthorizationServerConfiguration { |
|
|
|
|
|
|
|
|
|
@Bean |
|
|
|
|
AuthorizationServerSettings authorizationServerSettings() { |
|
|
|
|
return AuthorizationServerSettings.builder().issuer(ISSUER_URL + "?param=value#fragment").build(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@EnableWebSecurity |
|
|
|
|
@Import(OAuth2AuthorizationServerConfiguration.class) |
|
|
|
|
static class AuthorizationServerConfigurationWithIssuerEmptyQuery extends AuthorizationServerConfiguration { |
|
|
|
|
|
|
|
|
|
@Bean |
|
|
|
|
AuthorizationServerSettings authorizationServerSettings() { |
|
|
|
|
return AuthorizationServerSettings.builder().issuer(ISSUER_URL + "?").build(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@EnableWebSecurity |
|
|
|
|
@Import(OAuth2AuthorizationServerConfiguration.class) |
|
|
|
|
static class AuthorizationServerConfigurationWithIssuerEmptyFragment extends AuthorizationServerConfiguration { |
|
|
|
|
|
|
|
|
|
@Bean |
|
|
|
|
AuthorizationServerSettings authorizationServerSettings() { |
|
|
|
|
return AuthorizationServerSettings.builder().issuer(ISSUER_URL + "#").build(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|