Получение принципала внутри ErrorWebExceptionHandler в WebfluxJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Получение принципала внутри ErrorWebExceptionHandler в Webflux

Сообщение Anonymous »


I wrote a working error handler for my webflux application. The problem arose when I tried to add the username of the logged Principal to exceptions... I see using the debugger that no context is found inside the ReactiveSecurityContextHolder, so "N/A" is always used as username value...

Note that:
  • If you remove the call to restPrincipalService.getPrincipalUsername() the handler works as expected
  • The method restPrincipalUsername.getPrincipalUsername() when called in a Controller or Service works just well, and authentication is working

Here the code:

@Component @Order(-2) @SuppressWarnings("unused") @Slf4j public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler { @Autowired private RestPrincipalService principalService; public GlobalErrorWebExceptionHandler(ErrorAttributes errorAttributes, ApplicationContext applicationContext, ServerCodecConfigurer serverCodecConfigurer) { super(errorAttributes, new WebProperties.Resources(), applicationContext); super.setMessageWriters(serverCodecConfigurer.getWriters()); super.setMessageReaders(serverCodecConfigurer.getReaders()); } @Override protected RouterFunction getRoutingFunction( ErrorAttributes errorAttributes) { return RouterFunctions.route( RequestPredicates.all(), this::renderErrorResponse); } private Mono renderErrorResponse(ServerRequest request) { Map errorPropertiesMap = getErrorAttributes(request, ErrorAttributeOptions.of(ErrorAttributeOptions.Include.EXCEPTION, ErrorAttributeOptions.Include.MESSAGE)); return principalService.getPrincipalUsername().flatMap(username -> { errorPropertiesMap.put("username", username); String exception= errorPropertiesMap.get("exception").toString(); //...business logic on exception and properties, using username return ServerResponse.status(HttpStatus.valueOf((Integer) errorPropertiesMap.get("status"))) .contentType(MediaType.APPLICATION_JSON) .body(BodyInserters.fromValue(errorPropertiesMap)); }); } } The getPrincipalUsername() implementation:

public Mono getPrincipalUsername() { return ReactiveSecurityContextHolder.getContext() .map(ctx-> ctx.getAuthentication()) .filter(authentication -> authentication != null && authentication.isAuthenticated()) .map(authentication -> ((Principal)authentication.getPrincipal()).getUsername()) .switchIfEmpty(Mono.just("N/A")); //No user authenticated } So the question is: why is the getPrincipalUsername working only in services and controllers, and not there? And how can I achieve the expected result?

Edit: I know, the request has a method getPrincipal, but it doesn't work either... I see using the debugger that the default implementation is:

(org/springframework/web/server/adapter/DefaultServerWebExchange.java)
@Override public Mono getPrincipal() { return Mono.empty(); }

Источник: https://stackoverflow.com/questions/781 ... in-webflux
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»