Skip to content

Commit 1e211b6

Browse files
parikshitduttajgrandja
authored andcommitted
Add RequestCache setter in OAuth2AuthorizationCodeGrantFilter
Fixes gh-8120
1 parent c1abc9b commit 1e211b6

File tree

4 files changed

+88
-3
lines changed

4 files changed

+88
-3
lines changed

config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2ClientConfigurer.java

Lines changed: 6 additions & 1 deletion
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-2020 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.
@@ -79,6 +79,7 @@
7979
* </ul>
8080
*
8181
* @author Joe Grandja
82+
* @author Parikshit Dutta
8283
* @since 5.1
8384
* @see OAuth2AuthorizationRequestRedirectFilter
8485
* @see OAuth2AuthorizationCodeGrantFilter
@@ -256,6 +257,10 @@ private OAuth2AuthorizationCodeGrantFilter createAuthorizationCodeGrantFilter(B
256257
if (this.authorizationRequestRepository != null) {
257258
authorizationCodeGrantFilter.setAuthorizationRequestRepository(this.authorizationRequestRepository);
258259
}
260+
RequestCache requestCache = builder.getSharedObject(RequestCache.class);
261+
if (requestCache != null) {
262+
authorizationCodeGrantFilter.setRequestCache(requestCache);
263+
}
259264
return authorizationCodeGrantFilter;
260265
}
261266

config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2ClientConfigurerTests.java

Lines changed: 39 additions & 1 deletion
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-2020 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.
@@ -75,6 +75,7 @@
7575
* Tests for {@link OAuth2ClientConfigurer}.
7676
*
7777
* @author Joe Grandja
78+
* @author Parikshit Dutta
7879
*/
7980
public class OAuth2ClientConfigurerTests {
8081
private static ClientRegistrationRepository clientRegistrationRepository;
@@ -208,6 +209,43 @@ public void configureWhenRequestCacheProvidedAndClientAuthorizationRequiredExcep
208209
verify(requestCache).saveRequest(any(HttpServletRequest.class), any(HttpServletResponse.class));
209210
}
210211

