1
1
/*
2
- * Copyright 2002-2019 the original author or authors.
2
+ * Copyright 2002-2020 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
41
41
import org .springframework .util .MultiValueMap ;
42
42
import org .springframework .util .StringUtils ;
43
43
import org .springframework .web .filter .OncePerRequestFilter ;
44
+ import org .springframework .web .util .UriComponents ;
44
45
import org .springframework .web .util .UriComponentsBuilder ;
45
46
46
47
import javax .servlet .FilterChain ;
47
48
import javax .servlet .ServletException ;
48
49
import javax .servlet .http .HttpServletRequest ;
49
50
import javax .servlet .http .HttpServletResponse ;
50
51
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 ;
51
57
52
58
/**
53
59
* A {@code Filter} for the OAuth 2.0 Authorization Code Grant,
@@ -132,24 +138,39 @@ public final void setAuthorizationRequestRepository(AuthorizationRequestReposito
132
138
protected void doFilterInternal (HttpServletRequest request , HttpServletResponse response , FilterChain filterChain )
133
139
throws ServletException , IOException {
134
140
135
- if (this . shouldProcessAuthorizationResponse (request )) {
136
- this . processAuthorizationResponse (request , response );
141
+ if (matchesAuthorizationResponse (request )) {
142
+ processAuthorizationResponse (request , response );
137
143
return ;
138
144
}
139
145
140
146
filterChain .doFilter (request , response );
141
147
}
142
148
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
+ }
144
154
OAuth2AuthorizationRequest authorizationRequest = this .authorizationRequestRepository .loadAuthorizationRequest (request );
145
155
if (authorizationRequest == null ) {
146
156
return false ;
147
157
}
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 ())) {
153
174
return true ;
154
175
}
155
176
return false ;
@@ -165,10 +186,7 @@ private void processAuthorizationResponse(HttpServletRequest request, HttpServle
165
186
ClientRegistration clientRegistration = this .clientRegistrationRepository .findByRegistrationId (registrationId );
166
187
167
188
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 );
172
190
OAuth2AuthorizationResponse authorizationResponse = OAuth2AuthorizationResponseUtils .convert (params , redirectUri );
173
191
174
192
OAuth2AuthorizationCodeAuthenticationToken authenticationRequest = new OAuth2AuthorizationCodeAuthenticationToken (
@@ -183,7 +201,7 @@ private void processAuthorizationResponse(HttpServletRequest request, HttpServle
183
201
} catch (OAuth2AuthorizationException ex ) {
184
202
OAuth2Error error = ex .getError ();
185
203
UriComponentsBuilder uriBuilder = UriComponentsBuilder
186
- .fromUriString (authorizationResponse .getRedirectUri ())
204
+ .fromUriString (authorizationRequest .getRedirectUri ())
187
205
.queryParam (OAuth2ParameterNames .ERROR , error .getErrorCode ());
188
206
if (!StringUtils .isEmpty (error .getDescription ())) {
189
207
uriBuilder .queryParam (OAuth2ParameterNames .ERROR_DESCRIPTION , error .getDescription ());
@@ -206,7 +224,7 @@ private void processAuthorizationResponse(HttpServletRequest request, HttpServle
206
224
207
225
this .authorizedClientRepository .saveAuthorizedClient (authorizedClient , currentAuthentication , request , response );
208
226
209
- String redirectUrl = authorizationResponse .getRedirectUri ();
227
+ String redirectUrl = authorizationRequest .getRedirectUri ();
210
228
SavedRequest savedRequest = this .requestCache .getRequest (request , response );
211
229
if (savedRequest != null ) {
212
230
redirectUrl = savedRequest .getRedirectUrl ();
0 commit comments