@@ -122,11 +122,55 @@ public OAuth2AuthorizationCodeRequestAuthenticationProvider(RegisteredClientRepo
122122 public Authentication authenticate (Authentication authentication ) throws AuthenticationException {
123123 OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication = (OAuth2AuthorizationCodeRequestAuthenticationToken ) authentication ;
124124
125+ OAuth2Authorization pushedAuthorization = null ;
125126 String requestUri = (String ) authorizationCodeRequestAuthentication .getAdditionalParameters ()
126127 .get ("request_uri" );
127128 if (StringUtils .hasText (requestUri )) {
128- authorizationCodeRequestAuthentication = fromPushedAuthorizationRequest (
129- authorizationCodeRequestAuthentication );
129+ OAuth2PushedAuthorizationRequestUri pushedAuthorizationRequestUri = null ;
130+ try {
131+ pushedAuthorizationRequestUri = OAuth2PushedAuthorizationRequestUri .parse (requestUri );
132+ }
133+ catch (Exception ex ) {
134+ throwError (OAuth2ErrorCodes .INVALID_REQUEST , "request_uri" , authorizationCodeRequestAuthentication ,
135+ null );
136+ }
137+
138+ pushedAuthorization = this .authorizationService .findByToken (pushedAuthorizationRequestUri .getState (),
139+ STATE_TOKEN_TYPE );
140+ if (pushedAuthorization == null ) {
141+ throwError (OAuth2ErrorCodes .INVALID_REQUEST , "request_uri" , authorizationCodeRequestAuthentication ,
142+ null );
143+ }
144+
145+ if (this .logger .isTraceEnabled ()) {
146+ this .logger .trace ("Retrieved authorization with pushed authorization request" );
147+ }
148+
149+ OAuth2AuthorizationRequest authorizationRequest = pushedAuthorization
150+ .getAttribute (OAuth2AuthorizationRequest .class .getName ());
151+
152+ if (!authorizationCodeRequestAuthentication .getClientId ().equals (authorizationRequest .getClientId ())) {
153+ throwError (OAuth2ErrorCodes .INVALID_REQUEST , OAuth2ParameterNames .CLIENT_ID ,
154+ authorizationCodeRequestAuthentication , null );
155+ }
156+
157+ if (Instant .now ().isAfter (pushedAuthorizationRequestUri .getExpiresAt ())) {
158+ // Remove (effectively invalidating) the pushed authorization request
159+ this .authorizationService .remove (pushedAuthorization );
160+ if (this .logger .isWarnEnabled ()) {
161+ this .logger
162+ .warn (LogMessage .format ("Removed expired pushed authorization request for client id '%s'" ,
163+ authorizationRequest .getClientId ()));
164+ }
165+ throwError (OAuth2ErrorCodes .INVALID_REQUEST , "request_uri" , authorizationCodeRequestAuthentication ,
166+ null );
167+ }
168+
169+ authorizationCodeRequestAuthentication = new OAuth2AuthorizationCodeRequestAuthenticationToken (
170+ authorizationCodeRequestAuthentication .getAuthorizationUri (), authorizationRequest .getClientId (),
171+ (Authentication ) authorizationCodeRequestAuthentication .getPrincipal (),
172+ authorizationRequest .getRedirectUri (), authorizationRequest .getState (),
173+ authorizationRequest .getScopes (), authorizationRequest .getAdditionalParameters ());
130174 }
131175
132176 RegisteredClient registeredClient = this .registeredClientRepository
@@ -223,13 +267,21 @@ public Authentication authenticate(Authentication authentication) throws Authent
223267
224268 this .authorizationService .save (authorization );
225269
226- Set <String > currentAuthorizedScopes = (currentAuthorizationConsent != null )
227- ? currentAuthorizationConsent .getScopes () : null ;
228-
229270 if (this .logger .isTraceEnabled ()) {
230271 this .logger .trace ("Saved authorization" );
231272 }
232273
274+ if (pushedAuthorization != null ) {
275+ // Enforce one-time use by removing the pushed authorization request
276+ this .authorizationService .remove (pushedAuthorization );
277+ if (this .logger .isTraceEnabled ()) {
278+ this .logger .trace ("Removed authorization with pushed authorization request" );
279+ }
280+ }
281+
282+ Set <String > currentAuthorizedScopes = (currentAuthorizationConsent != null )
283+ ? currentAuthorizationConsent .getScopes () : null ;
284+
233285 return new OAuth2AuthorizationConsentAuthenticationToken (authorizationRequest .getAuthorizationUri (),
234286 registeredClient .getClientId (), principal , state , currentAuthorizedScopes , null );
235287 }
@@ -257,6 +309,14 @@ public Authentication authenticate(Authentication authentication) throws Authent
257309 this .logger .trace ("Saved authorization" );
258310 }
259311
312+ if (pushedAuthorization != null ) {
313+ // Enforce one-time use by removing the pushed authorization request
314+ this .authorizationService .remove (pushedAuthorization );
315+ if (this .logger .isTraceEnabled ()) {
316+ this .logger .trace ("Removed authorization with pushed authorization request" );
317+ }
318+ }
319+
260320 String redirectUri = authorizationRequest .getRedirectUri ();
261321 if (!StringUtils .hasText (redirectUri )) {
262322 redirectUri = registeredClient .getRedirectUris ().iterator ().next ();
@@ -335,55 +395,6 @@ public void setAuthorizationConsentRequired(
335395 this .authorizationConsentRequired = authorizationConsentRequired ;
336396 }
337397
338- private OAuth2AuthorizationCodeRequestAuthenticationToken fromPushedAuthorizationRequest (
339- OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication ) {
340-
341- String requestUri = (String ) authorizationCodeRequestAuthentication .getAdditionalParameters ()
342- .get ("request_uri" );
343-
344- OAuth2PushedAuthorizationRequestUri pushedAuthorizationRequestUri = null ;
345- try {
346- pushedAuthorizationRequestUri = OAuth2PushedAuthorizationRequestUri .parse (requestUri );
347- }
348- catch (Exception ex ) {
349- throwError (OAuth2ErrorCodes .INVALID_REQUEST , "request_uri" , authorizationCodeRequestAuthentication , null );
350- }
351-
352- OAuth2Authorization authorization = this .authorizationService
353- .findByToken (pushedAuthorizationRequestUri .getState (), STATE_TOKEN_TYPE );
354- if (authorization == null ) {
355- throwError (OAuth2ErrorCodes .INVALID_REQUEST , "request_uri" , authorizationCodeRequestAuthentication , null );
356- }
357-
358- if (this .logger .isTraceEnabled ()) {
359- this .logger .trace ("Retrieved authorization with pushed authorization request" );
360- }
361-
362- OAuth2AuthorizationRequest authorizationRequest = authorization
363- .getAttribute (OAuth2AuthorizationRequest .class .getName ());
364-
365- if (!authorizationCodeRequestAuthentication .getClientId ().equals (authorizationRequest .getClientId ())) {
366- throwError (OAuth2ErrorCodes .INVALID_REQUEST , OAuth2ParameterNames .CLIENT_ID ,
367- authorizationCodeRequestAuthentication , null );
368- }
369-
370- if (Instant .now ().isAfter (pushedAuthorizationRequestUri .getExpiresAt ())) {
371- // Remove (effectively invalidating) the pushed authorization request
372- this .authorizationService .remove (authorization );
373- if (this .logger .isWarnEnabled ()) {
374- this .logger .warn (LogMessage .format ("Removed expired pushed authorization request for client id '%s'" ,
375- authorizationRequest .getClientId ()));
376- }
377- throwError (OAuth2ErrorCodes .INVALID_REQUEST , "request_uri" , authorizationCodeRequestAuthentication , null );
378- }
379-
380- return new OAuth2AuthorizationCodeRequestAuthenticationToken (
381- authorizationCodeRequestAuthentication .getAuthorizationUri (), authorizationRequest .getClientId (),
382- (Authentication ) authorizationCodeRequestAuthentication .getPrincipal (),
383- authorizationRequest .getRedirectUri (), authorizationRequest .getState (),
384- authorizationRequest .getScopes (), authorizationRequest .getAdditionalParameters ());
385- }
386-
387398 private static boolean isAuthorizationConsentRequired (
388399 OAuth2AuthorizationCodeRequestAuthenticationContext authenticationContext ) {
389400 if (!authenticationContext .getRegisteredClient ().getClientSettings ().isRequireAuthorizationConsent ()) {
0 commit comments