I've been using ReactiveAuthenticationManager in Spring Security + Webflux. It is customised to return an instance of UsernamePasswordAuthenticationToken
which from what I can tell is an what I should be receiving when I call ReactiveSecurityContextHolder.getContext().map(ctx -> ctx.getAuthentication()).block()
. As as far as I can tell I am unable to access the authentication context through both:
SecurityContextHolder.getContext().getAuthentication();
or
ReactiveSecurityContextHolder.getContext().map(ctx -> ctx.getAuthentication()).block()
And attempting to access those from controllers or components resolves to null
. I had some doubts about whether I am really returning an Authentication
instance in my custom manager and it seems like I am:
@Override
public Mono<Authentication> authenticate(final Authentication authentication) {
if (authentication instanceof PreAuthentication) {
return Mono.just(authentication)
.publishOn(Schedulers.parallel())
.switchIfEmpty(Mono.defer(this::throwCredentialError))
.cast(PreAuthentication.class)
.flatMap(this::authenticatePayload)
.publishOn(Schedulers.parallel())
.onErrorResume(e -> throwCredentialError())
.map(userDetails -> new AuthenticationToken(userDetails, userDetails.getAuthorities()));
}
return Mono.empty();
}
Where PreAuthentication
is an instance of a AbstractAuthenticationToken
and AuthenticationToken
extends UsernamePasswordAuthenticationToken
Interestingly although ReactiveSecurityContextHolder.getContext().map(ctx -> ctx.getAuthentication()).block()
does not work in a controller I can inject the authentication principal with the @AuthenticationPrincipal
annotation as a method parameter successfully in a controller.
This seems like a configuration issue but I cannot tell where. Anyone have any idea why I cannot return authentication?
See Question&Answers more detail:os