21
21
import java .util .HashMap ;
22
22
import java .util .Map ;
23
23
import java .util .function .Consumer ;
24
- import java .util .function .Supplier ;
25
24
26
25
import jakarta .servlet .http .HttpServletRequest ;
27
26
import jakarta .servlet .http .HttpServletResponse ;
35
34
import org .springframework .http .client .ClientHttpRequestExecution ;
36
35
import org .springframework .http .client .ClientHttpRequestInterceptor ;
37
36
import org .springframework .http .client .ClientHttpResponse ;
38
- import org .springframework .security .authentication .AbstractAuthenticationToken ;
39
37
import org .springframework .security .authentication .AnonymousAuthenticationToken ;
40
38
import org .springframework .security .core .Authentication ;
41
39
import org .springframework .security .core .authority .AuthorityUtils ;
@@ -130,9 +128,6 @@ public final class OAuth2ClientHttpRequestInterceptor implements ClientHttpReque
130
128
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
131
129
.getContextHolderStrategy ();
132
130
133
- private Supplier <Authentication > authentication = () -> this .securityContextHolderStrategy .getContext ()
134
- .getAuthentication ();
135
-
136
131
/**
137
132
* Constructs a {@code OAuth2ClientHttpRequestInterceptor} using the provided
138
133
* parameters.
@@ -242,101 +237,6 @@ public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy secur
242
237
this .securityContextHolderStrategy = securityContextHolderStrategy ;
243
238
}
244
239
245
- /**
246
- * Sets the principal name of the resource owner used to look up and save the
247
- * {@link OAuth2AuthorizedClient}.
248
- *
249
- * <p>
250
- * When this setter is used, the principal will not be resolved from the configured
251
- * {@link SecurityContextHolderStrategy} and will instead use the provided name.
252
- *
253
- * <p>
254
- * One example where this is useful is with the {@code client_credentials} grant type
255
- * to scope an {@link OAuth2AuthorizedClient} to the application for global use in a
256
- * background service.
257
- * @param principalName the principal name to use
258
- */
259
- public void setPrincipalName (String principalName ) {
260
- Assert .hasText (principalName , "principalName cannot be empty" );
261
- Authentication principal = createAuthentication (principalName );
262
- this .authentication = () -> principal ;
263
- }
264
-
265
- /**
266
- * Sets the {@link Authentication principal} of the resource owner used to look up and
267
- * save the {@link OAuth2AuthorizedClient}.
268
- *
269
- * <p>
270
- * When this setter is used, the principal will not be resolved from the configured
271
- * {@link SecurityContextHolderStrategy} and will instead use the provided instance.
272
- *
273
- * <p>
274
- * One example where this is useful is with the {@code client_credentials} grant type
275
- * to scope an {@link OAuth2AuthorizedClient} to the application for global use in a
276
- * background service.
277
- * @param principal the principal to use
278
- */
279
- public void setPrincipal (Authentication principal ) {
280
- Assert .notNull (principal , "principal cannot be null" );
281
- this .authentication = () -> principal ;
282
- }
283
-
284
- /**
285
- * Returns a {@link Consumer callback} that can be provided to
286
- * {@link org.springframework.web.client.RestClient.RequestHeadersSpec#httpRequest(Consumer)}
287
- * to make OAuth 2.0 requests by including the
288
- * {@link OAuth2AuthorizedClient#getAccessToken() access token} as a bearer token.
289
- *
290
- * <p>
291
- * This is useful for authorizing a client on a per-request basis, for example when
292
- * the {@code clientRegistrationId} is only known at runtime.
293
- *
294
- * <p>
295
- * Example usage:
296
- *
297
- * <pre>
298
- * RestClient restClient = RestClient.create();
299
- * ...
300
- * OAuth2ClientHttpRequestInterceptor requestInterceptor =
301
- * new OAuth2ClientHttpRequestInterceptor(authorizedClientManager, clientRegistrationId);
302
- * String response = restClient.get()
303
- * .uri(uri)
304
- * .httpRequest(requestInterceptor.httpRequest())
305
- * .retrieve()
306
- * .onStatus(requestInterceptor.errorHandler())
307
- * .body(String.class);
308
- * </pre>
309
- * @return a {@link Consumer} that can access the {@link ClientHttpRequest}
310
- * @see #errorHandler()
311
- */
312
- public Consumer <ClientHttpRequest > httpRequest () {
313
- return this ::authorizeClient ;
314
- }
315
-
316
- /**
317
- * Returns a {@link ResponseErrorHandler} that can be provided to
318
- * {@link org.springframework.web.client.RestClient.ResponseSpec#onStatus(ResponseErrorHandler)}
319
- * in order to forward authentication (HTTP 401 Unauthorized) and authorization (HTTP
320
- * 403 Forbidden) failures from an OAuth 2.0 Resource Server to a
321
- * {@link OAuth2AuthorizationFailureHandler}.
322
- *
323
- * <p>
324
- * This is useful for handling errors on a per-request basis, for example when the
325
- * {@code clientRegistrationId} is only known at runtime. See {@link #httpRequest()}
326
- * for more information.
327
- * @return the error handler
328
- * @see #httpRequest()
329
- */
330
- public ResponseErrorHandler errorHandler () {
331
- return new DefaultResponseErrorHandler () {
332
- @ Override
333
- public void handleError (URI url , HttpMethod method , ClientHttpResponse response ) throws IOException {
334
- handleAuthorizationFailure (response .getHeaders (), response .getStatusCode ());
335
- super .handleError (url , method , response );
336
- }
337
- };
338
- }
339
-
340
240
@ Override
341
241
public ClientHttpResponse intercept (HttpRequest request , byte [] body , ClientHttpRequestExecution execution )
342
242
throws IOException {
@@ -357,7 +257,7 @@ public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttp
357
257
}
358
258
359
259
private void authorizeClient (HttpRequest request ) {
360
- Authentication principal = this .authentication . get ();
260
+ Authentication principal = this .securityContextHolderStrategy . getContext (). getAuthentication ();
361
261
if (principal == null ) {
362
262
principal = ANONYMOUS_AUTHENTICATION ;
363
263
}
@@ -424,7 +324,7 @@ private static Map<String, String> parseWwwAuthenticateHeader(String wwwAuthenti
424
324
}
425
325
426
326
private void handleAuthorizationFailure (OAuth2AuthorizationException authorizationException ) {
427
- Authentication principal = this .authentication . get ();
327
+ Authentication principal = this .securityContextHolderStrategy . getContext (). getAuthentication ();
428
328
if (principal == null ) {
429
329
principal = ANONYMOUS_AUTHENTICATION ;
430
330
}
@@ -442,21 +342,4 @@ private void handleAuthorizationFailure(OAuth2AuthorizationException authorizati
442
342
this .authorizationFailureHandler .onAuthorizationFailure (authorizationException , principal , attributes );
443
343
}
444
344
445
- private static Authentication createAuthentication (final String principalName ) {
446
- Assert .hasText (principalName , "principalName cannot be empty" );
447
- return new AbstractAuthenticationToken (null ) {
448
-
449
- @ Override
450
- public Object getPrincipal () {
451
- return principalName ;
452
- }
453
-
454
- @ Override
455
- public Object getCredentials () {
456
- return "" ;
457
- }
458
-
459
- };
460
- }
461
-
462
345
}
0 commit comments