212+
@Test
213+
public void configureWhenRequestCacheProvidedAndClientAuthorizationSucceedsThenRequestCacheUsed() throws Exception {
214+
this.spring.register(OAuth2ClientConfig.class).autowire();
215+
216+
// Setup the Authorization Request in the session
217+
Map<String, Object> attributes = new HashMap<>();
218+
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, this.registration1.getRegistrationId());
219+
OAuth2AuthorizationRequest authorizationRequest = OAuth2AuthorizationRequest.authorizationCode()
220+
.authorizationUri(this.registration1.getProviderDetails().getAuthorizationUri())
221+
.clientId(this.registration1.getClientId())
222+
.redirectUri("http://localhost/client-1")
223+
.state("state")
224+
.attributes(attributes)
225+
.build();
226+
227+
AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository =
228+
new HttpSessionOAuth2AuthorizationRequestRepository();
229+
MockHttpServletRequest request = new MockHttpServletRequest("GET", "");
230+
MockHttpServletResponse response = new MockHttpServletResponse();
231+
authorizationRequestRepository.saveAuthorizationRequest(authorizationRequest, request, response);
232+
233+
MockHttpSession session = (MockHttpSession) request.getSession();
234+
235+
String principalName = "user1";
236+
TestingAuthenticationToken authentication = new TestingAuthenticationToken(principalName, "password");
237+
238+
this.mockMvc.perform(get("/client-1")
239+
.param(OAuth2ParameterNames.CODE, "code")
240+
.param(OAuth2ParameterNames.STATE, "state")
241+
.with(authentication(authentication))
242+
.session(session))
243+
.andExpect(status().is3xxRedirection())
244+
.andExpect(redirectedUrl("http://localhost/client-1"));
245+
246+
verify(requestCache).getRequest(any(HttpServletRequest.class), any(HttpServletResponse.class));
247+
}
248+
211249
// gh-5521
212250
@Test
213251
public void configureWhenCustomAuthorizationRequestResolverSetThenAuthorizationRequestIncludesCustomParameters() throws Exception {

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/OAuth2AuthorizationCodeGrantFilter.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
* </ul>
8484
*
8585
* @author Joe Grandja
86+
* @author Parikshit Dutta
8687
* @since 5.1
8788
* @see OAuth2AuthorizationCodeAuthenticationToken
8889
* @see OAuth2AuthorizationCodeAuthenticationProvider
@@ -104,7 +105,7 @@ public class OAuth2AuthorizationCodeGrantFilter extends OncePerRequestFilter {
104105
new HttpSessionOAuth2AuthorizationRequestRepository();
105106
private final AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
106107
private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
107-
private final RequestCache requestCache = new HttpSessionRequestCache();
108+
private RequestCache requestCache = new HttpSessionRequestCache();
108109

109110
/**
110111
* Constructs an {@code OAuth2AuthorizationCodeGrantFilter} using the provided parameters.
@@ -134,6 +135,18 @@ public final void setAuthorizationRequestRepository(AuthorizationRequestReposito
134135
this.authorizationRequestRepository = authorizationRequestRepository;
135136
}
136137

138+
/**
139+
* Sets the {@link RequestCache} used for loading a previously saved request (if available)
140+
* and replaying it after completing the processing of the OAuth 2.0 Authorization Response.
141+
*
142+
* @since 5.4
143+
* @param requestCache the cache used for loading a previously saved request (if available)
144+
*/
145+
public final void setRequestCache(RequestCache requestCache) {
146+
Assert.notNull(requestCache, "requestCache cannot be null");
147+
this.requestCache = requestCache;
148+
}
149+
137150
@Override
138151
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
139152
throws ServletException, IOException {

oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/OAuth2AuthorizationCodeGrantFilterTests.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
* Tests for {@link OAuth2AuthorizationCodeGrantFilter}.
7373
*
7474
* @author Joe Grandja
75+
* @author Parikshit Dutta
7576
*/
7677
public class OAuth2AuthorizationCodeGrantFilterTests {
7778
private ClientRegistration registration1;
@@ -130,6 +131,12 @@ public void setAuthorizationRequestRepositoryWhenAuthorizationRequestRepositoryI
130131
.isInstanceOf(IllegalArgumentException.class);
131132
}
132133

134+
@Test
135+
public void setRequestCacheWhenRequestCacheIsNullThenThrowIllegalArgumentException() {
136+
assertThatThrownBy(() -> this.filter.setRequestCache(null))
137+
.isInstanceOf(IllegalArgumentException.class);
138+
}
139+
133140
@Test
134141
public void doFilterWhenNotAuthorizationResponseThenNotProcessed() throws Exception {
135142
String requestUri = "/path";
@@ -326,6 +333,28 @@ public void doFilterWhenAuthorizationSucceedsAndHasSavedRequestThenRedirectToSav
326333
assertThat(response.getRedirectedUrl()).isEqualTo("http://localhost/saved-request");
327334
}
328335

336+
@Test
337+
public void doFilterWhenAuthorizationSucceedsAndRequestCacheConfiguredThenRequestCacheUsed() throws Exception {
338+
MockHttpServletRequest authorizationRequest = createAuthorizationRequest("/callback/client-1");
339+
MockHttpServletRequest authorizationResponse = createAuthorizationResponse(authorizationRequest);
340+
MockHttpServletResponse response = new MockHttpServletResponse();
341+
342+
FilterChain filterChain = mock(FilterChain.class);
343+
this.setUpAuthorizationRequest(authorizationRequest, response, this.registration1);
344+
this.setUpAuthenticationResult(this.registration1);
345+
346+
RequestCache requestCache = spy(HttpSessionRequestCache.class);
347+
this.filter.setRequestCache(requestCache);
348+
349+
authorizationRequest.setRequestURI("/saved-request");
350+
requestCache.saveRequest(authorizationRequest, response);
351+
352+
this.filter.doFilter(authorizationResponse, response, filterChain);
353+
354+
verify(requestCache).getRequest(any(HttpServletRequest.class), any(HttpServletResponse.class));
355+
assertThat(response.getRedirectedUrl()).isEqualTo("http://localhost/saved-request");
356+
}
357+
329358
@Test
330359
public void doFilterWhenAuthorizationSucceedsAndAnonymousAccessThenAuthorizedClientSavedToHttpSession() throws Exception {
331360
AnonymousAuthenticationToken anonymousPrincipal =

0 commit comments

Comments
 (0)