Как использовать @PreAuthorize в Spring WebFlux? - PullRequest
0 голосов
/ 27 сентября 2018

В Spring Web я использовал @PreAuthorize с SpEl для проверки прав доступа текущего пользователя.Примерно так:

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

В RestController:

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

Теперь я пытаюсь использовать WebFlux.Написал реактивныйCheckPermission.

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

Но он генерирует исключение IllegalStateException ("block () / blockFirst () / blockLast () блокируются, что не поддерживается в параллельной нити

Изменен логический на Mono,но @PreAuthroze нужен только логический, а не Mono.

Как использовать @PreAuthorize в WebFlux, верно?

1 Ответ

0 голосов
/ 27 сентября 2018

Я нашел одно решение.

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

Где CurrentAccount используется в 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;
}
...