Skip to content

Commit cc7ea4a

Browse files
committed
OAuth2AuthorizationCodeGrantFilter matches on query parameters
Fixes gh-7963
1 parent 1e4736f commit cc7ea4a

File tree

2 files changed

+204
-117
lines changed

2 files changed

+204
-117
lines changed

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

Lines changed: 33 additions & 15 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-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.
@@ -41,13 +41,19 @@
4141
import org.springframework.util.MultiValueMap;
4242
import org.springframework.util.StringUtils;
4343
import org.springframework.web.filter.OncePerRequestFilter;
44+
import org.springframework.web.util.UriComponents;
4445
import org.springframework.web.util.UriComponentsBuilder;
4546

4647
import javax.servlet.FilterChain;
4748
import javax.servlet.ServletException;
4849
import javax.servlet.http.HttpServletRequest;
4950
import javax.servlet.http.HttpServletResponse;
5051
import java.io.IOException;
52+
import java.util.LinkedHashSet;
53+
import java.util.List;
54+
import java.util.Map;
55+
import java.util.Objects;
56+
import java.util.Set;
5157

5258
/**
5359
* A {@code Filter} for the OAuth 2.0 Authorization Code Grant,
@@ -132,24 +138,39 @@ public final void setAuthorizationRequestRepository(AuthorizationRequestReposito
132138
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
133139
throws ServletException, IOException {
134140

135-
if (this.shouldProcessAuthorizationResponse(request)) {
136-
this.processAuthorizationResponse(request, response);
141+
if (matchesAuthorizationResponse(request)) {
142+
processAuthorizationResponse(request, response);
137143
return;
138144
}
139145

140146
filterChain.doFilter(request, response);
141147
}
142148

143-
private boolean shouldProcessAuthorizationResponse(HttpServletRequest request) {
149+
private boolean matchesAuthorizationResponse(HttpServletRequest request) {
150+
MultiValueMap<String, String> params = OAuth2AuthorizationResponseUtils.toMultiMap(request.getParameterMap());
151+
if (!OAuth2AuthorizationResponseUtils.isAuthorizationResponse(params)) {
152+
return false;
153+
}
144154
OAuth2AuthorizationRequest authorizationRequest = this.authorizationRequestRepository.loadAuthorizationRequest(request);
145155
if (authorizationRequest == null) {
146156
return false;
147157
}
148-
String requestUrl = UrlUtils.buildFullRequestUrl(request.getScheme(), request.getServerName(),
149-
request.getServerPort(), request.getRequestURI(), null);
150-
MultiValueMap<String, String> params = OAuth2AuthorizationResponseUtils.toMultiMap(request.getParameterMap());
151-
if (requestUrl.equals(authorizationRequest.getRedirectUri()) &&
152-
OAuth2AuthorizationResponseUtils.isAuthorizationResponse(params)) {
158+
159+
// Compare redirect_uri
160+
UriComponents requestUri = UriComponentsBuilder.fromUriString(UrlUtils.buildFullRequestUrl(request)).build();
161+
UriComponents redirectUri = UriComponentsBuilder.fromUriString(authorizationRequest.getRedirectUri()).build();
162+
Set<Map.Entry<String, List<String>>> requestUriParameters = new LinkedHashSet<>(requestUri.getQueryParams().entrySet());
163+
Set<Map.Entry<String, List<String>>> redirectUriParameters = new LinkedHashSet<>(redirectUri.getQueryParams().entrySet());
164+
// Remove the additional request parameters (if any) from the authorization response (request)
165+
// before doing an exact comparison with the authorizationRequest.getRedirectUri() parameters (if any)
166+
requestUriParameters.retainAll(redirectUriParameters);
167+
168+
if (Objects.equals(requestUri.getScheme(), redirectUri.getScheme()) &&
169+
Objects.equals(requestUri.getUserInfo(), redirectUri.getUserInfo()) &&
170+
Objects.equals(requestUri.getHost(), redirectUri.getHost()) &&
171+
Objects.equals(requestUri.getPort(), redirectUri.getPort()) &&
172+
Objects.equals(requestUri.getPath(), redirectUri.getPath()) &&
173+
Objects.equals(requestUriParameters.toString(), redirectUriParameters.toString())) {
153174
return true;
154175
}
155176
return false;
@@ -165,10 +186,7 @@ private void processAuthorizationResponse(HttpServletRequest request, HttpServle
165186
ClientRegistration clientRegistration = this.clientRegistrationRepository.findByRegistrationId(registrationId);
166187

167188
MultiValueMap<String, String> params = OAuth2AuthorizationResponseUtils.toMultiMap(request.getParameterMap());
168-
String redirectUri = UriComponentsBuilder.fromHttpUrl(UrlUtils.buildFullRequestUrl(request))
169-
.replaceQuery(null)
170-
.build()
171-
.toUriString();
189+
String redirectUri = UrlUtils.buildFullRequestUrl(request);
172190
OAuth2AuthorizationResponse authorizationResponse = OAuth2AuthorizationResponseUtils.convert(params, redirectUri);
173191

174192
OAuth2AuthorizationCodeAuthenticationToken authenticationRequest = new OAuth2AuthorizationCodeAuthenticationToken(
@@ -183,7 +201,7 @@ private void processAuthorizationResponse(HttpServletRequest request, HttpServle
183201
} catch (OAuth2AuthorizationException ex) {
184202
OAuth2Error error = ex.getError();
185203
UriComponentsBuilder uriBuilder = UriComponentsBuilder
186-
.fromUriString(authorizationResponse.getRedirectUri())
204+
.fromUriString(authorizationRequest.getRedirectUri())
187205
.queryParam(OAuth2ParameterNames.ERROR, error.getErrorCode());
188206
if (!StringUtils.isEmpty(error.getDescription())) {
189207
uriBuilder.queryParam(OAuth2ParameterNames.ERROR_DESCRIPTION, error.getDescription());
@@ -206,7 +224,7 @@ private void processAuthorizationResponse(HttpServletRequest request, HttpServle
206224

207225
this.authorizedClientRepository.saveAuthorizedClient(authorizedClient, currentAuthentication, request, response);
208226

209-
String redirectUrl = authorizationResponse.getRedirectUri();
227+
String redirectUrl = authorizationRequest.getRedirectUri();
210228
SavedRequest savedRequest = this.requestCache.getRequest(request, response);
211229
if (savedRequest != null) {
212230
redirectUrl = savedRequest.getRedirectUrl();

0 commit comments

Comments
 (0)