19
19
import org .reactivestreams .Subscription ;
20
20
import org .springframework .beans .factory .DisposableBean ;
21
21
import org .springframework .beans .factory .InitializingBean ;
22
+ import org .springframework .lang .Nullable ;
22
23
import org .springframework .security .authentication .AnonymousAuthenticationToken ;
23
24
import org .springframework .security .core .Authentication ;
24
25
import org .springframework .security .core .GrantedAuthority ;
95
96
*
96
97
* @author Rob Winch
97
98
* @author Joe Grandja
99
+ * @author Roman Matiushchenko
98
100
* @since 5.1
99
101
* @see OAuth2AuthorizedClientManager
100
102
*/
@@ -174,7 +176,7 @@ private static OAuth2AuthorizedClientManager createDefaultAuthorizedClientManage
174
176
175
177
@ Override
176
178
public void afterPropertiesSet () throws Exception {
177
- Hooks .onLastOperator (REQUEST_CONTEXT_OPERATOR_KEY , Operators .lift ((s , sub ) -> createRequestContextSubscriber (sub )));
179
+ Hooks .onLastOperator (REQUEST_CONTEXT_OPERATOR_KEY , Operators .liftPublisher ((s , sub ) -> createRequestContextSubscriberIfNecessary (sub )));
178
180
}
179
181
180
182
@ Override
@@ -378,14 +380,22 @@ private Mono<ClientRequest> mergeRequestAttributesFromContext(ClientRequest requ
378
380
}
379
381
380
382
private void populateRequestAttributes (Map <String , Object > attrs , Context ctx ) {
381
- if (ctx .hasKey (HTTP_SERVLET_REQUEST_ATTR_NAME )) {
382
- attrs .putIfAbsent (HTTP_SERVLET_REQUEST_ATTR_NAME , ctx .get (HTTP_SERVLET_REQUEST_ATTR_NAME ));
383
- }
384
- if (ctx .hasKey (HTTP_SERVLET_RESPONSE_ATTR_NAME )) {
385
- attrs .putIfAbsent (HTTP_SERVLET_RESPONSE_ATTR_NAME , ctx .get (HTTP_SERVLET_RESPONSE_ATTR_NAME ));
386
- }
387
- if (ctx .hasKey (AUTHENTICATION_ATTR_NAME )) {
388
- attrs .putIfAbsent (AUTHENTICATION_ATTR_NAME , ctx .get (AUTHENTICATION_ATTR_NAME ));
383
+ RequestContextDataHolder holder = RequestContextSubscriber .getRequestContext (ctx );
384
+ if (holder != null ) {
385
+ HttpServletRequest request = holder .getRequest ();
386
+ if (request != null ) {
387
+ attrs .putIfAbsent (HTTP_SERVLET_REQUEST_ATTR_NAME , request );
388
+ }
389
+
390
+ HttpServletResponse response = holder .getResponse ();
391
+ if (response != null ) {
392
+ attrs .putIfAbsent (HTTP_SERVLET_RESPONSE_ATTR_NAME , response );
393
+ }
394
+
395
+ Authentication authentication = holder .getAuthentication ();
396
+ if (authentication != null ) {
397
+ attrs .putIfAbsent (AUTHENTICATION_ATTR_NAME , authentication );
398
+ }
389
399
}
390
400
}
391
401
@@ -472,7 +482,7 @@ private ClientRequest bearer(ClientRequest request, OAuth2AuthorizedClient autho
472
482
.build ();
473
483
}
474
484
475
- private <T > CoreSubscriber <T > createRequestContextSubscriber (CoreSubscriber <T > delegate ) {
485
+ <T > CoreSubscriber <T > createRequestContextSubscriberIfNecessary (CoreSubscriber <T > delegate ) {
476
486
HttpServletRequest request = null ;
477
487
HttpServletResponse response = null ;
478
488
ServletRequestAttributes requestAttributes =
@@ -482,6 +492,10 @@ private <T> CoreSubscriber<T> createRequestContextSubscriber(CoreSubscriber<T> d
482
492
response = requestAttributes .getResponse ();
483
493
}
484
494
Authentication authentication = SecurityContextHolder .getContext ().getAuthentication ();
495
+ if (authentication == null && request == null && response == null ) {
496
+ //do not need to create RequestContextSubscriber with empty data
497
+ return delegate ;
498
+ }
485
499
return new RequestContextSubscriber <>(delegate , request , response , authentication );
486
500
}
487
501
@@ -553,34 +567,37 @@ private UnsupportedOperationException unsupported() {
553
567
}
554
568
}
555
569
556
- private static class RequestContextSubscriber <T > implements CoreSubscriber <T > {
557
- private static final String CONTEXT_DEFAULTED_ATTR_NAME = RequestContextSubscriber .class .getName ().concat (".CONTEXT_DEFAULTED_ATTR_NAME" );
570
+ static class RequestContextSubscriber <T > implements CoreSubscriber <T > {
571
+ static final String REQUEST_CONTEXT_DATA_HOLDER =
572
+ RequestContextSubscriber .class .getName ().concat (".REQUEST_CONTEXT_DATA_HOLDER" );
558
573
private final CoreSubscriber <T > delegate ;
559
- private final HttpServletRequest request ;
560
- private final HttpServletResponse response ;
561
- private final Authentication authentication ;
574
+ private final Context context ;
562
575
563
- private RequestContextSubscriber (CoreSubscriber <T > delegate ,
564
- HttpServletRequest request ,
565
- HttpServletResponse response ,
566
- Authentication authentication ) {
576
+ RequestContextSubscriber (CoreSubscriber <T > delegate ,
577
+ HttpServletRequest request ,
578
+ HttpServletResponse response ,
579
+ Authentication authentication ) {
567
580
this .delegate = delegate ;
568
- this .request = request ;
569
- this .response = response ;
570
- this .authentication = authentication ;
581
+
582
+ Context parentContext = this .delegate .currentContext ();
583
+ Context context ;
584
+ if (parentContext .hasKey (REQUEST_CONTEXT_DATA_HOLDER )) {
585
+ context = parentContext ;
586
+ } else {
587
+ context = parentContext .put (REQUEST_CONTEXT_DATA_HOLDER , new RequestContextDataHolder (request , response , authentication ));
588
+ }
589
+
590
+ this .context = context ;
591
+ }
592
+
593
+ @ Nullable
594
+ private static RequestContextDataHolder getRequestContext (Context ctx ) {
595
+ return ctx .getOrDefault (REQUEST_CONTEXT_DATA_HOLDER , null );
571
596
}
572
597
573
598
@ Override
574
599
public Context currentContext () {
575
- Context context = this .delegate .currentContext ();
576
- if (context .hasKey (CONTEXT_DEFAULTED_ATTR_NAME )) {
577
- return context ;
578
- }
579
- return Context .of (
580
- CONTEXT_DEFAULTED_ATTR_NAME , Boolean .TRUE ,
581
- HTTP_SERVLET_REQUEST_ATTR_NAME , this .request ,
582
- HTTP_SERVLET_RESPONSE_ATTR_NAME , this .response ,
583
- AUTHENTICATION_ATTR_NAME , this .authentication );
600
+ return this .context ;
584
601
}
585
602
586
603
@ Override
@@ -603,4 +620,33 @@ public void onComplete() {
603
620
this .delegate .onComplete ();
604
621
}
605
622
}
623
+
624
+ static class RequestContextDataHolder {
625
+ private final HttpServletRequest request ;
626
+ private final HttpServletResponse response ;
627
+ private final Authentication authentication ;
628
+
629
+ RequestContextDataHolder (@ Nullable HttpServletRequest request ,
630
+ @ Nullable HttpServletResponse response ,
631
+ @ Nullable Authentication authentication ) {
632
+ this .request = request ;
633
+ this .response = response ;
634
+ this .authentication = authentication ;
635
+ }
636
+
637
+ @ Nullable
638
+ private HttpServletRequest getRequest () {
639
+ return this .request ;
640
+ }
641
+
642
+ @ Nullable
643
+ private HttpServletResponse getResponse () {
644
+ return this .response ;
645
+ }
646
+
647
+ @ Nullable
648
+ private Authentication getAuthentication () {
649
+ return this .authentication ;
650
+ }
651
+ }
606
652
}
0 commit comments