parent
7490a8162b
commit
63f018eb18
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -29,9 +29,9 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
|
||||||
import org.springframework.security.config.oauth2.client.CommonOAuth2Provider
|
import org.springframework.security.config.oauth2.client.CommonOAuth2Provider
|
||||||
import org.springframework.security.config.test.SpringTestContext
|
import org.springframework.security.config.test.SpringTestContext
|
||||||
import org.springframework.security.config.test.SpringTestContextExtension
|
import org.springframework.security.config.test.SpringTestContextExtension
|
||||||
import org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient
|
|
||||||
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient
|
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient
|
||||||
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest
|
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest
|
||||||
|
import org.springframework.security.oauth2.client.endpoint.RestClientAuthorizationCodeTokenResponseClient
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository
|
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository
|
||||||
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository
|
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository
|
||||||
import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository
|
import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository
|
||||||
|
@ -128,7 +128,7 @@ class OAuth2ClientDslTests {
|
||||||
val REQUEST_REPOSITORY: AuthorizationRequestRepository<OAuth2AuthorizationRequest> =
|
val REQUEST_REPOSITORY: AuthorizationRequestRepository<OAuth2AuthorizationRequest> =
|
||||||
HttpSessionOAuth2AuthorizationRequestRepository()
|
HttpSessionOAuth2AuthorizationRequestRepository()
|
||||||
val CLIENT: OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> =
|
val CLIENT: OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> =
|
||||||
DefaultAuthorizationCodeTokenResponseClient()
|
RestClientAuthorizationCodeTokenResponseClient()
|
||||||
val CLIENT_REPOSITORY: OAuth2AuthorizedClientRepository = HttpSessionOAuth2AuthorizedClientRepository()
|
val CLIENT_REPOSITORY: OAuth2AuthorizedClientRepository = HttpSessionOAuth2AuthorizedClientRepository()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -27,13 +27,13 @@ import org.springframework.context.annotation.Bean
|
||||||
import org.springframework.context.annotation.Configuration
|
import org.springframework.context.annotation.Configuration
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
||||||
|
import org.springframework.security.config.annotation.web.invoke
|
||||||
import org.springframework.security.config.oauth2.client.CommonOAuth2Provider
|
import org.springframework.security.config.oauth2.client.CommonOAuth2Provider
|
||||||
import org.springframework.security.config.test.SpringTestContext
|
import org.springframework.security.config.test.SpringTestContext
|
||||||
import org.springframework.security.config.test.SpringTestContextExtension
|
import org.springframework.security.config.test.SpringTestContextExtension
|
||||||
import org.springframework.security.config.annotation.web.invoke
|
|
||||||
import org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient
|
|
||||||
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient
|
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient
|
||||||
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest
|
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest
|
||||||
|
import org.springframework.security.oauth2.client.endpoint.RestClientAuthorizationCodeTokenResponseClient
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository
|
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository
|
||||||
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository
|
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository
|
||||||
import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository
|
import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository
|
||||||
|
@ -175,7 +175,7 @@ class AuthorizationCodeGrantDslTests {
|
||||||
val REQUEST_REPOSITORY: AuthorizationRequestRepository<OAuth2AuthorizationRequest> =
|
val REQUEST_REPOSITORY: AuthorizationRequestRepository<OAuth2AuthorizationRequest> =
|
||||||
HttpSessionOAuth2AuthorizationRequestRepository()
|
HttpSessionOAuth2AuthorizationRequestRepository()
|
||||||
val CLIENT: OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> =
|
val CLIENT: OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> =
|
||||||
DefaultAuthorizationCodeTokenResponseClient()
|
RestClientAuthorizationCodeTokenResponseClient()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -25,14 +25,14 @@ import org.springframework.context.annotation.Bean
|
||||||
import org.springframework.context.annotation.Configuration
|
import org.springframework.context.annotation.Configuration
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
||||||
|
import org.springframework.security.config.annotation.web.invoke
|
||||||
import org.springframework.security.config.oauth2.client.CommonOAuth2Provider
|
import org.springframework.security.config.oauth2.client.CommonOAuth2Provider
|
||||||
import org.springframework.security.config.test.SpringTestContext
|
import org.springframework.security.config.test.SpringTestContext
|
||||||
import org.springframework.security.config.test.SpringTestContextExtension
|
import org.springframework.security.config.test.SpringTestContextExtension
|
||||||
import org.springframework.security.config.annotation.web.invoke
|
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority
|
import org.springframework.security.core.authority.SimpleGrantedAuthority
|
||||||
import org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient
|
|
||||||
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient
|
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient
|
||||||
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest
|
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest
|
||||||
|
import org.springframework.security.oauth2.client.endpoint.RestClientAuthorizationCodeTokenResponseClient
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository
|
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository
|
||||||
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository
|
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository
|
||||||
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService
|
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService
|
||||||
|
@ -110,7 +110,7 @@ class RedirectionEndpointDslTests {
|
||||||
val REPOSITORY: AuthorizationRequestRepository<OAuth2AuthorizationRequest> =
|
val REPOSITORY: AuthorizationRequestRepository<OAuth2AuthorizationRequest> =
|
||||||
HttpSessionOAuth2AuthorizationRequestRepository()
|
HttpSessionOAuth2AuthorizationRequestRepository()
|
||||||
val CLIENT: OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> =
|
val CLIENT: OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> =
|
||||||
DefaultAuthorizationCodeTokenResponseClient()
|
RestClientAuthorizationCodeTokenResponseClient()
|
||||||
val USER_SERVICE: OAuth2UserService<OAuth2UserRequest, OAuth2User> = DefaultOAuth2UserService()
|
val USER_SERVICE: OAuth2UserService<OAuth2UserRequest, OAuth2User> = DefaultOAuth2UserService()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -26,13 +26,13 @@ import org.springframework.context.annotation.Bean
|
||||||
import org.springframework.context.annotation.Configuration
|
import org.springframework.context.annotation.Configuration
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
||||||
|
import org.springframework.security.config.annotation.web.invoke
|
||||||
import org.springframework.security.config.oauth2.client.CommonOAuth2Provider
|
import org.springframework.security.config.oauth2.client.CommonOAuth2Provider
|
||||||
import org.springframework.security.config.test.SpringTestContext
|
import org.springframework.security.config.test.SpringTestContext
|
||||||
import org.springframework.security.config.test.SpringTestContextExtension
|
import org.springframework.security.config.test.SpringTestContextExtension
|
||||||
import org.springframework.security.config.annotation.web.invoke
|
|
||||||
import org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient
|
|
||||||
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient
|
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient
|
||||||
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest
|
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest
|
||||||
|
import org.springframework.security.oauth2.client.endpoint.RestClientAuthorizationCodeTokenResponseClient
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository
|
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository
|
||||||
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository
|
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository
|
||||||
import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository
|
import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository
|
||||||
|
@ -101,7 +101,7 @@ class TokenEndpointDslTests {
|
||||||
val REPOSITORY: AuthorizationRequestRepository<OAuth2AuthorizationRequest> =
|
val REPOSITORY: AuthorizationRequestRepository<OAuth2AuthorizationRequest> =
|
||||||
HttpSessionOAuth2AuthorizationRequestRepository()
|
HttpSessionOAuth2AuthorizationRequestRepository()
|
||||||
val CLIENT: OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> =
|
val CLIENT: OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> =
|
||||||
DefaultAuthorizationCodeTokenResponseClient()
|
RestClientAuthorizationCodeTokenResponseClient()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2019 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -18,35 +18,40 @@ package org.springframework.security.oauth2.client;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.http.RequestEntity;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.converter.FormHttpMessageConverter;
|
||||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.oauth2.client.endpoint.DefaultClientCredentialsTokenResponseClient;
|
|
||||||
import org.springframework.security.oauth2.client.endpoint.DefaultPasswordTokenResponseClient;
|
import org.springframework.security.oauth2.client.endpoint.DefaultPasswordTokenResponseClient;
|
||||||
import org.springframework.security.oauth2.client.endpoint.DefaultRefreshTokenTokenResponseClient;
|
import org.springframework.security.oauth2.client.endpoint.RestClientClientCredentialsTokenResponseClient;
|
||||||
|
import org.springframework.security.oauth2.client.endpoint.RestClientRefreshTokenTokenResponseClient;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||||
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
|
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
|
||||||
import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
||||||
import org.springframework.security.oauth2.core.TestOAuth2RefreshTokens;
|
import org.springframework.security.oauth2.core.TestOAuth2RefreshTokens;
|
||||||
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
|
import org.springframework.security.oauth2.core.http.converter.OAuth2AccessTokenResponseHttpMessageConverter;
|
||||||
import org.springframework.security.oauth2.core.endpoint.TestOAuth2AccessTokenResponses;
|
import org.springframework.test.web.client.ExpectedCount;
|
||||||
import org.springframework.web.client.RestOperations;
|
import org.springframework.test.web.client.MockRestServiceServer;
|
||||||
|
import org.springframework.web.client.RestClient;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
|
||||||
import static org.mockito.BDDMockito.given;
|
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.springframework.test.web.client.ExpectedCount.once;
|
||||||
|
import static org.springframework.test.web.client.ExpectedCount.times;
|
||||||
|
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
|
||||||
|
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link OAuth2AuthorizedClientProviderBuilder}.
|
* Tests for {@link OAuth2AuthorizedClientProviderBuilder}.
|
||||||
|
@ -55,29 +60,30 @@ import static org.mockito.Mockito.verify;
|
||||||
*/
|
*/
|
||||||
public class OAuth2AuthorizedClientProviderBuilderTests {
|
public class OAuth2AuthorizedClientProviderBuilderTests {
|
||||||
|
|
||||||
private RestOperations accessTokenClient;
|
private RestClientClientCredentialsTokenResponseClient clientCredentialsTokenResponseClient;
|
||||||
|
|
||||||
private DefaultClientCredentialsTokenResponseClient clientCredentialsTokenResponseClient;
|
private RestClientRefreshTokenTokenResponseClient refreshTokenTokenResponseClient;
|
||||||
|
|
||||||
private DefaultRefreshTokenTokenResponseClient refreshTokenTokenResponseClient;
|
|
||||||
|
|
||||||
private DefaultPasswordTokenResponseClient passwordTokenResponseClient;
|
private DefaultPasswordTokenResponseClient passwordTokenResponseClient;
|
||||||
|
|
||||||
private Authentication principal;
|
private Authentication principal;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
private MockRestServiceServer server;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setup() {
|
public void setup() {
|
||||||
OAuth2AccessTokenResponse accessTokenResponse = TestOAuth2AccessTokenResponses.accessTokenResponse().build();
|
// TODO: Use of RestTemplate in these tests can be removed when
|
||||||
this.accessTokenClient = mock(RestOperations.class);
|
// DefaultPasswordTokenResponseClient is removed.
|
||||||
given(this.accessTokenClient.exchange(any(RequestEntity.class), eq(OAuth2AccessTokenResponse.class)))
|
RestTemplate accessTokenClient = new RestTemplate(
|
||||||
.willReturn(new ResponseEntity(accessTokenResponse, HttpStatus.OK));
|
List.of(new FormHttpMessageConverter(), new OAuth2AccessTokenResponseHttpMessageConverter()));
|
||||||
this.refreshTokenTokenResponseClient = new DefaultRefreshTokenTokenResponseClient();
|
this.server = MockRestServiceServer.bindTo(accessTokenClient).build();
|
||||||
this.refreshTokenTokenResponseClient.setRestOperations(this.accessTokenClient);
|
RestClient restClient = RestClient.create(accessTokenClient);
|
||||||
this.clientCredentialsTokenResponseClient = new DefaultClientCredentialsTokenResponseClient();
|
this.refreshTokenTokenResponseClient = new RestClientRefreshTokenTokenResponseClient();
|
||||||
this.clientCredentialsTokenResponseClient.setRestOperations(this.accessTokenClient);
|
this.refreshTokenTokenResponseClient.setRestClient(restClient);
|
||||||
|
this.clientCredentialsTokenResponseClient = new RestClientClientCredentialsTokenResponseClient();
|
||||||
|
this.clientCredentialsTokenResponseClient.setRestClient(restClient);
|
||||||
this.passwordTokenResponseClient = new DefaultPasswordTokenResponseClient();
|
this.passwordTokenResponseClient = new DefaultPasswordTokenResponseClient();
|
||||||
this.passwordTokenResponseClient.setRestOperations(this.accessTokenClient);
|
this.passwordTokenResponseClient.setRestOperations(accessTokenClient);
|
||||||
this.principal = new TestingAuthenticationToken("principal", "password");
|
this.principal = new TestingAuthenticationToken("principal", "password");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,6 +110,8 @@ public class OAuth2AuthorizedClientProviderBuilderTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void buildWhenRefreshTokenProviderThenProviderReauthorizes() {
|
public void buildWhenRefreshTokenProviderThenProviderReauthorizes() {
|
||||||
|
mockAccessTokenResponse(once());
|
||||||
|
|
||||||
OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
|
OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
|
||||||
.refreshToken((configurer) -> configurer.accessTokenResponseClient(this.refreshTokenTokenResponseClient))
|
.refreshToken((configurer) -> configurer.accessTokenResponseClient(this.refreshTokenTokenResponseClient))
|
||||||
.build();
|
.build();
|
||||||
|
@ -118,11 +126,13 @@ public class OAuth2AuthorizedClientProviderBuilderTests {
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
OAuth2AuthorizedClient reauthorizedClient = authorizedClientProvider.authorize(authorizationContext);
|
OAuth2AuthorizedClient reauthorizedClient = authorizedClientProvider.authorize(authorizationContext);
|
||||||
assertThat(reauthorizedClient).isNotNull();
|
assertThat(reauthorizedClient).isNotNull();
|
||||||
verify(this.accessTokenClient).exchange(any(RequestEntity.class), eq(OAuth2AccessTokenResponse.class));
|
this.server.verify();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void buildWhenClientCredentialsProviderThenProviderAuthorizes() {
|
public void buildWhenClientCredentialsProviderThenProviderAuthorizes() {
|
||||||
|
mockAccessTokenResponse(once());
|
||||||
|
|
||||||
OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
|
OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
|
||||||
.clientCredentials(
|
.clientCredentials(
|
||||||
(configurer) -> configurer.accessTokenResponseClient(this.clientCredentialsTokenResponseClient))
|
(configurer) -> configurer.accessTokenResponseClient(this.clientCredentialsTokenResponseClient))
|
||||||
|
@ -135,11 +145,13 @@ public class OAuth2AuthorizedClientProviderBuilderTests {
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
OAuth2AuthorizedClient authorizedClient = authorizedClientProvider.authorize(authorizationContext);
|
OAuth2AuthorizedClient authorizedClient = authorizedClientProvider.authorize(authorizationContext);
|
||||||
assertThat(authorizedClient).isNotNull();
|
assertThat(authorizedClient).isNotNull();
|
||||||
verify(this.accessTokenClient).exchange(any(RequestEntity.class), eq(OAuth2AccessTokenResponse.class));
|
this.server.verify();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void buildWhenPasswordProviderThenProviderAuthorizes() {
|
public void buildWhenPasswordProviderThenProviderAuthorizes() {
|
||||||
|
mockAccessTokenResponse(once());
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
|
OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
|
||||||
.password((configurer) -> configurer.accessTokenResponseClient(this.passwordTokenResponseClient))
|
.password((configurer) -> configurer.accessTokenResponseClient(this.passwordTokenResponseClient))
|
||||||
|
@ -153,11 +165,13 @@ public class OAuth2AuthorizedClientProviderBuilderTests {
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
OAuth2AuthorizedClient authorizedClient = authorizedClientProvider.authorize(authorizationContext);
|
OAuth2AuthorizedClient authorizedClient = authorizedClientProvider.authorize(authorizationContext);
|
||||||
assertThat(authorizedClient).isNotNull();
|
assertThat(authorizedClient).isNotNull();
|
||||||
verify(this.accessTokenClient).exchange(any(RequestEntity.class), eq(OAuth2AccessTokenResponse.class));
|
this.server.verify();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void buildWhenAllProvidersThenProvidersAuthorize() {
|
public void buildWhenAllProvidersThenProvidersAuthorize() {
|
||||||
|
mockAccessTokenResponse(times(3));
|
||||||
|
|
||||||
OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
|
OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
|
||||||
.authorizationCode()
|
.authorizationCode()
|
||||||
.refreshToken((configurer) -> configurer.accessTokenResponseClient(this.refreshTokenTokenResponseClient))
|
.refreshToken((configurer) -> configurer.accessTokenResponseClient(this.refreshTokenTokenResponseClient))
|
||||||
|
@ -184,8 +198,6 @@ public class OAuth2AuthorizedClientProviderBuilderTests {
|
||||||
.build();
|
.build();
|
||||||
OAuth2AuthorizedClient reauthorizedClient = authorizedClientProvider.authorize(refreshTokenContext);
|
OAuth2AuthorizedClient reauthorizedClient = authorizedClientProvider.authorize(refreshTokenContext);
|
||||||
assertThat(reauthorizedClient).isNotNull();
|
assertThat(reauthorizedClient).isNotNull();
|
||||||
verify(this.accessTokenClient, times(1)).exchange(any(RequestEntity.class),
|
|
||||||
eq(OAuth2AccessTokenResponse.class));
|
|
||||||
// client_credentials
|
// client_credentials
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
OAuth2AuthorizationContext clientCredentialsContext = OAuth2AuthorizationContext
|
OAuth2AuthorizationContext clientCredentialsContext = OAuth2AuthorizationContext
|
||||||
|
@ -195,8 +207,6 @@ public class OAuth2AuthorizedClientProviderBuilderTests {
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
authorizedClient = authorizedClientProvider.authorize(clientCredentialsContext);
|
authorizedClient = authorizedClientProvider.authorize(clientCredentialsContext);
|
||||||
assertThat(authorizedClient).isNotNull();
|
assertThat(authorizedClient).isNotNull();
|
||||||
verify(this.accessTokenClient, times(2)).exchange(any(RequestEntity.class),
|
|
||||||
eq(OAuth2AccessTokenResponse.class));
|
|
||||||
// password
|
// password
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
OAuth2AuthorizationContext passwordContext = OAuth2AuthorizationContext
|
OAuth2AuthorizationContext passwordContext = OAuth2AuthorizationContext
|
||||||
|
@ -208,8 +218,7 @@ public class OAuth2AuthorizedClientProviderBuilderTests {
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
authorizedClient = authorizedClientProvider.authorize(passwordContext);
|
authorizedClient = authorizedClientProvider.authorize(passwordContext);
|
||||||
assertThat(authorizedClient).isNotNull();
|
assertThat(authorizedClient).isNotNull();
|
||||||
verify(this.accessTokenClient, times(3)).exchange(any(RequestEntity.class),
|
this.server.verify();
|
||||||
eq(OAuth2AccessTokenResponse.class));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -234,4 +243,10 @@ public class OAuth2AuthorizedClientProviderBuilderTests {
|
||||||
return new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, "access-token-1234", issuedAt, expiresAt);
|
return new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, "access-token-1234", issuedAt, expiresAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void mockAccessTokenResponse(ExpectedCount expectedCount) {
|
||||||
|
this.server.expect(expectedCount, requestTo("https://example.com/login/oauth/access_token"))
|
||||||
|
.andRespond(withSuccess().header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
.body(new ClassPathResource("access-token-response.json")));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -43,11 +43,11 @@ import reactor.util.context.Context;
|
||||||
|
|
||||||
import org.springframework.core.codec.ByteBufferEncoder;
|
import org.springframework.core.codec.ByteBufferEncoder;
|
||||||
import org.springframework.core.codec.CharSequenceEncoder;
|
import org.springframework.core.codec.CharSequenceEncoder;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.RequestEntity;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.http.codec.EncoderHttpMessageWriter;
|
import org.springframework.http.codec.EncoderHttpMessageWriter;
|
||||||
import org.springframework.http.codec.FormHttpMessageWriter;
|
import org.springframework.http.codec.FormHttpMessageWriter;
|
||||||
import org.springframework.http.codec.HttpMessageWriter;
|
import org.springframework.http.codec.HttpMessageWriter;
|
||||||
|
@ -55,6 +55,7 @@ import org.springframework.http.codec.ResourceHttpMessageWriter;
|
||||||
import org.springframework.http.codec.ServerSentEventHttpMessageWriter;
|
import org.springframework.http.codec.ServerSentEventHttpMessageWriter;
|
||||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||||
import org.springframework.http.codec.multipart.MultipartHttpMessageWriter;
|
import org.springframework.http.codec.multipart.MultipartHttpMessageWriter;
|
||||||
|
import org.springframework.http.converter.FormHttpMessageConverter;
|
||||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||||
import org.springframework.mock.http.client.reactive.MockClientHttpRequest;
|
import org.springframework.mock.http.client.reactive.MockClientHttpRequest;
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
|
@ -75,12 +76,12 @@ import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder;
|
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder;
|
||||||
import org.springframework.security.oauth2.client.RefreshTokenOAuth2AuthorizedClientProvider;
|
import org.springframework.security.oauth2.client.RefreshTokenOAuth2AuthorizedClientProvider;
|
||||||
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
||||||
import org.springframework.security.oauth2.client.endpoint.DefaultRefreshTokenTokenResponseClient;
|
|
||||||
import org.springframework.security.oauth2.client.endpoint.JwtBearerGrantRequest;
|
import org.springframework.security.oauth2.client.endpoint.JwtBearerGrantRequest;
|
||||||
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
|
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
|
||||||
import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequest;
|
import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequest;
|
||||||
import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest;
|
import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest;
|
||||||
import org.springframework.security.oauth2.client.endpoint.OAuth2RefreshTokenGrantRequest;
|
import org.springframework.security.oauth2.client.endpoint.OAuth2RefreshTokenGrantRequest;
|
||||||
|
import org.springframework.security.oauth2.client.endpoint.RestClientRefreshTokenTokenResponseClient;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
||||||
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
|
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
|
||||||
|
@ -96,11 +97,13 @@ import org.springframework.security.oauth2.core.OAuth2RefreshToken;
|
||||||
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
|
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
|
||||||
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
||||||
import org.springframework.security.oauth2.core.endpoint.TestOAuth2AccessTokenResponses;
|
import org.springframework.security.oauth2.core.endpoint.TestOAuth2AccessTokenResponses;
|
||||||
|
import org.springframework.security.oauth2.core.http.converter.OAuth2AccessTokenResponseHttpMessageConverter;
|
||||||
import org.springframework.security.oauth2.core.user.OAuth2User;
|
import org.springframework.security.oauth2.core.user.OAuth2User;
|
||||||
import org.springframework.security.oauth2.jwt.Jwt;
|
import org.springframework.security.oauth2.jwt.Jwt;
|
||||||
import org.springframework.security.oauth2.jwt.TestJwts;
|
import org.springframework.security.oauth2.jwt.TestJwts;
|
||||||
|
import org.springframework.test.web.client.MockRestServiceServer;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.client.RestOperations;
|
import org.springframework.web.client.RestClient;
|
||||||
import org.springframework.web.context.request.RequestContextHolder;
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
import org.springframework.web.reactive.function.BodyInserter;
|
import org.springframework.web.reactive.function.BodyInserter;
|
||||||
|
@ -121,6 +124,8 @@ import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.verifyNoInteractions;
|
import static org.mockito.Mockito.verifyNoInteractions;
|
||||||
|
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
|
||||||
|
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
|
@ -357,11 +362,18 @@ public class ServletOAuth2AuthorizedClientExchangeFilterFunctionTests {
|
||||||
.expiresIn(3600)
|
.expiresIn(3600)
|
||||||
// .refreshToken(xxx) // No refreshToken in response
|
// .refreshToken(xxx) // No refreshToken in response
|
||||||
.build();
|
.build();
|
||||||
RestOperations refreshTokenClient = mock(RestOperations.class);
|
RestClient.Builder builder = RestClient.builder().messageConverters((messageConverters) -> {
|
||||||
given(refreshTokenClient.exchange(any(RequestEntity.class), eq(OAuth2AccessTokenResponse.class)))
|
messageConverters.clear();
|
||||||
.willReturn(new ResponseEntity(response, HttpStatus.OK));
|
messageConverters.add(new FormHttpMessageConverter());
|
||||||
DefaultRefreshTokenTokenResponseClient refreshTokenTokenResponseClient = new DefaultRefreshTokenTokenResponseClient();
|
messageConverters.add(new OAuth2AccessTokenResponseHttpMessageConverter());
|
||||||
refreshTokenTokenResponseClient.setRestOperations(refreshTokenClient);
|
});
|
||||||
|
MockRestServiceServer server = MockRestServiceServer.bindTo(builder).build();
|
||||||
|
RestClient refreshTokenClient = builder.build();
|
||||||
|
server.expect(requestTo("https://example.com/login/oauth/access_token"))
|
||||||
|
.andRespond(withSuccess().header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
.body(new ClassPathResource("access-token-response-1.json")));
|
||||||
|
RestClientRefreshTokenTokenResponseClient refreshTokenTokenResponseClient = new RestClientRefreshTokenTokenResponseClient();
|
||||||
|
refreshTokenTokenResponseClient.setRestClient(refreshTokenClient);
|
||||||
RefreshTokenOAuth2AuthorizedClientProvider authorizedClientProvider = new RefreshTokenOAuth2AuthorizedClientProvider();
|
RefreshTokenOAuth2AuthorizedClientProvider authorizedClientProvider = new RefreshTokenOAuth2AuthorizedClientProvider();
|
||||||
authorizedClientProvider.setAccessTokenResponseClient(refreshTokenTokenResponseClient);
|
authorizedClientProvider.setAccessTokenResponseClient(refreshTokenTokenResponseClient);
|
||||||
DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager(
|
DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager(
|
||||||
|
@ -384,11 +396,12 @@ public class ServletOAuth2AuthorizedClientExchangeFilterFunctionTests {
|
||||||
.httpServletResponse(new MockHttpServletResponse()))
|
.httpServletResponse(new MockHttpServletResponse()))
|
||||||
.build();
|
.build();
|
||||||
this.function.filter(request, this.exchange).block();
|
this.function.filter(request, this.exchange).block();
|
||||||
verify(refreshTokenClient).exchange(any(RequestEntity.class), eq(OAuth2AccessTokenResponse.class));
|
server.verify();
|
||||||
verify(this.authorizedClientRepository).saveAuthorizedClient(this.authorizedClientCaptor.capture(),
|
verify(this.authorizedClientRepository).saveAuthorizedClient(this.authorizedClientCaptor.capture(),
|
||||||
eq(this.authentication), any(), any());
|
eq(this.authentication), any(), any());
|
||||||
OAuth2AuthorizedClient newAuthorizedClient = this.authorizedClientCaptor.getValue();
|
OAuth2AuthorizedClient newAuthorizedClient = this.authorizedClientCaptor.getValue();
|
||||||
assertThat(newAuthorizedClient.getAccessToken()).isEqualTo(response.getAccessToken());
|
assertThat(newAuthorizedClient.getAccessToken().getTokenValue())
|
||||||
|
.isEqualTo(response.getAccessToken().getTokenValue());
|
||||||
assertThat(newAuthorizedClient.getRefreshToken().getTokenValue()).isEqualTo(refreshToken.getTokenValue());
|
assertThat(newAuthorizedClient.getRefreshToken().getTokenValue()).isEqualTo(refreshToken.getTokenValue());
|
||||||
List<ClientRequest> requests = this.exchange.getRequests();
|
List<ClientRequest> requests = this.exchange.getRequests();
|
||||||
assertThat(requests).hasSize(1);
|
assertThat(requests).hasSize(1);
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"access_token": "token-1",
|
||||||
|
"token_type": "Bearer",
|
||||||
|
"expires_in": 3600
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"access_token": "token",
|
||||||
|
"token_type": "Bearer",
|
||||||
|
"expires_in": 3600
|
||||||
|
}
|
Loading…
Reference in New Issue