1

Below code return Mono from ReactiveSecurityContextHolder

@Component
public class SomeClass {
public static Mono<String> issuesID() {
        return ReactiveSecurityContextHolder.getContext().switchIfEmpty(Mono.empty()).flatMap((securityContext) -> {
            Authentication authentication = securityContext.getAuthentication();
            Jwt jwt = (Jwt) authentication.getPrincipal();
            String issuer = (String) jwt.getClaims().get("some_claim");
            log.info("{}",issuer);
            return Mono.justOrEmpty(issuer);
        }).switchIfEmpty(Mono.empty());
    }
}

I need something like this String mutatedId = PREXIX+SomeClass.issuesID();

If i do followings,

  1. PREXIX+SomeClass.issuesID().block();
  2. PREXIX+SomeClass.issuesID().subscribeOn(Schedulers.elastic()).block();
  3. PREXIX+SomeClass.issuesID().toProcessor().block();
  4. PREXIX+SomeClass.issuesID().toFuture().get();

They all give the same error.

block()/blockFirst()/blockLast() are blocking, which is not supported in thread rector-xxx

I have also tried delaying the Mono but that's also not helping.

I know reactor is a non-blocking framework and blocking is discourages but in my case I can't figure out another way to solve this.

I need to pass the mutatedId to mongoFactory so i can switch databases based on Jwt property per request. I do not want to inject @AuthenticationPrincipal in controller and keep passing it to downward layers and finally make decision at DOA layer.

@Override
public Mono<MongoDatabase> getMongoDatabase(String dbName) throws DataAccessException {
      String mutatedId = PREXIX+SomeClass.issuesID();
      return super.getMongoDatabase(mutatedId+"@"+dbName);
}

Any suggestion how this can be achieved or is there any better approach.

Ketan
  • 439
  • 4
  • 5
  • This is a duplicate of https://stackoverflow.com/questions/74921888/how-to-get-raw-token-from-reactivesecuritycontextholder and I would suggest bio close it and continue discussion there. – Alex Jan 11 '23 at 16:56

1 Answers1

0

You use for instance flatMap.

Mono<MongoDatabase> db = issuesID()
   .flatMap(id -> getMongoDatabase(id));
Alex
  • 4,987
  • 1
  • 8
  • 26
Toerktumlare
  • 12,548
  • 3
  • 35
  • 54
  • 1
    Nope didn't helped – Ketan Jul 29 '22 at 06:23
  • 2
    Not sure why you are saying "didn't helped". This is exactly the way how you handle such cases in reactive. This is very common question "It returns a Mono but I need String" that usually shows that person don't understand difference between reactive and imperative programming. Why you even using webflux if you want String and blocking? In reactive you need to build flow chaining reactive operators and you can get String as a part of the flow (in this case `issuesID().flatMap(id -> ...)`Then you can continue chain but result should be `Mono` or `Flux`. – Alex Jan 11 '23 at 16:37
  • @Alex world is not ideal and sometimes you have to have an ability to make blocking operations. – gstackoverflow Jan 13 '23 at 12:37
  • 2
    if you need to do blocking operations, then you shouldnt be using reactive, since its a non-blocking-framework. – Toerktumlare Jan 13 '23 at 13:48