1
votes

In Spring Web I used @PreAuthorize with SpEl to check permission of current user. Something like that:

@Component
public class CustomSecurity {
    public boolean checkPermission(){
        Authentication authentication = SecurityContextHolder.getContext()
                .getAuthentication();
        CurrentAccount currentAccount = (CurrentAccount)authentication.getPrincipal();
        return currentAccount.getUsername().equals("admin");
    }
}

In RestController:

@PreAuthorize("@customSecurity.checkPermission()")
@GetMapping("/")
public Object getWidgetValues() {
    return "Hello admin";
}

Now I try to use WebFlux. Wrote reactiveCheckPermission.

public boolean checkPermission2() {
    return ReactiveSecurityContextHolder.getContext()
            .map(SecurityContext::getAuthentication)
            .map(Authentication::getPrincipal)
            .map(o -> (CurrentAccount) o)
            .map(currentAccount -> currentAccount.getUsername().equals("admin"))
            .block();
}

But it throws IllegalStateException("block()/blockFirst()/blockLast() are blocking, which is not supported in thread parallel

Changed boolean to Mono, but @PreAuthroze needs only boolean, not Mono.

How to use @PreAuthorize in WebFlux right?

1

1 Answers

0
votes

I found one solution.

@PreAuthorize("@customSecurity.checkPermission(#account)")
@GetMapping("/")
public Object getWidgetValues(@AuthenticationPrincipal(expression = "account") Account account) {
    return "Hello admin";
}

Where CurrentAccount used in ReactiveUserDetailsService

public class CurrentAccount extends User {
private Account account;

public CurrentAccount(Account account) {
    super(account.getLogin(), account.getPassword(), true, true,
            true, !account.isLocked(),
            AuthorityUtils.createAuthorityList(account.getRole().name()));
    this.account = account;
}