Reactive spring security context

Viewed 810

I have a problem with my spring boot application (version 2.6.3). I have configured reactive spring security like there:

MyApplication.java:

@SpringBootApplication
@EnableWebFlux
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class);
    }

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(final ServerHttpSecurity http, final ReactiveOpaqueTokenIntrospector reactiveOpaqueTokenIntrospector) {
        return http.authorizeExchange()
                .anyExchange().authenticated()
                .and()
                .httpBasic().disable()
                .cors().and()
                .logout().disable()
                .formLogin().disable()
                .oauth2ResourceServer()
                .opaqueToken()
                .introspector(reactiveOpaqueTokenIntrospector)
                .and().and()
                .csrf()
                .disable()
                .build();
    }
    
}

And this is my web resource (controller):

MyWebResource.java:

@RestController
public class MyWebResource implements MyWebResourceApi {

    
    @PreAuthorize("hasRole('ROLE_USER')")
    @Override
    public Mono<String> details(String userId, ServerWebExchange exchange) {
        return exchange.getPrincipal().map(Principal::getName);
    }
}

It's work fine, when my access token is expired or incorrect the request should be denied. However when PreAuthorized allow request, my user principal will be never resolved in my exchange...

Any ideas ?

Thanxs you for your help !

1 Answers

In reactive application authentication information is stored in the Reactive flow and accessible from Mono/Flux. You could use ReactiveSecurityContextHolder to obtain the currently authenticated principal, or an authentication request token.

@PreAuthorize("hasRole('ROLE_USER')")
public Mono<String> details() {
        return ReactiveSecurityContextHolder.getContext()
                .map(ctx -> ((Principal) ctx.getAuthentication().getPrincipal()).getName());
    }
Related