Skip to content

Commit 77233da

Browse files
committed
Merge branch '6.3.x'
Closes gh-16139
2 parents 93ce7e9 + 4b41f8c commit 77233da

File tree

4 files changed

+164
-14
lines changed

4 files changed

+164
-14
lines changed

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/InMemoryOAuth2AuthorizedClientService.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -80,7 +80,13 @@ public <T extends OAuth2AuthorizedClient> T loadAuthorizedClient(String clientRe
8080
if (registration == null) {
8181
return null;
8282
}
83-
return (T) this.authorizedClients.get(new OAuth2AuthorizedClientId(clientRegistrationId, principalName));
83+
OAuth2AuthorizedClient cachedAuthorizedClient = this.authorizedClients
84+
.get(new OAuth2AuthorizedClientId(clientRegistrationId, principalName));
85+
if (cachedAuthorizedClient == null) {
86+
return null;
87+
}
88+
return (T) new OAuth2AuthorizedClient(registration, cachedAuthorizedClient.getPrincipalName(),
89+
cachedAuthorizedClient.getAccessToken(), cachedAuthorizedClient.getRefreshToken());
8490
}
8591

8692
@Override

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/InMemoryReactiveOAuth2AuthorizedClientService.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -62,8 +62,15 @@ public <T extends OAuth2AuthorizedClient> Mono<T> loadAuthorizedClient(String cl
6262
Assert.hasText(clientRegistrationId, "clientRegistrationId cannot be empty");
6363
Assert.hasText(principalName, "principalName cannot be empty");
6464
return (Mono<T>) this.clientRegistrationRepository.findByRegistrationId(clientRegistrationId)
65-
.map((clientRegistration) -> new OAuth2AuthorizedClientId(clientRegistrationId, principalName))
66-
.flatMap((identifier) -> Mono.justOrEmpty(this.authorizedClients.get(identifier)));
65+
.mapNotNull((clientRegistration) -> {
66+
OAuth2AuthorizedClientId id = new OAuth2AuthorizedClientId(clientRegistrationId, principalName);
67+
OAuth2AuthorizedClient cachedAuthorizedClient = this.authorizedClients.get(id);
68+
if (cachedAuthorizedClient == null) {
69+
return null;
70+
}
71+
return new OAuth2AuthorizedClient(clientRegistration, cachedAuthorizedClient.getPrincipalName(),
72+
cachedAuthorizedClient.getAccessToken(), cachedAuthorizedClient.getRefreshToken());
73+
});
6774
}
6875

6976
@Override

oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/InMemoryOAuth2AuthorizedClientServiceTests.java

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,22 +18,25 @@
1818

1919
import java.util.Collections;
2020
import java.util.Map;
21+
import java.util.function.Consumer;
2122

2223
import org.junit.jupiter.api.Test;
2324

25+
import org.springframework.security.authentication.TestingAuthenticationToken;
2426
import org.springframework.security.core.Authentication;
2527
import org.springframework.security.oauth2.client.registration.ClientRegistration;
2628
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
2729
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
2830
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
2931
import org.springframework.security.oauth2.core.OAuth2AccessToken;
32+
import org.springframework.security.oauth2.core.OAuth2RefreshToken;
3033

3134
import static org.assertj.core.api.Assertions.assertThat;
3235
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
3336
import static org.assertj.core.api.Assertions.assertThatObject;
3437
import static org.mockito.ArgumentMatchers.eq;
3538
import static org.mockito.BDDMockito.given;
36-
import static org.mockito.Mockito.mock;
39+
import static org.mockito.BDDMockito.mock;
3740

