Browse Source

Update integration tests to use in-memory

pull/341/head
Steve Riesenberg 5 years ago committed by Steve Riesenberg
parent
commit
549cdc7222
  1. 32
      oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/JwkSetTests.java
  2. 206
      oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationCodeGrantTests.java
  3. 7
      oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationServerMetadataTests.java
  4. 50
      oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2ClientCredentialsGrantTests.java
  5. 62
      oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2RefreshTokenGrantTests.java
  6. 79
      oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2TokenIntrospectionTests.java
  7. 74
      oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2TokenRevocationTests.java
  8. 63
      oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcClientRegistrationTests.java
  9. 83
      oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcTests.java
  10. 2
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/TestOAuth2Authorizations.java
  11. 49
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/jackson2/TestingAuthenticationTokenMixin.java

32
oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/JwkSetTests.java

@ -18,7 +18,6 @@ package org.springframework.security.config.annotation.web.configurers.oauth2.se @@ -18,7 +18,6 @@ package org.springframework.security.config.annotation.web.configurers.oauth2.se
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.proc.SecurityContext;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
@ -31,15 +30,17 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe @@ -31,15 +30,17 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
import org.springframework.security.config.test.SpringTestRule;
import org.springframework.security.oauth2.jose.TestJwks;
import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
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.client.TestRegisteredClients;
import org.springframework.security.oauth2.server.authorization.config.ProviderSettings;
import org.springframework.security.oauth2.server.authorization.web.NimbusJwkSetEndpointFilter;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.CoreMatchers.containsString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
@ -51,8 +52,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @@ -51,8 +52,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Florian Berthe
*/
public class JwkSetTests {
private static RegisteredClientRepository registeredClientRepository;
private static OAuth2AuthorizationService authorizationService;
private static JWKSource<SecurityContext> jwkSource;
private static ProviderSettings providerSettings;
@ -64,19 +63,11 @@ public class JwkSetTests { @@ -64,19 +63,11 @@ public class JwkSetTests {
@BeforeClass
public static void init() {
registeredClientRepository = mock(RegisteredClientRepository.class);
authorizationService = mock(OAuth2AuthorizationService.class);
JWKSet jwkSet = new JWKSet(TestJwks.DEFAULT_RSA_JWK);
jwkSource = (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
providerSettings = new ProviderSettings().jwkSetEndpoint("/test/jwks");
}
@Before
public void setup() {
reset(registeredClientRepository);
reset(authorizationService);
}
@Test
public void requestWhenJwkSetThenReturnKeys() throws Exception {
this.spring.register(AuthorizationServerConfiguration.class).autowire();
@ -105,13 +96,20 @@ public class JwkSetTests { @@ -105,13 +96,20 @@ public class JwkSetTests {
static class AuthorizationServerConfiguration {
@Bean
RegisteredClientRepository registeredClientRepository() {
return registeredClientRepository;
OAuth2AuthorizationService authorizationService() {
return new InMemoryOAuth2AuthorizationService();
}
@Bean
OAuth2AuthorizationService authorizationService() {
return authorizationService;
RegisteredClientRepository registeredClientRepository() {
// @formatter:off
RegisteredClient dummyClient = TestRegisteredClients.registeredClient()
.id("dummy-client")
.clientId("dummy-client")
.clientSecret("dummy-secret")
.build();
// @formatter:on
return new InMemoryRegisteredClientRepository(dummyClient);
}
@Bean

206
oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationCodeGrantTests.java

@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
*/
package org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
@ -28,11 +29,9 @@ import java.util.stream.Collectors; @@ -28,11 +29,9 @@ import java.util.stream.Collectors;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.proc.SecurityContext;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@ -62,12 +61,16 @@ import org.springframework.security.oauth2.jwt.Jwt; @@ -62,12 +61,16 @@ import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.JwtEncoder;
import org.springframework.security.oauth2.jwt.NimbusJwsEncoder;
import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationConsentService;
import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.JwtEncodingContext;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationCode;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.OAuth2TokenCustomizer;
import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations;
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.client.TestRegisteredClients;
@ -86,14 +89,6 @@ import org.springframework.web.util.UriComponentsBuilder; @@ -86,14 +89,6 @@ import org.springframework.web.util.UriComponentsBuilder;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.CoreMatchers.containsString;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
@ -114,9 +109,8 @@ public class OAuth2AuthorizationCodeGrantTests { @@ -114,9 +109,8 @@ public class OAuth2AuthorizationCodeGrantTests {
private static final String S256_CODE_CHALLENGE = "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM";
private static final String AUTHORITIES_CLAIM = "authorities";
private static final OAuth2TokenType AUTHORIZATION_CODE_TOKEN_TYPE = new OAuth2TokenType(OAuth2ParameterNames.CODE);
private static final OAuth2TokenType STATE_TOKEN_TYPE = new OAuth2TokenType(OAuth2ParameterNames.STATE);
private static RegisteredClientRepository registeredClientRepository;
private static OAuth2AuthorizationService authorizationService;
private static JWKSource<SecurityContext> jwkSource;
private static NimbusJwsEncoder jwtEncoder;
private static ProviderSettings providerSettings;
@ -130,13 +124,17 @@ public class OAuth2AuthorizationCodeGrantTests { @@ -130,13 +124,17 @@ public class OAuth2AuthorizationCodeGrantTests {
@Autowired
private MockMvc mvc;
@Autowired
private RegisteredClientRepository registeredClientRepository;
@Autowired
private OAuth2AuthorizationService authorizationService;
@Autowired
private JwtDecoder jwtDecoder;
@BeforeClass
public static void init() {
registeredClientRepository = mock(RegisteredClientRepository.class);
authorizationService = mock(OAuth2AuthorizationService.class);
JWKSet jwkSet = new JWKSet(TestJwks.DEFAULT_RSA_JWK);
jwkSource = (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
jwtEncoder = new NimbusJwsEncoder(jwkSource);
@ -145,27 +143,29 @@ public class OAuth2AuthorizationCodeGrantTests { @@ -145,27 +143,29 @@ public class OAuth2AuthorizationCodeGrantTests {
.tokenEndpoint("/test/token");
}
@Before
public void setup() {
reset(registeredClientRepository);
reset(authorizationService);
}
@Test
public void requestWhenAuthorizationRequestNotAuthenticatedThenUnauthorized() throws Exception {
this.spring.register(AuthorizationServerConfiguration.class).autowire();
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
when(registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
.thenReturn(registeredClient);
this.registeredClientRepository.save(registeredClient);
this.mvc.perform(get(OAuth2AuthorizationEndpointFilter.DEFAULT_AUTHORIZATION_ENDPOINT_URI)
.params(getAuthorizationRequestParameters(registeredClient)))
.andExpect(status().isUnauthorized())
.andReturn();
}
verify(registeredClientRepository).findByClientId(eq(registeredClient.getClientId()));
verifyNoInteractions(authorizationService);
@Test
public void requestWhenRegisteredClientMissingThenBadRequest() throws Exception {
this.spring.register(AuthorizationServerConfiguration.class).autowire();
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
this.mvc.perform(get(OAuth2AuthorizationEndpointFilter.DEFAULT_AUTHORIZATION_ENDPOINT_URI)
.params(getAuthorizationRequestParameters(registeredClient)))
.andExpect(status().isBadRequest())
.andReturn();
}
@Test
@ -184,18 +184,20 @@ public class OAuth2AuthorizationCodeGrantTests { @@ -184,18 +184,20 @@ public class OAuth2AuthorizationCodeGrantTests {
private void assertAuthorizationRequestRedirectsToClient(String authorizationEndpointUri) throws Exception {
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
when(registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
.thenReturn(registeredClient);
this.registeredClientRepository.save(registeredClient);
MvcResult mvcResult = this.mvc.perform(get(authorizationEndpointUri)
.params(getAuthorizationRequestParameters(registeredClient))
.with(user("user")))
.andExpect(status().is3xxRedirection())
.andReturn();
assertThat(mvcResult.getResponse().getRedirectedUrl()).matches("https://example.com\\?code=.{15,}&state=state");
String redirectedUrl = mvcResult.getResponse().getRedirectedUrl();
assertThat(redirectedUrl).matches("https://example.com\\?code=.{15,}&state=state");
verify(registeredClientRepository).findByClientId(eq(registeredClient.getClientId()));
verify(authorizationService).save(any());
String authorizationCode = extractParameterFromRedirectUri(redirectedUrl, "code");
OAuth2Authorization authorization = this.authorizationService.findByToken(authorizationCode, AUTHORIZATION_CODE_TOKEN_TYPE);
assertThat(authorization).isNotNull();
assertThat(authorization.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
}
@Test
@ -203,14 +205,10 @@ public class OAuth2AuthorizationCodeGrantTests { @@ -203,14 +205,10 @@ public class OAuth2AuthorizationCodeGrantTests {
this.spring.register(AuthorizationServerConfiguration.class).autowire();
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
when(registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
.thenReturn(registeredClient);
this.registeredClientRepository.save(registeredClient);
OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build();
when(authorizationService.findByToken(
eq(authorization.getToken(OAuth2AuthorizationCode.class).getToken().getTokenValue()),
eq(AUTHORIZATION_CODE_TOKEN_TYPE)))
.thenReturn(authorization);
this.authorizationService.save(authorization);
OAuth2AccessTokenResponse accessTokenResponse = assertTokenRequestReturnsAccessTokenResponse(
registeredClient, authorization, OAuth2TokenEndpointFilter.DEFAULT_TOKEN_ENDPOINT_URI);
@ -230,14 +228,10 @@ public class OAuth2AuthorizationCodeGrantTests { @@ -230,14 +228,10 @@ public class OAuth2AuthorizationCodeGrantTests {
this.spring.register(AuthorizationServerConfigurationCustomEndpoints.class).autowire();
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
when(registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
.thenReturn(registeredClient);
this.registeredClientRepository.save(registeredClient);
OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build();
when(authorizationService.findByToken(
eq(authorization.getToken(OAuth2AuthorizationCode.class).getToken().getTokenValue()),
eq(AUTHORIZATION_CODE_TOKEN_TYPE)))
.thenReturn(authorization);
this.authorizationService.save(authorization);
assertTokenRequestReturnsAccessTokenResponse(
registeredClient, authorization, providerSettings.tokenEndpoint());
@ -258,11 +252,14 @@ public class OAuth2AuthorizationCodeGrantTests { @@ -258,11 +252,14 @@ public class OAuth2AuthorizationCodeGrantTests {
.andExpect(jsonPath("$.scope").isNotEmpty())
.andReturn();
verify(registeredClientRepository).findByClientId(eq(registeredClient.getClientId()));
verify(authorizationService).findByToken(
eq(authorization.getToken(OAuth2AuthorizationCode.class).getToken().getTokenValue()),
eq(AUTHORIZATION_CODE_TOKEN_TYPE));
verify(authorizationService).save(any());
OAuth2Authorization accessTokenAuthorization = this.authorizationService.findById(authorization.getId());
assertThat(accessTokenAuthorization).isNotNull();
assertThat(accessTokenAuthorization.getAccessToken()).isNotNull();
assertThat(accessTokenAuthorization.getRefreshToken()).isNotNull();
OAuth2Authorization.Token<OAuth2AuthorizationCode> authorizationCodeToken = accessTokenAuthorization.getToken(OAuth2AuthorizationCode.class);
assertThat(authorizationCodeToken).isNotNull();
assertThat(authorizationCodeToken.getMetadata().get(OAuth2Authorization.Token.INVALIDATED_METADATA_NAME)).isEqualTo(true);
MockHttpServletResponse servletResponse = mvcResult.getResponse();
MockClientHttpResponse httpResponse = new MockClientHttpResponse(
@ -275,8 +272,7 @@ public class OAuth2AuthorizationCodeGrantTests { @@ -275,8 +272,7 @@ public class OAuth2AuthorizationCodeGrantTests {
this.spring.register(AuthorizationServerConfiguration.class).autowire();
RegisteredClient registeredClient = TestRegisteredClients.registeredPublicClient().build();
when(registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
.thenReturn(registeredClient);
this.registeredClientRepository.save(registeredClient);
MvcResult mvcResult = this.mvc.perform(get(OAuth2AuthorizationEndpointFilter.DEFAULT_AUTHORIZATION_ENDPOINT_URI)
.params(getAuthorizationRequestParameters(registeredClient))
@ -285,21 +281,16 @@ public class OAuth2AuthorizationCodeGrantTests { @@ -285,21 +281,16 @@ public class OAuth2AuthorizationCodeGrantTests {
.with(user("user")))
.andExpect(status().is3xxRedirection())
.andReturn();
assertThat(mvcResult.getResponse().getRedirectedUrl()).matches("https://example.com\\?code=.{15,}&state=state");
verify(registeredClientRepository).findByClientId(eq(registeredClient.getClientId()));
String redirectedUrl = mvcResult.getResponse().getRedirectedUrl();
assertThat(redirectedUrl).matches("https://example.com\\?code=.{15,}&state=state");
ArgumentCaptor<OAuth2Authorization> authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class);
verify(authorizationService).save(authorizationCaptor.capture());
OAuth2Authorization authorization = authorizationCaptor.getValue();
when(authorizationService.findByToken(
eq(authorization.getToken(OAuth2AuthorizationCode.class).getToken().getTokenValue()),
eq(AUTHORIZATION_CODE_TOKEN_TYPE)))
.thenReturn(authorization);
String authorizationCode = extractParameterFromRedirectUri(redirectedUrl, "code");
OAuth2Authorization authorizationCodeAuthorization = this.authorizationService.findByToken(authorizationCode, AUTHORIZATION_CODE_TOKEN_TYPE);
assertThat(authorizationCodeAuthorization).isNotNull();
assertThat(authorizationCodeAuthorization.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
this.mvc.perform(post(OAuth2TokenEndpointFilter.DEFAULT_TOKEN_ENDPOINT_URI)
.params(getTokenRequestParameters(registeredClient, authorization))
.params(getTokenRequestParameters(registeredClient, authorizationCodeAuthorization))
.param(OAuth2ParameterNames.CLIENT_ID, registeredClient.getClientId())
.param(PkceParameterNames.CODE_VERIFIER, S256_CODE_VERIFIER))
.andExpect(header().string(HttpHeaders.CACHE_CONTROL, containsString("no-store")))
@ -311,11 +302,13 @@ public class OAuth2AuthorizationCodeGrantTests { @@ -311,11 +302,13 @@ public class OAuth2AuthorizationCodeGrantTests {
.andExpect(jsonPath("$.refresh_token").doesNotExist())
.andExpect(jsonPath("$.scope").isNotEmpty());
verify(registeredClientRepository, times(2)).findByClientId(eq(registeredClient.getClientId()));
verify(authorizationService, times(2)).findByToken(
eq(authorization.getToken(OAuth2AuthorizationCode.class).getToken().getTokenValue()),
eq(AUTHORIZATION_CODE_TOKEN_TYPE));
verify(authorizationService, times(2)).save(any());
OAuth2Authorization accessTokenAuthorization = this.authorizationService.findById(authorizationCodeAuthorization.getId());
assertThat(accessTokenAuthorization).isNotNull();
assertThat(accessTokenAuthorization.getAccessToken()).isNotNull();
OAuth2Authorization.Token<OAuth2AuthorizationCode> authorizationCodeToken = accessTokenAuthorization.getToken(OAuth2AuthorizationCode.class);
assertThat(authorizationCodeToken).isNotNull();
assertThat(authorizationCodeToken.getMetadata().get(OAuth2Authorization.Token.INVALIDATED_METADATA_NAME)).isEqualTo(true);
}
@Test
@ -323,14 +316,10 @@ public class OAuth2AuthorizationCodeGrantTests { @@ -323,14 +316,10 @@ public class OAuth2AuthorizationCodeGrantTests {
this.spring.register(AuthorizationServerConfigurationWithJwtEncoder.class).autowire();
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
when(registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
.thenReturn(registeredClient);
this.registeredClientRepository.save(registeredClient);
OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build();
when(authorizationService.findByToken(
eq(authorization.getToken(OAuth2AuthorizationCode.class).getToken().getTokenValue()),
eq(AUTHORIZATION_CODE_TOKEN_TYPE)))
.thenReturn(authorization);
this.authorizationService.save(authorization);
this.mvc.perform(post(OAuth2TokenEndpointFilter.DEFAULT_TOKEN_ENDPOINT_URI)
.params(getTokenRequestParameters(registeredClient, authorization))
@ -349,8 +338,7 @@ public class OAuth2AuthorizationCodeGrantTests { @@ -349,8 +338,7 @@ public class OAuth2AuthorizationCodeGrantTests {
})
.clientSettings(settings -> settings.requireUserConsent(true))
.build();
when(registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
.thenReturn(registeredClient);
this.registeredClientRepository.save(registeredClient);
String consentPage = this.mvc.perform(get(OAuth2AuthorizationEndpointFilter.DEFAULT_AUTHORIZATION_ENDPOINT_URI)
.params(getAuthorizationRequestParameters(registeredClient))
@ -377,36 +365,28 @@ public class OAuth2AuthorizationCodeGrantTests { @@ -377,36 +365,28 @@ public class OAuth2AuthorizationCodeGrantTests {
})
.clientSettings(settings -> settings.requireUserConsent(true))
.build();
when(registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
.thenReturn(registeredClient);
this.registeredClientRepository.save(registeredClient);
OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient)
.principalName("user")
.build();
final String stateParameter = "state";
when(authorizationService.findByToken(
eq(stateParameter), eq(new OAuth2TokenType(OAuth2ParameterNames.STATE))))
.thenReturn(authorization);
this.authorizationService.save(authorization);
MvcResult mvcResult = this.mvc.perform(post(OAuth2AuthorizationEndpointFilter.DEFAULT_AUTHORIZATION_ENDPOINT_URI)
.param(OAuth2ParameterNames.CLIENT_ID, registeredClient.getClientId())
.param(OAuth2ParameterNames.SCOPE, "message.read")
.param(OAuth2ParameterNames.SCOPE, "message.write")
.param(OAuth2ParameterNames.STATE, stateParameter)
.param(OAuth2ParameterNames.STATE, "state")
.param("consent_action", "approve")
.with(user("user")))
.andExpect(status().is3xxRedirection())
.andReturn();
assertThat(mvcResult.getResponse().getRedirectedUrl()).matches("https://example.com\\?code=.{15,}&state=state");
ArgumentCaptor<OAuth2Authorization> authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class);
verify(authorizationService).save(authorizationCaptor.capture());
OAuth2Authorization authorizationCodeAuthorization = authorizationCaptor.getValue();
when(authorizationService.findByToken(
eq(authorizationCodeAuthorization.getToken(OAuth2AuthorizationCode.class).getToken().getTokenValue()),
eq(AUTHORIZATION_CODE_TOKEN_TYPE)))
.thenReturn(authorizationCodeAuthorization);
String redirectedUrl = mvcResult.getResponse().getRedirectedUrl();
assertThat(redirectedUrl).matches("https://example.com\\?code=.{15,}&state=state");
String authorizationCode = extractParameterFromRedirectUri(redirectedUrl, "code");
OAuth2Authorization authorizationCodeAuthorization = this.authorizationService.findByToken(authorizationCode, AUTHORIZATION_CODE_TOKEN_TYPE);
this.mvc.perform(post(OAuth2TokenEndpointFilter.DEFAULT_TOKEN_ENDPOINT_URI)
.params(getTokenRequestParameters(registeredClient, authorizationCodeAuthorization))
@ -434,27 +414,27 @@ public class OAuth2AuthorizationCodeGrantTests { @@ -434,27 +414,27 @@ public class OAuth2AuthorizationCodeGrantTests {
})
.clientSettings(settings -> settings.requireUserConsent(true))
.build();
when(registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
.thenReturn(registeredClient);
this.registeredClientRepository.save(registeredClient);
MvcResult mvcResult = this.mvc.perform(get(OAuth2AuthorizationEndpointFilter.DEFAULT_AUTHORIZATION_ENDPOINT_URI)
.params(getAuthorizationRequestParameters(registeredClient))
.with(user("user")))
.andExpect(status().is3xxRedirection())
.andReturn();
String redirectedUrl = mvcResult.getResponse().getRedirectedUrl();
assertThat(redirectedUrl).matches("/oauth2/consent\\?scope=.+&client_id=.+&state=.+");
String locationHeader = URLDecoder.decode(mvcResult.getResponse().getRedirectedUrl(), StandardCharsets.UTF_8.name());
UriComponents redirectedUrl = UriComponentsBuilder.fromUriString(locationHeader).build();
MultiValueMap<String, String> redirectQueryParams = redirectedUrl.getQueryParams();
String locationHeader = URLDecoder.decode(redirectedUrl, StandardCharsets.UTF_8.name());
UriComponents uriComponents = UriComponentsBuilder.fromUriString(locationHeader).build();
MultiValueMap<String, String> redirectQueryParams = uriComponents.getQueryParams();
assertThat(redirectedUrl.getPath()).isEqualTo(consentPage);
assertThat(uriComponents.getPath()).isEqualTo(consentPage);
assertThat(redirectQueryParams.getFirst(OAuth2ParameterNames.SCOPE)).isEqualTo("message.read message.write");
assertThat(redirectQueryParams.getFirst(OAuth2ParameterNames.CLIENT_ID)).isEqualTo(registeredClient.getClientId());
ArgumentCaptor<OAuth2Authorization> authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class);
verify(authorizationService).save(authorizationCaptor.capture());
OAuth2Authorization authorization = authorizationCaptor.getValue();
assertThat(redirectQueryParams.getFirst(OAuth2ParameterNames.STATE)).isEqualTo(authorization.getAttribute(OAuth2ParameterNames.STATE));
String state = extractParameterFromRedirectUri(redirectedUrl, "state");
OAuth2Authorization authorization = this.authorizationService.findByToken(state, STATE_TOKEN_TYPE);
assertThat(authorization).isNotNull();
}
private static MultiValueMap<String, String> getAuthorizationRequestParameters(RegisteredClient registeredClient) {
@ -494,18 +474,36 @@ public class OAuth2AuthorizationCodeGrantTests { @@ -494,18 +474,36 @@ public class OAuth2AuthorizationCodeGrantTests {
);
}
private String extractParameterFromRedirectUri(String redirectUri, String param) throws UnsupportedEncodingException {
String locationHeader = URLDecoder.decode(redirectUri, StandardCharsets.UTF_8.name());
UriComponents uriComponents = UriComponentsBuilder.fromUriString(locationHeader).build();
return uriComponents.getQueryParams().getFirst(param);
}
@EnableWebSecurity
@Import(OAuth2AuthorizationServerConfiguration.class)
static class AuthorizationServerConfiguration {
@Bean
RegisteredClientRepository registeredClientRepository() {
return registeredClientRepository;
OAuth2AuthorizationService authorizationService() {
return new InMemoryOAuth2AuthorizationService();
}
@Bean
OAuth2AuthorizationService authorizationService() {
return authorizationService;
OAuth2AuthorizationConsentService authorizationConsentService() {
return new InMemoryOAuth2AuthorizationConsentService();
}
@Bean
RegisteredClientRepository registeredClientRepository() {
// @formatter:off
RegisteredClient dummyClient = TestRegisteredClients.registeredClient()
.id("dummy-client")
.clientId("dummy-client")
.clientSecret("dummy-secret")
.build();
// @formatter:on
return new InMemoryRegisteredClientRepository(dummyClient);
}
@Bean

7
oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationServerMetadataTests.java

@ -29,12 +29,14 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe @@ -29,12 +29,14 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
import org.springframework.security.config.test.SpringTestRule;
import org.springframework.security.oauth2.jose.TestJwks;
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.client.TestRegisteredClients;
import org.springframework.security.oauth2.server.authorization.config.ProviderSettings;
import org.springframework.security.oauth2.server.authorization.web.OAuth2AuthorizationServerMetadataEndpointFilter;
import org.springframework.test.web.servlet.MockMvc;
import static org.mockito.Mockito.mock;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -76,7 +78,8 @@ public class OAuth2AuthorizationServerMetadataTests { @@ -76,7 +78,8 @@ public class OAuth2AuthorizationServerMetadataTests {
@Bean
RegisteredClientRepository registeredClientRepository() {
return mock(RegisteredClientRepository.class);
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
return new InMemoryRegisteredClientRepository(registeredClient);
}
@Bean

50
oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2ClientCredentialsGrantTests.java

@ -44,12 +44,16 @@ import org.springframework.security.oauth2.core.AuthorizationGrantType; @@ -44,12 +44,16 @@ import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.oauth2.jose.TestJwks;
import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationConsentService;
import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.JwtEncodingContext;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.OAuth2TokenCustomizer;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AccessTokenAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientCredentialsAuthenticationToken;
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.client.TestRegisteredClients;
@ -67,7 +71,6 @@ import static org.mockito.ArgumentMatchers.eq; @@ -67,7 +71,6 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
@ -80,8 +83,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @@ -80,8 +83,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Joe Grandja
*/
public class OAuth2ClientCredentialsGrantTests {
private static RegisteredClientRepository registeredClientRepository;
private static OAuth2AuthorizationService authorizationService;
private static JWKSource<SecurityContext> jwkSource;
private static OAuth2TokenCustomizer<JwtEncodingContext> jwtCustomizer;
private static AuthenticationConverter accessTokenRequestConverter;
@ -95,10 +96,11 @@ public class OAuth2ClientCredentialsGrantTests { @@ -95,10 +96,11 @@ public class OAuth2ClientCredentialsGrantTests {
@Autowired
private MockMvc mvc;
@Autowired
private RegisteredClientRepository registeredClientRepository;
@BeforeClass
public static void init() {
registeredClientRepository = mock(RegisteredClientRepository.class);
authorizationService = mock(OAuth2AuthorizationService.class);
JWKSet jwkSet = new JWKSet(TestJwks.DEFAULT_RSA_JWK);
jwkSource = (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
jwtCustomizer = mock(OAuth2TokenCustomizer.class);
@ -112,8 +114,6 @@ public class OAuth2ClientCredentialsGrantTests { @@ -112,8 +114,6 @@ public class OAuth2ClientCredentialsGrantTests {
@Before
public void setup() {
reset(jwtCustomizer);
reset(registeredClientRepository);
reset(authorizationService);
}
@Test
@ -123,9 +123,6 @@ public class OAuth2ClientCredentialsGrantTests { @@ -123,9 +123,6 @@ public class OAuth2ClientCredentialsGrantTests {
this.mvc.perform(MockMvcRequestBuilders.post(OAuth2TokenEndpointFilter.DEFAULT_TOKEN_ENDPOINT_URI)
.param(OAuth2ParameterNames.GRANT_TYPE, AuthorizationGrantType.CLIENT_CREDENTIALS.getValue()))
.andExpect(status().isUnauthorized());
verifyNoInteractions(registeredClientRepository);
verifyNoInteractions(authorizationService);
}
@Test
@ -133,8 +130,7 @@ public class OAuth2ClientCredentialsGrantTests { @@ -133,8 +130,7 @@ public class OAuth2ClientCredentialsGrantTests {
this.spring.register(AuthorizationServerConfiguration.class).autowire();
RegisteredClient registeredClient = TestRegisteredClients.registeredClient2().build();
when(registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
.thenReturn(registeredClient);
this.registeredClientRepository.save(registeredClient);
this.mvc.perform(post(OAuth2TokenEndpointFilter.DEFAULT_TOKEN_ENDPOINT_URI)
.param(OAuth2ParameterNames.GRANT_TYPE, AuthorizationGrantType.CLIENT_CREDENTIALS.getValue())
@ -146,8 +142,6 @@ public class OAuth2ClientCredentialsGrantTests { @@ -146,8 +142,6 @@ public class OAuth2ClientCredentialsGrantTests {
.andExpect(jsonPath("$.scope").value("scope1 scope2"));
verify(jwtCustomizer).customize(any());
verify(registeredClientRepository).findByClientId(eq(registeredClient.getClientId()));
verify(authorizationService).save(any());
}
@Test
@ -155,8 +149,7 @@ public class OAuth2ClientCredentialsGrantTests { @@ -155,8 +149,7 @@ public class OAuth2ClientCredentialsGrantTests {
this.spring.register(AuthorizationServerConfiguration.class).autowire();
RegisteredClient registeredClient = TestRegisteredClients.registeredClient2().build();
when(registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
.thenReturn(registeredClient);
this.registeredClientRepository.save(registeredClient);
this.mvc.perform(post(OAuth2TokenEndpointFilter.DEFAULT_TOKEN_ENDPOINT_URI)
.param(OAuth2ParameterNames.GRANT_TYPE, AuthorizationGrantType.CLIENT_CREDENTIALS.getValue())
@ -168,8 +161,6 @@ public class OAuth2ClientCredentialsGrantTests { @@ -168,8 +161,6 @@ public class OAuth2ClientCredentialsGrantTests {
.andExpect(jsonPath("$.scope").value("scope1 scope2"));
verify(jwtCustomizer).customize(any());
verify(registeredClientRepository).findByClientId(eq(registeredClient.getClientId()));
verify(authorizationService).save(any());
}
@Test
@ -177,8 +168,7 @@ public class OAuth2ClientCredentialsGrantTests { @@ -177,8 +168,7 @@ public class OAuth2ClientCredentialsGrantTests {
this.spring.register(AuthorizationServerConfigurationCustomTokenEndpoint.class).autowire();
RegisteredClient registeredClient = TestRegisteredClients.registeredClient2().build();
when(registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
.thenReturn(registeredClient);
this.registeredClientRepository.save(registeredClient);
OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(registeredClient);
OAuth2ClientCredentialsAuthenticationToken clientCredentialsAuthentication =
@ -217,13 +207,25 @@ public class OAuth2ClientCredentialsGrantTests { @@ -217,13 +207,25 @@ public class OAuth2ClientCredentialsGrantTests {
static class AuthorizationServerConfiguration {
@Bean
RegisteredClientRepository registeredClientRepository() {
return registeredClientRepository;
OAuth2AuthorizationService authorizationService() {
return new InMemoryOAuth2AuthorizationService();
}
@Bean
OAuth2AuthorizationService authorizationService() {
return authorizationService;
OAuth2AuthorizationConsentService authorizationConsentService() {
return new InMemoryOAuth2AuthorizationConsentService();
}
@Bean
RegisteredClientRepository registeredClientRepository() {
// @formatter:off
RegisteredClient dummyClient = TestRegisteredClients.registeredClient()
.id("dummy-client")
.clientId("dummy-client")
.clientSecret("dummy-secret")
.build();
// @formatter:on
return new InMemoryRegisteredClientRepository(dummyClient);
}
@Bean

62
oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2RefreshTokenGrantTests.java

@ -26,7 +26,6 @@ import java.util.stream.Collectors; @@ -26,7 +26,6 @@ import java.util.stream.Collectors;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.proc.SecurityContext;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
@ -47,7 +46,6 @@ import org.springframework.security.core.GrantedAuthority; @@ -47,7 +46,6 @@ import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.OAuth2TokenType;
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.oauth2.core.http.converter.OAuth2AccessTokenResponseHttpMessageConverter;
@ -55,11 +53,15 @@ import org.springframework.security.oauth2.jose.TestJwks; @@ -55,11 +53,15 @@ import org.springframework.security.oauth2.jose.TestJwks;
import org.springframework.security.oauth2.jose.TestKeys;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationConsentService;
import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.JwtEncodingContext;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.OAuth2TokenCustomizer;
import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations;
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.client.TestRegisteredClients;
@ -71,12 +73,6 @@ import org.springframework.util.MultiValueMap; @@ -71,12 +73,6 @@ import org.springframework.util.MultiValueMap;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.CoreMatchers.containsString;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
@ -90,8 +86,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @@ -90,8 +86,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
*/
public class OAuth2RefreshTokenGrantTests {
private static final String AUTHORITIES_CLAIM = "authorities";
private static RegisteredClientRepository registeredClientRepository;
private static OAuth2AuthorizationService authorizationService;
private static JWKSource<SecurityContext> jwkSource;
private static NimbusJwtDecoder jwtDecoder;
private static HttpMessageConverter<OAuth2AccessTokenResponse> accessTokenHttpResponseConverter =
@ -103,34 +97,28 @@ public class OAuth2RefreshTokenGrantTests { @@ -103,34 +97,28 @@ public class OAuth2RefreshTokenGrantTests {
@Autowired
private MockMvc mvc;
@Autowired
private RegisteredClientRepository registeredClientRepository;
@Autowired
private OAuth2AuthorizationService authorizationService;
@BeforeClass
public static void init() {
registeredClientRepository = mock(RegisteredClientRepository.class);
authorizationService = mock(OAuth2AuthorizationService.class);
JWKSet jwkSet = new JWKSet(TestJwks.DEFAULT_RSA_JWK);
jwkSource = (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
jwtDecoder = NimbusJwtDecoder.withPublicKey(TestKeys.DEFAULT_PUBLIC_KEY).build();
}
@Before
public void setup() {
reset(registeredClientRepository);
reset(authorizationService);
}
@Test
public void requestWhenRefreshTokenRequestValidThenReturnAccessTokenResponse() throws Exception {
this.spring.register(AuthorizationServerConfiguration.class).autowire();
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
when(registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
.thenReturn(registeredClient);
this.registeredClientRepository.save(registeredClient);
OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build();
when(authorizationService.findByToken(
eq(authorization.getRefreshToken().getToken().getTokenValue()),
eq(OAuth2TokenType.REFRESH_TOKEN)))
.thenReturn(authorization);
this.authorizationService.save(authorization);
MvcResult mvcResult = this.mvc.perform(post(OAuth2TokenEndpointFilter.DEFAULT_TOKEN_ENDPOINT_URI)
.params(getRefreshTokenRequestParameters(authorization))
@ -146,12 +134,6 @@ public class OAuth2RefreshTokenGrantTests { @@ -146,12 +134,6 @@ public class OAuth2RefreshTokenGrantTests {
.andExpect(jsonPath("$.scope").isNotEmpty())
.andReturn();
verify(registeredClientRepository).findByClientId(eq(registeredClient.getClientId()));
verify(authorizationService).findByToken(
eq(authorization.getRefreshToken().getToken().getTokenValue()),
eq(OAuth2TokenType.REFRESH_TOKEN));
verify(authorizationService).save(any());
MockHttpServletResponse servletResponse = mvcResult.getResponse();
MockClientHttpResponse httpResponse = new MockClientHttpResponse(
servletResponse.getContentAsByteArray(), HttpStatus.valueOf(servletResponse.getStatus()));
@ -188,13 +170,25 @@ public class OAuth2RefreshTokenGrantTests { @@ -188,13 +170,25 @@ public class OAuth2RefreshTokenGrantTests {
static class AuthorizationServerConfiguration {
@Bean
RegisteredClientRepository registeredClientRepository() {
return registeredClientRepository;
OAuth2AuthorizationService authorizationService() {
return new InMemoryOAuth2AuthorizationService();
}
@Bean
OAuth2AuthorizationService authorizationService() {
return authorizationService;
OAuth2AuthorizationConsentService authorizationConsentService() {
return new InMemoryOAuth2AuthorizationConsentService();
}
@Bean
RegisteredClientRepository registeredClientRepository() {
// @formatter:off
RegisteredClient dummyClient = TestRegisteredClients.registeredClient()
.id("dummy-client")
.clientId("dummy-client")
.clientSecret("dummy-secret")
.build();
// @formatter:on
return new InMemoryRegisteredClientRepository(dummyClient);
}
@Bean

79
oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2TokenIntrospectionTests.java

@ -23,7 +23,6 @@ import java.util.HashSet; @@ -23,7 +23,6 @@ import java.util.HashSet;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.proc.SecurityContext;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
@ -50,9 +49,13 @@ import org.springframework.security.oauth2.core.http.converter.OAuth2TokenIntros @@ -50,9 +49,13 @@ import org.springframework.security.oauth2.core.http.converter.OAuth2TokenIntros
import org.springframework.security.oauth2.jose.TestJwks;
import org.springframework.security.oauth2.jwt.JwtClaimsSet;
import org.springframework.security.oauth2.jwt.TestJwtClaimsSets;
import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationConsentService;
import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations;
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.client.TestRegisteredClients;
@ -63,12 +66,6 @@ import org.springframework.util.LinkedMultiValueMap; @@ -63,12 +66,6 @@ import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -80,8 +77,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @@ -80,8 +77,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Joe Grandja
*/
public class OAuth2TokenIntrospectionTests {
private static RegisteredClientRepository registeredClientRepository;
private static OAuth2AuthorizationService authorizationService;
private static JWKSource<SecurityContext> jwkSource;
private static ProviderSettings providerSettings;
private final HttpMessageConverter<OAuth2TokenIntrospection> tokenIntrospectionHttpResponseConverter =
@ -93,28 +88,26 @@ public class OAuth2TokenIntrospectionTests { @@ -93,28 +88,26 @@ public class OAuth2TokenIntrospectionTests {
@Autowired
private MockMvc mvc;
@Autowired
private RegisteredClientRepository registeredClientRepository;
@Autowired
private OAuth2AuthorizationService authorizationService;
@BeforeClass
public static void init() {
registeredClientRepository = mock(RegisteredClientRepository.class);
authorizationService = mock(OAuth2AuthorizationService.class);
JWKSet jwkSet = new JWKSet(TestJwks.DEFAULT_RSA_JWK);
jwkSource = (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
providerSettings = new ProviderSettings().tokenIntrospectionEndpoint("/test/introspect");
}
@Before
public void setup() {
reset(registeredClientRepository);
reset(authorizationService);
}
@Test
public void requestWhenIntrospectValidAccessTokenThenActive() throws Exception {
this.spring.register(AuthorizationServerConfiguration.class).autowire();
RegisteredClient introspectRegisteredClient = TestRegisteredClients.registeredClient2().build();
when(registeredClientRepository.findByClientId(eq(introspectRegisteredClient.getClientId())))
.thenReturn(introspectRegisteredClient);
RegisteredClient introspectRegisteredClient = TestRegisteredClients.registeredClient2()
.clientSecret("secret-2").build();
this.registeredClientRepository.save(introspectRegisteredClient);
RegisteredClient authorizedRegisteredClient = TestRegisteredClients.registeredClient().build();
Instant issuedAt = Instant.now();
@ -126,10 +119,8 @@ public class OAuth2TokenIntrospectionTests { @@ -126,10 +119,8 @@ public class OAuth2TokenIntrospectionTests {
OAuth2Authorization authorization = TestOAuth2Authorizations
.authorization(authorizedRegisteredClient, accessToken, tokenClaims.getClaims())
.build();
when(authorizationService.findByToken(eq(accessToken.getTokenValue()), isNull()))
.thenReturn(authorization);
when(registeredClientRepository.findById(eq(authorizedRegisteredClient.getId())))
.thenReturn(authorizedRegisteredClient);
this.registeredClientRepository.save(authorizedRegisteredClient);
this.authorizationService.save(authorization);
// @formatter:off
MvcResult mvcResult = this.mvc.perform(post(providerSettings.tokenIntrospectionEndpoint())
@ -139,10 +130,6 @@ public class OAuth2TokenIntrospectionTests { @@ -139,10 +130,6 @@ public class OAuth2TokenIntrospectionTests {
.andReturn();
// @formatter:on
verify(registeredClientRepository).findByClientId(eq(introspectRegisteredClient.getClientId()));
verify(authorizationService).findByToken(eq(accessToken.getTokenValue()), isNull());
verify(registeredClientRepository).findById(eq(authorizedRegisteredClient.getId()));
OAuth2TokenIntrospection tokenIntrospectionResponse = readTokenIntrospectionResponse(mvcResult);
assertThat(tokenIntrospectionResponse.isActive()).isTrue();
assertThat(tokenIntrospectionResponse.getClientId()).isEqualTo(authorizedRegisteredClient.getClientId());
@ -165,17 +152,15 @@ public class OAuth2TokenIntrospectionTests { @@ -165,17 +152,15 @@ public class OAuth2TokenIntrospectionTests {
public void requestWhenIntrospectValidRefreshTokenThenActive() throws Exception {
this.spring.register(AuthorizationServerConfiguration.class).autowire();
RegisteredClient introspectRegisteredClient = TestRegisteredClients.registeredClient2().build();
when(registeredClientRepository.findByClientId(eq(introspectRegisteredClient.getClientId())))
.thenReturn(introspectRegisteredClient);
RegisteredClient introspectRegisteredClient = TestRegisteredClients.registeredClient2()
.clientSecret("secret-2").build();
this.registeredClientRepository.save(introspectRegisteredClient);
RegisteredClient authorizedRegisteredClient = TestRegisteredClients.registeredClient().build();
OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(authorizedRegisteredClient).build();
OAuth2RefreshToken refreshToken = authorization.getRefreshToken().getToken();
when(authorizationService.findByToken(eq(refreshToken.getTokenValue()), isNull()))
.thenReturn(authorization);
when(registeredClientRepository.findById(eq(authorizedRegisteredClient.getId())))
.thenReturn(authorizedRegisteredClient);
this.registeredClientRepository.save(authorizedRegisteredClient);
this.authorizationService.save(authorization);
// @formatter:off
MvcResult mvcResult = this.mvc.perform(post(providerSettings.tokenIntrospectionEndpoint())
@ -185,10 +170,6 @@ public class OAuth2TokenIntrospectionTests { @@ -185,10 +170,6 @@ public class OAuth2TokenIntrospectionTests {
.andReturn();
// @formatter:on
verify(registeredClientRepository).findByClientId(eq(introspectRegisteredClient.getClientId()));
verify(authorizationService).findByToken(eq(refreshToken.getTokenValue()), isNull());
verify(registeredClientRepository).findById(eq(authorizedRegisteredClient.getId()));
OAuth2TokenIntrospection tokenIntrospectionResponse = readTokenIntrospectionResponse(mvcResult);
assertThat(tokenIntrospectionResponse.isActive()).isTrue();
assertThat(tokenIntrospectionResponse.getClientId()).isEqualTo(authorizedRegisteredClient.getClientId());
@ -226,13 +207,25 @@ public class OAuth2TokenIntrospectionTests { @@ -226,13 +207,25 @@ public class OAuth2TokenIntrospectionTests {
static class AuthorizationServerConfiguration {
@Bean
RegisteredClientRepository registeredClientRepository() {
return registeredClientRepository;
OAuth2AuthorizationService authorizationService() {
return new InMemoryOAuth2AuthorizationService();
}
@Bean
OAuth2AuthorizationService authorizationService() {
return authorizationService;
OAuth2AuthorizationConsentService authorizationConsentService() {
return new InMemoryOAuth2AuthorizationConsentService();
}
@Bean
RegisteredClientRepository registeredClientRepository() {
// @formatter:off
RegisteredClient dummyClient = TestRegisteredClients.registeredClient()
.id("dummy-client")
.clientId("dummy-client")
.clientSecret("dummy-secret")
.build();
// @formatter:on
return new InMemoryRegisteredClientRepository(dummyClient);
}
@Bean

74
oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2TokenRevocationTests.java

@ -22,11 +22,9 @@ import java.util.Base64; @@ -22,11 +22,9 @@ import java.util.Base64;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.proc.SecurityContext;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@ -43,9 +41,13 @@ import org.springframework.security.oauth2.core.OAuth2RefreshToken; @@ -43,9 +41,13 @@ import org.springframework.security.oauth2.core.OAuth2RefreshToken;
import org.springframework.security.oauth2.core.OAuth2TokenType;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames2;
import org.springframework.security.oauth2.jose.TestJwks;
import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationConsentService;
import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations;
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.client.TestRegisteredClients;
@ -56,12 +58,6 @@ import org.springframework.util.LinkedMultiValueMap; @@ -56,12 +58,6 @@ import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -71,8 +67,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @@ -71,8 +67,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Joe Grandja
*/
public class OAuth2TokenRevocationTests {
private static RegisteredClientRepository registeredClientRepository;
private static OAuth2AuthorizationService authorizationService;
private static JWKSource<SecurityContext> jwkSource;
private static ProviderSettings providerSettings;
@ -82,33 +76,30 @@ public class OAuth2TokenRevocationTests { @@ -82,33 +76,30 @@ public class OAuth2TokenRevocationTests {
@Autowired
private MockMvc mvc;
@Autowired
private RegisteredClientRepository registeredClientRepository;
@Autowired
private OAuth2AuthorizationService authorizationService;
@BeforeClass
public static void init() {
registeredClientRepository = mock(RegisteredClientRepository.class);
authorizationService = mock(OAuth2AuthorizationService.class);
JWKSet jwkSet = new JWKSet(TestJwks.DEFAULT_RSA_JWK);
jwkSource = (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
providerSettings = new ProviderSettings().tokenRevocationEndpoint("/test/revoke");
}
@Before
public void setup() {
reset(registeredClientRepository);
reset(authorizationService);
}
@Test
public void requestWhenRevokeRefreshTokenThenRevoked() throws Exception {
this.spring.register(AuthorizationServerConfiguration.class).autowire();
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
when(registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
.thenReturn(registeredClient);
this.registeredClientRepository.save(registeredClient);
OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build();
OAuth2RefreshToken token = authorization.getRefreshToken().getToken();
OAuth2TokenType tokenType = OAuth2TokenType.REFRESH_TOKEN;
when(authorizationService.findByToken(eq(token.getTokenValue()), isNull())).thenReturn(authorization);
this.authorizationService.save(authorization);
this.mvc.perform(post(OAuth2TokenRevocationEndpointFilter.DEFAULT_TOKEN_REVOCATION_ENDPOINT_URI)
.params(getTokenRevocationRequestParameters(token, tokenType))
@ -116,13 +107,7 @@ public class OAuth2TokenRevocationTests { @@ -116,13 +107,7 @@ public class OAuth2TokenRevocationTests {
registeredClient.getClientId(), registeredClient.getClientSecret())))
.andExpect(status().isOk());
verify(registeredClientRepository).findByClientId(eq(registeredClient.getClientId()));
verify(authorizationService).findByToken(eq(token.getTokenValue()), isNull());
ArgumentCaptor<OAuth2Authorization> authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class);
verify(authorizationService).save(authorizationCaptor.capture());
OAuth2Authorization updatedAuthorization = authorizationCaptor.getValue();
OAuth2Authorization updatedAuthorization = this.authorizationService.findById(authorization.getId());
OAuth2Authorization.Token<OAuth2RefreshToken> refreshToken = updatedAuthorization.getRefreshToken();
assertThat(refreshToken.isInvalidated()).isTrue();
OAuth2Authorization.Token<OAuth2AccessToken> accessToken = updatedAuthorization.getAccessToken();
@ -145,13 +130,12 @@ public class OAuth2TokenRevocationTests { @@ -145,13 +130,12 @@ public class OAuth2TokenRevocationTests {
private void assertRevokeAccessTokenThenRevoked(String tokenRevocationEndpointUri) throws Exception {
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
when(registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
.thenReturn(registeredClient);
this.registeredClientRepository.save(registeredClient);
OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build();
OAuth2AccessToken token = authorization.getAccessToken().getToken();
OAuth2TokenType tokenType = OAuth2TokenType.ACCESS_TOKEN;
when(authorizationService.findByToken(eq(token.getTokenValue()), isNull())).thenReturn(authorization);
this.authorizationService.save(authorization);
this.mvc.perform(post(tokenRevocationEndpointUri)
.params(getTokenRevocationRequestParameters(token, tokenType))
@ -159,13 +143,7 @@ public class OAuth2TokenRevocationTests { @@ -159,13 +143,7 @@ public class OAuth2TokenRevocationTests {
registeredClient.getClientId(), registeredClient.getClientSecret())))
.andExpect(status().isOk());
verify(registeredClientRepository).findByClientId(eq(registeredClient.getClientId()));
verify(authorizationService).findByToken(eq(token.getTokenValue()), isNull());
ArgumentCaptor<OAuth2Authorization> authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class);
verify(authorizationService).save(authorizationCaptor.capture());
OAuth2Authorization updatedAuthorization = authorizationCaptor.getValue();
OAuth2Authorization updatedAuthorization = this.authorizationService.findById(authorization.getId());
OAuth2Authorization.Token<OAuth2AccessToken> accessToken = updatedAuthorization.getAccessToken();
assertThat(accessToken.isInvalidated()).isTrue();
OAuth2Authorization.Token<OAuth2RefreshToken> refreshToken = updatedAuthorization.getRefreshToken();
@ -192,13 +170,25 @@ public class OAuth2TokenRevocationTests { @@ -192,13 +170,25 @@ public class OAuth2TokenRevocationTests {
static class AuthorizationServerConfiguration {
@Bean
RegisteredClientRepository registeredClientRepository() {
return registeredClientRepository;
OAuth2AuthorizationService authorizationService() {
return new InMemoryOAuth2AuthorizationService();
}
@Bean
OAuth2AuthorizationService authorizationService() {
return authorizationService;
OAuth2AuthorizationConsentService authorizationConsentService() {
return new InMemoryOAuth2AuthorizationConsentService();
}
@Bean
RegisteredClientRepository registeredClientRepository() {
// @formatter:off
RegisteredClient dummyClient = TestRegisteredClients.registeredClient()
.id("dummy-client")
.clientId("dummy-client")
.clientSecret("dummy-secret")
.build();
// @formatter:on
return new InMemoryRegisteredClientRepository(dummyClient);
}
@Bean

63
oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcClientRegistrationTests.java

@ -22,11 +22,9 @@ import java.util.Base64; @@ -22,11 +22,9 @@ import java.util.Base64;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.proc.SecurityContext;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@ -46,7 +44,6 @@ import org.springframework.security.crypto.password.PasswordEncoder; @@ -46,7 +44,6 @@ import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.OAuth2TokenType;
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponseType;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
@ -55,8 +52,11 @@ import org.springframework.security.oauth2.core.oidc.OidcClientRegistration; @@ -55,8 +52,11 @@ import org.springframework.security.oauth2.core.oidc.OidcClientRegistration;
import org.springframework.security.oauth2.core.oidc.http.converter.OidcClientRegistrationHttpMessageConverter;
import org.springframework.security.oauth2.jose.TestJwks;
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationConsentService;
import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
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.client.TestRegisteredClients;
@ -67,13 +67,6 @@ import org.springframework.test.web.servlet.MvcResult; @@ -67,13 +67,6 @@ import org.springframework.test.web.servlet.MvcResult;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.CoreMatchers.containsString;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
@ -90,8 +83,6 @@ public class OidcClientRegistrationTests { @@ -90,8 +83,6 @@ public class OidcClientRegistrationTests {
new OAuth2AccessTokenResponseHttpMessageConverter();
private static final HttpMessageConverter<OidcClientRegistration> clientRegistrationHttpMessageConverter =
new OidcClientRegistrationHttpMessageConverter();
private static RegisteredClientRepository registeredClientRepository;
private static OAuth2AuthorizationService authorizationService;
private static JWKSource<SecurityContext> jwkSource;
@Rule
@ -100,20 +91,18 @@ public class OidcClientRegistrationTests { @@ -100,20 +91,18 @@ public class OidcClientRegistrationTests {
@Autowired
private MockMvc mvc;
@Autowired
private RegisteredClientRepository registeredClientRepository;
@Autowired
private OAuth2AuthorizationService authorizationService;
@BeforeClass
public static void init() {
registeredClientRepository = mock(RegisteredClientRepository.class);
authorizationService = mock(OAuth2AuthorizationService.class);
JWKSet jwkSet = new JWKSet(TestJwks.DEFAULT_RSA_JWK);
jwkSource = (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
}
@Before
public void setup() {
reset(registeredClientRepository);
reset(authorizationService);
}
@Test
public void requestWhenClientRegistrationRequestAuthorizedThenClientRegistrationResponse() throws Exception {
this.spring.register(AuthorizationServerConfiguration.class).autowire();
@ -124,8 +113,7 @@ public class OidcClientRegistrationTests { @@ -124,8 +113,7 @@ public class OidcClientRegistrationTests {
RegisteredClient registeredClient = TestRegisteredClients.registeredClient2()
.scope(clientRegistrationScope)
.build();
when(registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
.thenReturn(registeredClient);
this.registeredClientRepository.save(registeredClient);
MvcResult mvcResult = this.mvc.perform(post(OAuth2TokenEndpointFilter.DEFAULT_TOKEN_ENDPOINT_URI)
.param(OAuth2ParameterNames.GRANT_TYPE, AuthorizationGrantType.CLIENT_CREDENTIALS.getValue())
@ -139,17 +127,8 @@ public class OidcClientRegistrationTests { @@ -139,17 +127,8 @@ public class OidcClientRegistrationTests {
OAuth2AccessToken accessToken = readAccessTokenResponse(mvcResult.getResponse()).getAccessToken();
verify(registeredClientRepository).findByClientId(eq(registeredClient.getClientId()));
ArgumentCaptor<OAuth2Authorization> authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class);
verify(authorizationService).save(authorizationCaptor.capture());
OAuth2Authorization authorization = authorizationCaptor.getValue();
// ***** (2) Register the client
when(authorizationService.findByToken(eq(accessToken.getTokenValue()), eq(OAuth2TokenType.ACCESS_TOKEN)))
.thenReturn(authorization);
doNothing().when(registeredClientRepository).save(any(RegisteredClient.class));
// @formatter:off
OidcClientRegistration clientRegistration = OidcClientRegistration.builder()
.clientName("client-name")
@ -225,13 +204,25 @@ public class OidcClientRegistrationTests { @@ -225,13 +204,25 @@ public class OidcClientRegistrationTests {
static class AuthorizationServerConfiguration {
@Bean
RegisteredClientRepository registeredClientRepository() {
return registeredClientRepository;
OAuth2AuthorizationService authorizationService() {
return new InMemoryOAuth2AuthorizationService();
}
@Bean
OAuth2AuthorizationService authorizationService() {
return authorizationService;
OAuth2AuthorizationConsentService authorizationConsentService() {
return new InMemoryOAuth2AuthorizationConsentService();
}
@Bean
RegisteredClientRepository registeredClientRepository() {
// @formatter:off
RegisteredClient dummyClient = TestRegisteredClients.registeredClient()
.id("dummy-client")
.clientId("dummy-client")
.clientSecret("dummy-secret")
.build();
// @formatter:on
return new InMemoryRegisteredClientRepository(dummyClient);
}
@Bean

83
oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcTests.java

@ -15,6 +15,8 @@ @@ -15,6 +15,8 @@
*/
package org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.Principal;
@ -26,11 +28,9 @@ import java.util.stream.Collectors; @@ -26,11 +28,9 @@ import java.util.stream.Collectors;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.proc.SecurityContext;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@ -58,11 +58,15 @@ import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames @@ -58,11 +58,15 @@ import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames
import org.springframework.security.oauth2.jose.TestJwks;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationConsentService;
import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.JwtEncodingContext;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationCode;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.OAuth2TokenCustomizer;
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.client.TestRegisteredClients;
@ -75,17 +79,12 @@ import org.springframework.test.web.servlet.MvcResult; @@ -75,17 +79,12 @@ import org.springframework.test.web.servlet.MvcResult;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
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.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
@ -102,8 +101,6 @@ public class OidcTests { @@ -102,8 +101,6 @@ public class OidcTests {
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 RegisteredClientRepository registeredClientRepository;
private static OAuth2AuthorizationService authorizationService;
private static JWKSource<SecurityContext> jwkSource;
private static HttpMessageConverter<OAuth2AccessTokenResponse> accessTokenHttpResponseConverter =
new OAuth2AccessTokenResponseHttpMessageConverter();
@ -114,23 +111,21 @@ public class OidcTests { @@ -114,23 +111,21 @@ public class OidcTests {
@Autowired
private MockMvc mvc;
@Autowired
private RegisteredClientRepository registeredClientRepository;
@Autowired
private OAuth2AuthorizationService authorizationService;
@Autowired
private JwtDecoder jwtDecoder;
@BeforeClass
public static void init() {
registeredClientRepository = mock(RegisteredClientRepository.class);
authorizationService = mock(OAuth2AuthorizationService.class);
JWKSet jwkSet = new JWKSet(TestJwks.DEFAULT_RSA_JWK);
jwkSource = (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
}
@Before
public void setup() {
reset(registeredClientRepository);
reset(authorizationService);
}
@Test
public void requestWhenConfigurationRequestAndIssuerSetThenReturnConfigurationResponse() throws Exception {
this.spring.register(AuthorizationServerConfigurationWithIssuer.class).autowire();
@ -159,26 +154,18 @@ public class OidcTests { @@ -159,26 +154,18 @@ public class OidcTests {
this.spring.register(AuthorizationServerConfiguration.class).autowire();
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().scope(OidcScopes.OPENID).build();
when(registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
.thenReturn(registeredClient);
this.registeredClientRepository.save(registeredClient);
MvcResult mvcResult = this.mvc.perform(get(OAuth2AuthorizationEndpointFilter.DEFAULT_AUTHORIZATION_ENDPOINT_URI)
.params(getAuthorizationRequestParameters(registeredClient))
.with(user("user").roles("A", "B")))
.andExpect(status().is3xxRedirection())
.andReturn();
assertThat(mvcResult.getResponse().getRedirectedUrl()).matches("https://example.com\\?code=.{15,}&state=state");
verify(registeredClientRepository).findByClientId(eq(registeredClient.getClientId()));
String redirectedUrl = mvcResult.getResponse().getRedirectedUrl();
assertThat(redirectedUrl).matches("https://example.com\\?code=.{15,}&state=state");
ArgumentCaptor<OAuth2Authorization> authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class);
verify(authorizationService).save(authorizationCaptor.capture());
OAuth2Authorization authorization = authorizationCaptor.getValue();
when(authorizationService.findByToken(
eq(authorization.getToken(OAuth2AuthorizationCode.class).getToken().getTokenValue()),
eq(AUTHORIZATION_CODE_TOKEN_TYPE)))
.thenReturn(authorization);
String authorizationCode = extractParameterFromRedirectUri(redirectedUrl, "code");
OAuth2Authorization authorization = this.authorizationService.findByToken(authorizationCode, AUTHORIZATION_CODE_TOKEN_TYPE);
mvcResult = this.mvc.perform(post(OAuth2TokenEndpointFilter.DEFAULT_TOKEN_ENDPOINT_URI)
.params(getTokenRequestParameters(registeredClient, authorization))
@ -195,12 +182,6 @@ public class OidcTests { @@ -195,12 +182,6 @@ public class OidcTests {
.andExpect(jsonPath("$.id_token").isNotEmpty())
.andReturn();
verify(registeredClientRepository, times(2)).findByClientId(eq(registeredClient.getClientId()));
verify(authorizationService).findByToken(
eq(authorization.getToken(OAuth2AuthorizationCode.class).getToken().getTokenValue()),
eq(AUTHORIZATION_CODE_TOKEN_TYPE));
verify(authorizationService, times(2)).save(any());
MockHttpServletResponse servletResponse = mvcResult.getResponse();
MockClientHttpResponse httpResponse = new MockClientHttpResponse(
servletResponse.getContentAsByteArray(), HttpStatus.valueOf(servletResponse.getStatus()));
@ -244,18 +225,36 @@ public class OidcTests { @@ -244,18 +225,36 @@ public class OidcTests {
return new String(encodedBytes, StandardCharsets.UTF_8);
}
private String extractParameterFromRedirectUri(String redirectUri, String param) throws UnsupportedEncodingException {
String locationHeader = URLDecoder.decode(redirectUri, StandardCharsets.UTF_8.name());
UriComponents uriComponents = UriComponentsBuilder.fromUriString(locationHeader).build();
return uriComponents.getQueryParams().getFirst(param);
}
@EnableWebSecurity
@Import(OAuth2AuthorizationServerConfiguration.class)
static class AuthorizationServerConfiguration {
@Bean
RegisteredClientRepository registeredClientRepository() {
return registeredClientRepository;
OAuth2AuthorizationService authorizationService() {
return new InMemoryOAuth2AuthorizationService();
}
@Bean
OAuth2AuthorizationService authorizationService() {
return authorizationService;
OAuth2AuthorizationConsentService authorizationConsentService() {
return new InMemoryOAuth2AuthorizationConsentService();
}
@Bean
RegisteredClientRepository registeredClientRepository() {
// @formatter:off
RegisteredClient dummyClient = TestRegisteredClients.registeredClient()
.id("dummy-client")
.clientId("dummy-client")
.clientSecret("dummy-secret")
.build();
// @formatter:on
return new InMemoryRegisteredClientRepository(dummyClient);
}
@Bean

2
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/TestOAuth2Authorizations.java

@ -28,6 +28,7 @@ import org.springframework.security.oauth2.core.OAuth2AccessToken; @@ -28,6 +28,7 @@ import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.OAuth2RefreshToken;
import org.springframework.security.oauth2.core.OAuth2RefreshToken2;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
import org.springframework.util.CollectionUtils;
@ -80,6 +81,7 @@ public class TestOAuth2Authorizations { @@ -80,6 +81,7 @@ public class TestOAuth2Authorizations {
.token(authorizationCode)
.token(accessToken, (metadata) -> metadata.putAll(tokenMetadata(accessTokenClaims)))
.refreshToken(refreshToken)
.attribute(OAuth2ParameterNames.STATE, "state")
.attribute(OAuth2AuthorizationRequest.class.getName(), authorizationRequest)
.attribute(Principal.class.getName(),
new TestingAuthenticationToken("principal", null, "ROLE_A", "ROLE_B"))

49
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/jackson2/TestingAuthenticationTokenMixin.java

@ -0,0 +1,49 @@ @@ -0,0 +1,49 @@
/*
* Copyright 2002-2021 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.jackson2;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
/**
* This mixin class is used to serialize/deserialize {@link TestingAuthenticationToken}.
*
* @author Steve Riesenberg
* @since 0.1.2
* @see TestingAuthenticationToken
*/
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE,
isGetterVisibility = JsonAutoDetect.Visibility.NONE)
@JsonIgnoreProperties(value = { "authenticated" }, ignoreUnknown = true)
public class TestingAuthenticationTokenMixin {
@JsonCreator
TestingAuthenticationTokenMixin(@JsonProperty("principal") Object principal,
@JsonProperty("credentials") Object credentials,
@JsonProperty("authorities") List<GrantedAuthority> authorities) {
}
}
Loading…
Cancel
Save