Skip to content

Commit 08d2c93

Browse files
committed
Polish gh-7466
1 parent 9bae0a4 commit 08d2c93

File tree

3 files changed

+85
-99
lines changed

3 files changed

+85
-99
lines changed

config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@
7676
import org.springframework.security.oauth2.client.web.server.AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository;
7777
import org.springframework.security.oauth2.client.web.server.OAuth2AuthorizationCodeGrantWebFilter;
7878
import org.springframework.security.oauth2.client.web.server.OAuth2AuthorizationRequestRedirectWebFilter;
79-
import org.springframework.security.oauth2.client.web.server.ServerAuthorizationRequestRepository;
8079
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizationCodeAuthenticationTokenConverter;
8180
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizationRequestResolver;
8281
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
@@ -1106,13 +1105,14 @@ public OAuth2LoginSpec authorizedClientRepository(ServerOAuth2AuthorizedClientRe
11061105
}
11071106

11081107
/**
1109-
* Sets authorization request repository for {@link OAuth2AuthorizationRequestRedirectWebFilter}.
1108+
* Sets the repository to use for storing {@link OAuth2AuthorizationRequest}'s.
11101109
*
1111-
* @param authorizationRequestRepository authorization request repository, must not be null
1110+
* @since 5.2
1111+
* @param authorizationRequestRepository the repository to use for storing {@link OAuth2AuthorizationRequest}'s
11121112
* @return the {@link OAuth2LoginSpec} for further configuration
11131113
*/
1114-
public OAuth2LoginSpec authorizationRequestRepository(ServerAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository) {
1115-
Assert.notNull(authorizationRequestRepository, "authorizationRequestRepository cannot be null");
1114+
public OAuth2LoginSpec authorizationRequestRepository(
1115+
ServerAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository) {
11161116
this.authorizationRequestRepository = authorizationRequestRepository;
11171117
return this;
11181118
}
@@ -1163,9 +1163,7 @@ protected void configure(ServerHttpSecurity http) {
11631163
OAuth2AuthorizationRequestRedirectWebFilter oauthRedirectFilter = getRedirectWebFilter();
11641164
ServerAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository =
11651165
getAuthorizationRequestRepository();
1166-
if (authorizationRequestRepository != null) {
1167-
oauthRedirectFilter.setAuthorizationRequestRepository(authorizationRequestRepository);
1168-
}
1166+
oauthRedirectFilter.setAuthorizationRequestRepository(authorizationRequestRepository);
11691167
oauthRedirectFilter.setRequestCache(http.requestCache.requestCache);
11701168

11711169
ReactiveAuthenticationManager manager = getAuthenticationManager();
@@ -1267,10 +1265,9 @@ private ServerOAuth2AuthorizedClientRepository getAuthorizedClientRepository() {
12671265
return result;
12681266
}
12691267

1270-
@SuppressWarnings("unchecked")
12711268
private ServerAuthorizationRequestRepository<OAuth2AuthorizationRequest> getAuthorizationRequestRepository() {
12721269
if (this.authorizationRequestRepository == null) {
1273-
this.authorizationRequestRepository = getBeanOrNull(ServerAuthorizationRequestRepository.class);
1270+
this.authorizationRequestRepository = new WebSessionOAuth2ServerAuthorizationRequestRepository();
12741271
}
12751272
return this.authorizationRequestRepository;
12761273
}

config/src/test/java/org/springframework/security/config/web/server/OAuth2LoginTests.java

Lines changed: 75 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,10 @@
1616

1717
package org.springframework.security.config.web.server;
1818

19-
import java.util.Collections;
20-
import java.util.HashMap;
21-
import java.util.Map;
22-
2319
import org.junit.Rule;
2420
import org.junit.Test;
2521
import org.mockito.stubbing.Answer;
2622
import org.openqa.selenium.WebDriver;
27-
import reactor.core.publisher.Mono;
28-
2923
import org.springframework.beans.factory.annotation.Autowired;
3024
import org.springframework.context.ApplicationContext;
3125
import org.springframework.context.annotation.Bean;
@@ -41,6 +35,8 @@
4135
import org.springframework.security.core.context.SecurityContext;
4236
import org.springframework.security.core.context.SecurityContextImpl;
4337
import org.springframework.security.htmlunit.server.WebTestClientHtmlUnitDriverBuilder;
38+
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
39+
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
4440
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
4541
import org.springframework.security.oauth2.client.authentication.OAuth2AuthorizationCodeAuthenticationToken;
4642
import org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationToken;
@@ -53,7 +49,9 @@
5349
import org.springframework.security.oauth2.client.registration.InMemoryReactiveClientRegistrationRepository;
5450
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
5551
import org.springframework.security.oauth2.client.userinfo.ReactiveOAuth2UserService;
52+
import org.springframework.security.oauth2.client.web.server.ServerAuthorizationRequestRepository;
5653
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizationRequestResolver;
54+
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
5755
import org.springframework.security.oauth2.core.OAuth2AccessToken;
5856
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
5957
import org.springframework.security.oauth2.core.OAuth2Error;
@@ -84,20 +82,25 @@
8482
import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler;
8583
import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler;
8684
import org.springframework.security.web.server.context.ServerSecurityContextRepository;
85+
import org.springframework.security.web.server.savedrequest.ServerRequestCache;
8786
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher;
8887
import org.springframework.test.web.reactive.server.WebTestClient;
88+
import org.springframework.web.bind.annotation.GetMapping;
89+
import org.springframework.web.bind.annotation.RestController;
8990
import org.springframework.web.reactive.config.EnableWebFlux;
9091
import org.springframework.web.server.ServerWebExchange;
9192
import org.springframework.web.server.WebFilter;
9293
import org.springframework.web.server.WebFilterChain;
9394
import org.springframework.web.server.WebHandler;
95+
import reactor.core.publisher.Mono;
96+
97+
import java.util.Collections;
98+
import java.util.HashMap;
99+
import java.util.Map;
94100

95101
import static org.assertj.core.api.Assertions.assertThat;
96102
import static org.mockito.ArgumentMatchers.any;
97-
import static org.mockito.Mockito.mock;
98-
import static org.mockito.Mockito.spy;
99-
import static org.mockito.Mockito.verify;
100-
import static org.mockito.Mockito.when;
103+
import static org.mockito.Mockito.*;
101104
import static org.springframework.security.oauth2.jwt.TestJwts.jwt;
102105

103106
/**
@@ -189,6 +192,68 @@ InMemoryReactiveClientRegistrationRepository clientRegistrationRepository() {
189192
}
190193
}
191194

195+
@Test
196+
public void oauth2AuthorizeWhenCustomObjectsThenUsed() {
197+
this.spring.register(OAuth2LoginWithSingleClientRegistrations.class,
198+
OAuth2AuthorizeWithMockObjectsConfig.class,
199+
AuthorizedClientController.class).autowire();
200+
201+
OAuth2AuthorizeWithMockObjectsConfig config = this.spring.getContext().getBean(OAuth2AuthorizeWithMockObjectsConfig.class);
202+
203+
ServerOAuth2AuthorizedClientRepository authorizedClientRepository = config.authorizedClientRepository;
204+
ServerAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository = config.authorizationRequestRepository;
205+
ServerRequestCache requestCache = config.requestCache;
206+
207+
when(authorizedClientRepository.loadAuthorizedClient(any(), any(), any())).thenReturn(Mono.empty());
208+
when(authorizationRequestRepository.saveAuthorizationRequest(any(), any())).thenReturn(Mono.empty());
209+
when(requestCache.removeMatchingRequest(any())).thenReturn(Mono.empty());
210+
when(requestCache.saveRequest(any())).thenReturn(Mono.empty());
211+
212+
this.client.get()
213+
.uri("/")
214+
.exchange()
215+
.expectStatus().is3xxRedirection();
216+
217+
verify(authorizedClientRepository).loadAuthorizedClient(any(), any(), any());
218+
verify(authorizationRequestRepository).saveAuthorizationRequest(any(), any());
219+
verify(requestCache).saveRequest(any());
220+
}
221+
222+
@EnableWebFlux
223+
static class OAuth2AuthorizeWithMockObjectsConfig {
224+
ServerOAuth2AuthorizedClientRepository authorizedClientRepository =
225+
mock(ServerOAuth2AuthorizedClientRepository.class);
226+
227+
ServerAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository =
228+
mock(ServerAuthorizationRequestRepository.class);
229+
230+
ServerRequestCache requestCache = mock(ServerRequestCache.class);
231+
232+
@Bean
233+
SecurityWebFilterChain springSecurity(ServerHttpSecurity http) {
234+
http
235+
.requestCache()
236+
.requestCache(this.requestCache)
237+
.and()
238+
.oauth2Login()
239+
.authorizationRequestRepository(this.authorizationRequestRepository);
240+
return http.build();
241+
}
242+
243+
@Bean
244+
ServerOAuth2AuthorizedClientRepository authorizedClientRepository() {
245+
return this.authorizedClientRepository;
246+
}
247+
}
248+
249+
@RestController
250+
static class AuthorizedClientController {
251+
@GetMapping("/")
252+
String home(@RegisteredOAuth2AuthorizedClient("github") OAuth2AuthorizedClient authorizedClient) {
253+
return "home";
254+
}
255+
}
256+
192257
@Test
193258
public void oauth2LoginWhenCustomObjectsThenUsed() {
194259
this.spring.register(OAuth2LoginWithSingleClientRegistrations.class,

config/src/test/java/org/springframework/security/config/web/server/ServerHttpSecurityTests.java

Lines changed: 3 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,12 @@
2020
import static org.mockito.BDDMockito.given;
2121
import static org.mockito.ArgumentMatchers.any;
2222
import static org.mockito.Mockito.mock;
23-
import static org.mockito.Mockito.times;
2423
import static org.mockito.Mockito.verify;
2524
import static org.mockito.Mockito.verifyZeroInteractions;
2625
import static org.mockito.Mockito.when;
2726
import static org.springframework.security.config.Customizer.withDefaults;
2827

2928
import java.util.Arrays;
30-
import java.util.Collections;
3129
import java.util.List;
3230
import java.util.Objects;
3331
import java.util.Optional;
@@ -43,37 +41,25 @@
4341
import org.springframework.security.core.Authentication;
4442
import org.springframework.security.web.authentication.preauth.x509.X509PrincipalExtractor;
4543
import org.springframework.security.web.server.authentication.ServerX509AuthenticationConverter;
46-
import org.springframework.web.server.handler.FilteringWebHandler;
4744
import reactor.core.publisher.Mono;
4845
import reactor.test.publisher.TestPublisher;
4946

5047
import org.springframework.security.authentication.ReactiveAuthenticationManager;
5148
import org.springframework.security.authentication.TestingAuthenticationToken;
5249
import org.springframework.security.config.annotation.web.reactive.ServerHttpSecurityConfigurationBuilder;
5350
import org.springframework.security.core.context.SecurityContext;
54-
import org.springframework.security.oauth2.client.ClientAuthorizationRequiredException;
55-
import org.springframework.security.oauth2.client.registration.ClientRegistration;
56-
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
57-
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
58-
import org.springframework.security.oauth2.client.web.server.OAuth2AuthorizationRequestRedirectWebFilter;
59-
import org.springframework.security.oauth2.client.web.server.ServerAuthorizationRequestRepository;
60-
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
6151
import org.springframework.security.test.web.reactive.server.WebTestClientBuilder;
6252
import org.springframework.security.web.server.SecurityWebFilterChain;
6353
import org.springframework.security.web.server.WebFilterChainProxy;
64-
import org.springframework.security.web.server.authentication.AnonymousAuthenticationWebFilterTests;
65-
import org.springframework.security.web.server.authentication.HttpBasicServerAuthenticationEntryPoint;
6654
import org.springframework.security.web.server.authentication.logout.DelegatingServerLogoutHandler;
6755
import org.springframework.security.web.server.authentication.logout.LogoutWebFilter;
6856
import org.springframework.security.web.server.authentication.logout.SecurityContextServerLogoutHandler;
6957
import org.springframework.security.web.server.authentication.logout.ServerLogoutHandler;
70-
import org.springframework.security.web.server.context.SecurityContextServerWebExchangeWebFilter;
7158
import org.springframework.security.web.server.context.ServerSecurityContextRepository;
7259
import org.springframework.security.web.server.context.WebSessionServerSecurityContextRepository;
7360
import org.springframework.security.web.server.csrf.CsrfServerLogoutHandler;
7461
import org.springframework.security.web.server.csrf.CsrfWebFilter;
7562
import org.springframework.security.web.server.csrf.ServerCsrfTokenRepository;
76-
import org.springframework.security.web.server.savedrequest.ServerRequestCache;
7763
import org.springframework.test.util.ReflectionTestUtils;
7864
import org.springframework.test.web.reactive.server.EntityExchangeResult;
7965
import org.springframework.test.web.reactive.server.FluxExchangeResult;
@@ -82,7 +68,10 @@
8268
import org.springframework.web.bind.annotation.RestController;
8369
import org.springframework.web.server.ServerWebExchange;
8470
import org.springframework.web.server.WebFilter;
71+
import org.springframework.security.web.server.context.SecurityContextServerWebExchangeWebFilter;
8572
import org.springframework.web.server.WebFilterChain;
73+
import org.springframework.security.web.server.authentication.AnonymousAuthenticationWebFilterTests;
74+
import org.springframework.security.web.server.authentication.HttpBasicServerAuthenticationEntryPoint;
8675

8776
/**
8877
* @author Rob Winch
@@ -486,71 +475,6 @@ public void postWhenCustomCsrfTokenRepositoryThenUsed() {
486475
verify(customServerCsrfTokenRepository).loadToken(any());
487476
}
488477

489-
@SuppressWarnings("UnassignedFluxMonoInstance")
490-
@Test
491-
public void configureOAuth2LoginUsingCustomCommonServerRequestCache() {
492-
ServerRequestCache requestCacheMock = mock(ServerRequestCache.class);
493-
when(requestCacheMock.saveRequest(any(ServerWebExchange.class))).thenReturn(Mono.empty());
494-
495-
ClientRegistration clientRegistration = TestClientRegistrations.clientRegistration().build();
496-
String registrationId = clientRegistration.getRegistrationId();
497-
498-
ReactiveClientRegistrationRepository clientRegistrationRepositoryMock =
499-
mock(ReactiveClientRegistrationRepository.class);
500-
when(clientRegistrationRepositoryMock.findByRegistrationId(registrationId))
501-
.thenReturn(Mono.just(clientRegistration));
502-
503-
SecurityWebFilterChain filterChain = http.requestCache().requestCache(requestCacheMock)
504-
.and().oauth2Login().clientRegistrationRepository(clientRegistrationRepositoryMock)
505-
.and().build();
506-
507-
Optional<OAuth2AuthorizationRequestRedirectWebFilter> redirectWebFilter =
508-
getWebFilter(filterChain, OAuth2AuthorizationRequestRedirectWebFilter.class);
509-
assertThat(redirectWebFilter.isPresent()).isTrue();
510-
511-
FilteringWebHandler webHandler = new FilteringWebHandler(
512-
e -> Mono.error(new ClientAuthorizationRequiredException(registrationId)),
513-
Collections.singletonList(redirectWebFilter.get())
514-
);
515-
WebTestClient client = WebTestClient.bindToWebHandler(webHandler).build();
516-
client.get().uri("/foo/bar").exchange();
517-
verify(requestCacheMock, times(1)).saveRequest(any(ServerWebExchange.class));
518-
}
519-
520-
@Test(expected = IllegalArgumentException.class)
521-
public void throwExceptionWhenNullPassedForOAuth2LoginAuthorizationRequestRepository() {
522-
http.oauth2Login().authorizationRequestRepository(null).and().build();
523-
}
524-
525-
@SuppressWarnings({"UnassignedFluxMonoInstance", "unchecked"})
526-
@Test
527-
public void configureOAuth2LoginUsingCustomAuthorizationRequestRepository() {
528-
ClientRegistration clientRegistration = TestClientRegistrations.clientRegistration().build();
529-
String registrationId = clientRegistration.getRegistrationId();
530-
531-
ReactiveClientRegistrationRepository clientRegistrationRepositoryMock =
532-
mock(ReactiveClientRegistrationRepository.class);
533-
when(clientRegistrationRepositoryMock.findByRegistrationId(registrationId))
534-
.thenReturn(Mono.just(clientRegistration));
535-
536-
ServerAuthorizationRequestRepository requestRepositoryMock = mock(ServerAuthorizationRequestRepository.class);
537-
SecurityWebFilterChain filterChain = http.oauth2Login()
538-
.clientRegistrationRepository(clientRegistrationRepositoryMock)
539-
.authorizationRequestRepository(requestRepositoryMock)
540-
.and().build();
541-
542-
Optional<OAuth2AuthorizationRequestRedirectWebFilter> redirectWebFilter =
543-
getWebFilter(filterChain, OAuth2AuthorizationRequestRedirectWebFilter.class);
544-
assertThat(redirectWebFilter.isPresent()).isTrue();
545-
546-
WebTestClient client = WebTestClient.bindToController(new SubscriberContextController())
547-
.webFilter(redirectWebFilter.get())
548-
.build();
549-
client.get().uri("/oauth2/authorization/" + registrationId).exchange();
550-
verify(requestRepositoryMock, times(1)).saveAuthorizationRequest(any(OAuth2AuthorizationRequest.class),
551-
any(ServerWebExchange.class));
552-
}
553-
554478
private boolean isX509Filter(WebFilter filter) {
555479
try {
556480
Object converter = ReflectionTestUtils.getField(filter, "authenticationConverter");

0 commit comments

Comments
 (0)