3841
/**
3942
* Tests for {@link InMemoryOAuth2AuthorizedClientService}.
@@ -79,9 +82,11 @@ public void constructorWhenAuthorizedClientsIsNullThenThrowIllegalArgumentExcept
7982
@Test
8083
public void constructorWhenAuthorizedClientsProvidedThenUseProvidedAuthorizedClients() {
8184
String registrationId = this.registration3.getRegistrationId();
85+
OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(this.registration3, this.principalName1,
86+
mock(OAuth2AccessToken.class));
8287
Map<OAuth2AuthorizedClientId, OAuth2AuthorizedClient> authorizedClients = Collections.singletonMap(
8388
new OAuth2AuthorizedClientId(this.registration3.getRegistrationId(), this.principalName1),
84-
mock(OAuth2AuthorizedClient.class));
89+
authorizedClient);
8590
ClientRegistrationRepository clientRegistrationRepository = mock(ClientRegistrationRepository.class);
8691
given(clientRegistrationRepository.findByRegistrationId(eq(registrationId))).willReturn(this.registration3);
8792
InMemoryOAuth2AuthorizedClientService authorizedClientService = new InMemoryOAuth2AuthorizedClientService(
@@ -124,7 +129,35 @@ public void loadAuthorizedClientWhenClientRegistrationFoundAndAssociatedToPrinci
124129
this.authorizedClientService.saveAuthorizedClient(authorizedClient, authentication);
125130
OAuth2AuthorizedClient loadedAuthorizedClient = this.authorizedClientService
126131
.loadAuthorizedClient(this.registration1.getRegistrationId(), this.principalName1);
127-
assertThat(loadedAuthorizedClient).isEqualTo(authorizedClient);
132+
assertThat(loadedAuthorizedClient).satisfies(isEqualTo(authorizedClient));
133+
}
134+
135+
@Test
136+
public void loadAuthorizedClientWhenClientRegistrationIsUpdatedThenReturnAuthorizedClientWithUpdatedClientRegistration() {
137+
ClientRegistration updatedRegistration = ClientRegistration.withClientRegistration(this.registration1)
138+
.clientSecret("updated secret")
139+
.build();
140+
141+
ClientRegistrationRepository clientRegistrationRepository = mock(ClientRegistrationRepository.class);
142+
given(clientRegistrationRepository.findByRegistrationId(this.registration1.getRegistrationId()))
143+
.willReturn(this.registration1, updatedRegistration);
144+
145+
InMemoryOAuth2AuthorizedClientService authorizedClientService = new InMemoryOAuth2AuthorizedClientService(
146+
clientRegistrationRepository);
147+
148+
OAuth2AuthorizedClient cachedAuthorizedClient = new OAuth2AuthorizedClient(this.registration1,
149+
this.principalName1, mock(OAuth2AccessToken.class), mock(OAuth2RefreshToken.class));
150+
authorizedClientService.saveAuthorizedClient(cachedAuthorizedClient,
151+
new TestingAuthenticationToken(this.principalName1, null));
152+
153+
OAuth2AuthorizedClient authorizedClientWithUpdatedRegistration = new OAuth2AuthorizedClient(updatedRegistration,
154+
this.principalName1, mock(OAuth2AccessToken.class), mock(OAuth2RefreshToken.class));
155+
OAuth2AuthorizedClient firstLoadedClient = authorizedClientService
156+
.loadAuthorizedClient(this.registration1.getRegistrationId(), this.principalName1);
157+
OAuth2AuthorizedClient secondLoadedClient = authorizedClientService
158+
.loadAuthorizedClient(this.registration1.getRegistrationId(), this.principalName1);
159+
assertThat(firstLoadedClient).satisfies(isEqualTo(cachedAuthorizedClient));
160+
assertThat(secondLoadedClient).satisfies(isEqualTo(authorizedClientWithUpdatedRegistration));
128161
}
129162

130163
@Test
@@ -148,7 +181,7 @@ public void saveAuthorizedClientWhenSavedThenCanLoad() {
148181
this.authorizedClientService.saveAuthorizedClient(authorizedClient, authentication);
149182
OAuth2AuthorizedClient loadedAuthorizedClient = this.authorizedClientService
150183
.loadAuthorizedClient(this.registration3.getRegistrationId(), this.principalName2);
151-
assertThat(loadedAuthorizedClient).isEqualTo(authorizedClient);
184+
assertThat(loadedAuthorizedClient).satisfies(isEqualTo(authorizedClient));
152185
}
153186

154187
@Test
@@ -180,4 +213,38 @@ public void removeAuthorizedClientWhenSavedThenRemoved() {
180213
assertThat(loadedAuthorizedClient).isNull();
181214
}
182215

216+
private static Consumer<OAuth2AuthorizedClient> isEqualTo(OAuth2AuthorizedClient expected) {
217+
return (actual) -> {
218+
assertThat(actual).isNotNull();
219+
assertThat(actual.getClientRegistration().getRegistrationId())
220+
.isEqualTo(expected.getClientRegistration().getRegistrationId());
221+
assertThat(actual.getClientRegistration().getClientName())
222+
.isEqualTo(expected.getClientRegistration().getClientName());
223+
assertThat(actual.getClientRegistration().getRedirectUri())
224+
.isEqualTo(expected.getClientRegistration().getRedirectUri());
225+
assertThat(actual.getClientRegistration().getAuthorizationGrantType())
226+
.isEqualTo(expected.getClientRegistration().getAuthorizationGrantType());
227+
assertThat(actual.getClientRegistration().getClientAuthenticationMethod())
228+
.isEqualTo(expected.getClientRegistration().getClientAuthenticationMethod());
229+
assertThat(actual.getClientRegistration().getClientId())
230+
.isEqualTo(expected.getClientRegistration().getClientId());
231+
assertThat(actual.getClientRegistration().getClientSecret())
232+
.isEqualTo(expected.getClientRegistration().getClientSecret());
233+
assertThat(actual.getPrincipalName()).isEqualTo(expected.getPrincipalName());
234+
assertThat(actual.getAccessToken().getTokenType()).isEqualTo(expected.getAccessToken().getTokenType());
235+
assertThat(actual.getAccessToken().getTokenValue()).isEqualTo(expected.getAccessToken().getTokenValue());
236+
assertThat(actual.getAccessToken().getIssuedAt()).isEqualTo(expected.getAccessToken().getIssuedAt());
237+
assertThat(actual.getAccessToken().getExpiresAt()).isEqualTo(expected.getAccessToken().getExpiresAt());
238+
assertThat(actual.getAccessToken().getScopes()).isEqualTo(expected.getAccessToken().getScopes());
239+
if (expected.getRefreshToken() != null) {
240+
assertThat(actual.getRefreshToken()).isNotNull();
241+
assertThat(actual.getRefreshToken().getTokenValue())
242+
.isEqualTo(expected.getRefreshToken().getTokenValue());
243+
assertThat(actual.getRefreshToken().getIssuedAt()).isEqualTo(expected.getRefreshToken().getIssuedAt());
244+
assertThat(actual.getRefreshToken().getExpiresAt())
245+
.isEqualTo(expected.getRefreshToken().getExpiresAt());
246+
}
247+
};
248+
}
249+
183250
}

oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/InMemoryReactiveOAuth2AuthorizedClientServiceTests.java

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,12 +18,14 @@
1818

1919
import java.time.Duration;
2020
import java.time.Instant;
21+
import java.util.function.Consumer;
2122

2223
import org.junit.jupiter.api.BeforeEach;
2324
import org.junit.jupiter.api.Test;
2425
import org.junit.jupiter.api.extension.ExtendWith;
2526
import org.mockito.Mock;
2627
import org.mockito.junit.jupiter.MockitoExtension;
28+
import reactor.core.publisher.Flux;
2729
import reactor.core.publisher.Mono;
2830
import reactor.test.StepVerifier;
2931

@@ -34,7 +36,9 @@
3436
import org.springframework.security.oauth2.core.AuthorizationGrantType;
3537
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
3638
import org.springframework.security.oauth2.core.OAuth2AccessToken;
39+
import org.springframework.security.oauth2.core.OAuth2RefreshToken;
3740

41+
import static org.assertj.core.api.Assertions.assertThat;
3842
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
3943
import static org.mockito.BDDMockito.given;
4044

@@ -56,8 +60,9 @@ public class InMemoryReactiveOAuth2AuthorizedClientServiceTests {
5660

5761
private Authentication principal = new TestingAuthenticationToken(this.principalName, "notused");
5862

59-
OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, "token", Instant.now(),
60-
Instant.now().plus(Duration.ofDays(1)));
63+
private OAuth2AccessToken accessToken;
64+
65+
private OAuth2RefreshToken refreshToken;
6166

6267
// @formatter:off
6368
private ClientRegistration clientRegistration = ClientRegistration.withRegistrationId(this.clientRegistrationId)
@@ -79,6 +84,11 @@ public class InMemoryReactiveOAuth2AuthorizedClientServiceTests {
7984
public void setup() {
8085
this.authorizedClientService = new InMemoryReactiveOAuth2AuthorizedClientService(
8186
this.clientRegistrationRepository);
87+
88+
Instant issuedAt = Instant.now();
89+
Instant expiresAt = issuedAt.plus(Duration.ofDays(1));
90+
this.accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, "token", issuedAt, expiresAt);
91+
this.refreshToken = new OAuth2RefreshToken("refresh", issuedAt, expiresAt);
8292
}
8393

8494
@Test
@@ -153,11 +163,37 @@ public void loadAuthorizedClientWhenClientRegistrationFoundThenFound() {
153163
.saveAuthorizedClient(authorizedClient, this.principal)
154164
.then(this.authorizedClientService.loadAuthorizedClient(this.clientRegistrationId, this.principalName));
155165
StepVerifier.create(saveAndLoad)
156-
.expectNext(authorizedClient)
166+
.assertNext(isEqualTo(authorizedClient))
157167
.verifyComplete();
158168
// @formatter:on
159169
}
160170

171+
@Test
172+
@SuppressWarnings("unchecked")
173+
public void loadAuthorizedClientWhenClientRegistrationIsUpdatedThenReturnsAuthorizedClientWithUpdatedClientRegistration() {
174+
ClientRegistration updatedRegistration = ClientRegistration.withClientRegistration(this.clientRegistration)
175+
.clientSecret("updated secret")
176+
.build();
177+
178+
given(this.clientRegistrationRepository.findByRegistrationId(this.clientRegistrationId))
179+
.willReturn(Mono.just(this.clientRegistration), Mono.just(updatedRegistration));
180+
181+
OAuth2AuthorizedClient cachedAuthorizedClient = new OAuth2AuthorizedClient(this.clientRegistration,
182+
this.principalName, this.accessToken, this.refreshToken);
183+
OAuth2AuthorizedClient authorizedClientWithChangedRegistration = new OAuth2AuthorizedClient(updatedRegistration,
184+
this.principalName, this.accessToken, this.refreshToken);
185+
186+
Flux<OAuth2AuthorizedClient> saveAndLoadTwice = this.authorizedClientService
187+
.saveAuthorizedClient(cachedAuthorizedClient, this.principal)
188+
.then(this.authorizedClientService.loadAuthorizedClient(this.clientRegistrationId, this.principalName))
189+
.concatWith(
190+
this.authorizedClientService.loadAuthorizedClient(this.clientRegistrationId, this.principalName));
191+
StepVerifier.create(saveAndLoadTwice)
192+
.assertNext(isEqualTo(cachedAuthorizedClient))
193+
.assertNext(isEqualTo(authorizedClientWithChangedRegistration))
194+
.verifyComplete();
195+
}
196+
161197
@Test
162198
public void saveAuthorizedClientWhenAuthorizedClientNullThenIllegalArgumentException() {
163199
OAuth2AuthorizedClient authorizedClient = null;
@@ -246,4 +282,38 @@ public void removeAuthorizedClientWhenClientRegistrationFoundRemovedThenNotFound
246282
// @formatter:on
247283
}
248284

285+
private static Consumer<OAuth2AuthorizedClient> isEqualTo(OAuth2AuthorizedClient expected) {
286+
return (actual) -> {
287+
assertThat(actual).isNotNull();
288+
assertThat(actual.getClientRegistration().getRegistrationId())
289+
.isEqualTo(expected.getClientRegistration().getRegistrationId());
290+
assertThat(actual.getClientRegistration().getClientName())
291+
.isEqualTo(expected.getClientRegistration().getClientName());
292+
assertThat(actual.getClientRegistration().getRedirectUri())
293+
.isEqualTo(expected.getClientRegistration().getRedirectUri());
294+
assertThat(actual.getClientRegistration().getAuthorizationGrantType())
295+
.isEqualTo(expected.getClientRegistration().getAuthorizationGrantType());
296+
assertThat(actual.getClientRegistration().getClientAuthenticationMethod())
297+
.isEqualTo(expected.getClientRegistration().getClientAuthenticationMethod());
298+
assertThat(actual.getClientRegistration().getClientId())
299+
.isEqualTo(expected.getClientRegistration().getClientId());
300+
assertThat(actual.getClientRegistration().getClientSecret())
301+
.isEqualTo(expected.getClientRegistration().getClientSecret());
302+
assertThat(actual.getPrincipalName()).isEqualTo(expected.getPrincipalName());
303+
assertThat(actual.getAccessToken().getTokenType()).isEqualTo(expected.getAccessToken().getTokenType());
304+
assertThat(actual.getAccessToken().getTokenValue()).isEqualTo(expected.getAccessToken().getTokenValue());
305+
assertThat(actual.getAccessToken().getIssuedAt()).isEqualTo(expected.getAccessToken().getIssuedAt());
306+
assertThat(actual.getAccessToken().getExpiresAt()).isEqualTo(expected.getAccessToken().getExpiresAt());
307+
assertThat(actual.getAccessToken().getScopes()).isEqualTo(expected.getAccessToken().getScopes());
308+
if (expected.getRefreshToken() != null) {
309+
assertThat(actual.getRefreshToken()).isNotNull();
310+
assertThat(actual.getRefreshToken().getTokenValue())
311+
.isEqualTo(expected.getRefreshToken().getTokenValue());
312+
assertThat(actual.getRefreshToken().getIssuedAt()).isEqualTo(expected.getRefreshToken().getIssuedAt());
313+
assertThat(actual.getRefreshToken().getExpiresAt())
314+
.isEqualTo(expected.getRefreshToken().getExpiresAt());
315+
}
316+
};
317+
}
318+
249319
}

0 commit comments

Comments
 (0)