Мне нужно опубликовать ответ любого контроллера 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 возвратил
- Flowable
- , чтобы реализовать приведенный выше код реагирующим образом
Это то, что я сделал до сих пор.
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?
}
});
}
Может ли кто-нибудь дать мне подсказку, как продолжить обработку тела ответа, выполнить проверку безопасности, удалить элементы и сбросить новое тело?