Фильтр HTTP Micronaut для изменения полезной нагрузки ответа - PullRequest
2 голосов
/ 08 апреля 2020

Мне нужно опубликовать ответ любого контроллера Micronaut и исключить элементы в теле ответа, когда пользователь не авторизован для доступа к ним.

В мире блокировки я бы реализовал его как

protected MutableHttpResponse<?> doFilterOnce(HttpRequest<?> request, ServerFilterChain chain) {

        // If Micronaut Security rejected the request simpy do nothing
        if (request.getAttribute(SecurityFilter.REJECTION).isPresent()) {
            log.debug("Request was previously rejected. Not going to contact PDP");
            return chain.proceed(request);
        }

        HttpMethod method = request.getMethod();

        if (method.equals(GET) || method.equals(HEAD)) {

            MutableHttpResponse<?> response = chain.proceed(request);

            if (response.getBody().isPresent()) {
                // iterate through the body

                Object theBody = response.getBody().get();

                if (theBody instanceof Collection) {

                    Collection<?> iterable = (Iterable<?>) theBody;

                    // select all elements that are rejected. This is a blocking call.
                    List<?> collect = iterable.stream().filter(item -> mySecService.isAllowed(item) == false).collect(Collectors.toList());
                    // remove them
                    iterable.removeAll(collect);
                    // reset the body
                    response.body(iterable);
                }
            }

        } else {
            return chain.proceed(request)
        }
        return response;
    }

Micronaut заявляет, что

Фильтры выполняются в событии l oop, поэтому операции блокировки должны быть выгружены в другой пул потоков.

и, следовательно, в реальном мире требуется, чтобы mit возвратил

  1. Flowable
  2. , чтобы реализовать приведенный выше код реагирующим образом

Это то, что я сделал до сих пор.

if (method.equals(GET) || method.equals(HEAD)) {
    // post process
    return Flowable.fromPublisher(chain.proceed(request))
            .doNext(response -> {
                Optional<?> body = response.getBody();

                if (body.isPresent()) {
                     // how can I continue here an process the response body collection?
                }
            });
}

Может ли кто-нибудь дать мне подсказку, как продолжить обработку тела ответа, выполнить проверку безопасности, удалить элементы и сбросить новое тело?

...