Channel: CodeSection,代码区,网络安全 - CodeSec
Viewing all articles
Browse latest Browse all 12749

How to get the current user in a Spring Security reactive (WebFlux) and non-reac ...


When developing an application, we sometimes need to access the currently logged in user programmatically. In this post, we’ll discuss how to do that when using Spring Security ― both in non-reactive (Spring MVC) as well as reactive (Spring WebFlux) applications.

The code snippets are derived from the Spring Lemon library. If you haven’t heard of Spring Lemon , it’s a library encapsulating the sophisticated non-functional code and configuration that’s needed when developing reactive and non-reactive real-world RESTful web services using the Spring framework and Spring Boot.

When someone logs in, Spring Security creates an Authentication object. The authentication object has a principal property, which stores the current user.

So, if you can access the Authentication object, you can get the current user, like this:

public static Optional<User> currentUser(Authentication auth) { if (auth != null) { Object principal = auth.getPrincipal(); if (principal instanceof User) // User is your user type that implements UserDetails return Optional.of((User) principal); } return Optional.empty(); }

But, how to get access to the Authentication object?

The authentication object is stored in the SecurityContext object. Given the SecurityContext, a reference to the authentication object can be obtained just as below:

Authentication auth = securityContext.getAuthentication();

How to get access to the SecurityContext becomes the question then. It's different for reactive and non-reactive applications.

Accessing SecurityContext in a non-reactive (Spring MVC) application

Traditional (non-reactive) Spring Security provides a static method to access the security context, which can be called from anywhere, as below

SecurityContext context = SecurityContextHolder.getContext();

Accessing SecurityContext in a reactive (Spring WebFlux) application

Reactive Spring Security provides that in a reactive manner, as below:

Mono<SecurityContext> context = ReactiveSecurityContextHolder.getContext();

Beware that Mono<SecurityContext> returned above is just the assembly that gets resolved later at subscription time. Here is an example usage:

@PostMapping("/current-user") public Mono<UserDto<ID>> getCurrentUser(ServerWebExchange exchange) { return ReactiveSecurityContextHolder.getContext() .map(SecurityContext::getAuthentication) .map(Authentication::getPrincipal) .map(MyPrincipal::currentUser) .zipWith(exchange.getFormData()) .doOnNext(tuple -> { // based on some input parameters, amend the current user data to be returned }) .map(Tuple2::getT1); }

For exact details, refer to LecUtils , LemonUtils and LerUrils of Spring Lemon.

Viewing all articles
Browse latest Browse all 12749

Latest Images

Trending Articles

Latest Images