-
Notifications
You must be signed in to change notification settings - Fork 6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Align Servlet ExchangeFilterFunction CoreSubscriber #7476
Conversation
...client/web/reactive/function/client/ServletOAuth2AuthorizedClientExchangeFilterFunction.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Note: I pulled your changes locally to try them out with Resource Server, performing the needed changes, and it continued to work as expected.
|
||
@Override | ||
public void afterPropertiesSet() throws Exception { | ||
Hooks.onLastOperator(SECURITY_REACTOR_CONTEXT_OPERATOR_KEY, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jgrandja @rwinch
as far as function from Hooks.onLastOperator
is invoked for each last operator in a chain it means that such simple code will print 201
:
public static void main(String[] args) {
final AtomicInteger counter = new AtomicInteger();
Hooks.onLastOperator(pub -> {
counter.incrementAndGet();
return pub;
});
Flux.range(0, 200)
.flatMap(it -> Mono.defer(() -> Mono.just(it)))//just do some work
.blockLast();
System.out.println("counter: " + counter);
}
it means that 200 publishers and probably subscribers and attributes maps will be created just for nothing.
To reduce allocation this code could be rewritten to
public void afterPropertiesSet() {
Function<? super Publisher<Object>, ? extends Publisher<Object>> lifter =
Operators.liftPublisher((s, sub) -> createRequestContextSubscriberIfNecessary(sub));
Hooks.onLastOperator(SECURITY_REACTOR_CONTEXT_OPERATOR_KEY, pub -> {
HttpServletRequest request = null;
HttpServletResponse response = null;
ServletRequestAttributes requestAttributes =
(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (requestAttributes != null) {
request = requestAttributes.getRequest();
response = requestAttributes.getResponse();
}
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null && request == null && response == null) {
// No need to create lift Publisher so return original
return pub;
}
return lifter.apply(pub);
});
}
...
<T> CoreSubscriber<T> createRequestContextSubscriberIfNecessary(CoreSubscriber<T> delegate) {
if (delegate.currentContext().hasKey(SECURITY_CONTEXT_ATTRIBUTES)) {
//already enriched. no nead to create Subscriber
return delegate;
}
... // the rest logic is the same
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@robotmrv Your tips on the Reactive end of things has been very valuable. Thank you for keeping an eye out on improvements. I applied your suggested changes :) Thanks again!
Merged via 2a5bd6e |
Fixes gh-7422
The intention of the new
SecurityReactorContextConfiguration
is that it's meant to be used/shared by bothServletOAuth2AuthorizedClientExchangeFilterFunction
andServletBearerExchangeFilterFunction
. However, the changes in this PR work only forServletOAuth2AuthorizedClientExchangeFilterFunction
.When this PR is merged than I believe we can remove
OAuth2ResourceServerConfiguration
and apply a very small change inServletBearerExchangeFilterFunction
, which will than resolve #7423.