Пустой принципал, возвращаемый ServerRequest в обработчике запросов webflux

Я настроил аутентификацию в приложении Spring WebFlux. Механизм аутентификации работает нормально. Например, следующий код используется для настройки цепочки веб-фильтров безопасности:

@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {

    return http.authorizeExchange()
            .pathMatchers("/path/to/resource").hasAuthority("A_ROLE")
            .anyExchange().authenticated()
            .and().httpBasic()
            .and().build();
}

Это работает должным образом в сочетании с UserDetailsRepositoryReactiveAuthenticationManager и MapReactiveUserDetailsService. Если у пользователя нет необходимых прав доступа, возвращается запрещенный код ошибки, в противном случае запрос передается обработчику.

У меня есть требование применить детализированные проверки разрешений в самом обработчике, и я решил, что смогу получить полномочия из запроса следующим образом:

public Mono<ServerResponse> getMyResource(ServerRequest serverRequest) {

      Authentication authentication = (Authentication)serverRequest.principal().block();
      ...   
}

Тем не менее, я считаю, что основной всегда нулевой. Во-первых, это правильный способ получить контроль над властями, и если да, то есть ли какая-то восходящая конфигурация, которую я пропускаю?

1 ответ

Вы блокируете результат до того, как он станет доступен. Вы можете просто отобразить его так, чтобы вам не пришлось его блокировать.

public Mono<ServerResponse> getMyResource(ServerRequest serverRequest) {
    return serverRequest.principal().flatMap((principal) -> ServerResponse.ok()
            .body(fromObject("Hello " + principal.getName())));
}

ОБНОВЛЕНИЕ: Если вы хотите получить основную часть и тело, вы можете заархивировать их.

public Mono<ServerResponse> getMyResource(ServerRequest serverRequest) {
    return Mono.zip(
            serverRequest.principal(),
            serverRequest.bodyToMono(String.class)
    ).flatMap(tuple -> {
        Principal principal = tuple.getT1();
        String body = tuple.getT2();
        return ServerResponse.ok().build();
    });
}
Другие вопросы по тегам