Spring Boot: получение параметров строки запроса и тела запроса в слушателе AuditApplicationEvent - PullRequest
0 голосов
/ 29 июня 2018

Spring Boot REST приложение здесь. Я пытаюсь настроить аудит запросов Spring Boot для регистрации каждого HTTP-запроса, который получают любые ресурсы / контроллеры, со следующей информацией:

  1. Мне нужно видеть в журналах точный URL-адрес HTTP (путь), запрошенный клиентом, включая метод HTTP и любые параметры строки запроса ; и
  2. Если есть тело запроса (например, с POST или PUT), мне нужно также просмотреть содержимое этого тела в журналах

Моя лучшая попытка на данный момент:

@Component
public class MyAppAuditor {
    private Logger logger;

    @EventListener
    public void handleAuditEvent(AuditApplicationEvent auditApplicationEvent) {
        logger.info(auditApplicationEvent.auditEvent);
    }
}

public class AuditingTraceRepository implements TraceRepository {
    @Autowired
    private ApplicationEventPublisher applicationEventPublisher

    @Override
    List<Trace> findAll() {
        throw new UnsupportedOperationException("We don't expose trace information via /trace!");
    }

    @Override
    void add(Map<String, Object> traceInfo) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        AuditEvent traceRequestEvent = new AuditEvent(new Date(), "SomeUser", 'http.request.trace', traceInfo);
        AuditApplicationEvent traceRequestAppEvent = new AuditApplicationEvent(traceRequestEvent);

        applicationEventPublisher.publishEvent(traceRequestAppEvent);
    }
}

Однако во время выполнения, если я использую следующую команду curl:

curl -i -H "Content-Type: application/json" -X GET 'http://localhost:9200/v1/data/profiles?continent=NA&country=US&isMale=0&height=1.5&dob=range('1980-01-01','1990-01-01')'

Тогда я вижу только следующие сообщения журнала (где MyAppAuditor отправляет события аудита):

{ "timestamp" : "14:09:50.516", "thread" : "qtp1293252487-17", "level" : "INFO", "logger" : "com.myapp.ws.shared.auditing.MyAppAuditor", "message" : {"timestamp":"2018-06-29T18:09:50+0000","principal":"SomeUser","type":"http.request.trace","data":{"method":"GET","path":"/v1/data/profiles","headers":{"request":{"User-Agent":"curl/7.54.0","Host":"localhost:9200","Accept":"*/*","Content-Type":"application/json"},"response":{"X-Frame-Options":"DENY","Cache-Control":"no-cache, no-store, max-age=0, must-revalidate","X-Content-Type-Options":"nosniff","Pragma":"no-cache","Expires":"0","X-XSS-Protection":"1; mode=block","X-Application-Context":"application:9200","Date":"Fri, 29 Jun 2018 18:09:50 GMT","Content-Type":"application/json;charset=utf-8","status":"200"}},"timeTaken":"89"}} }

Итак, как вы можете видеть, аудитор выбирает базовый путь (/v1/data/profiles), но не регистрирует ни один из параметров строки запроса. Я также вижу аналогичное отсутствие информации о теле запроса при попадании в конечные точки POST или PUT, для которых действительно требуется тело запроса (JSON).

Что мне нужно сделать, чтобы настроить эти классы (или другие классы / конфиги Spring) так, чтобы я получил требуемый уровень аудита запросов?

1 Ответ

0 голосов
/ 03 июля 2018

К счастью, Actuator позволяет очень просто настроить эти Trace события.

Добавление параметров к информации о трассировке

Вы можете посмотреть на все варианты. Вы заметите значения по умолчанию (line 42):

Include.REQUEST_HEADERS, 
Include.RESPONSE_HEADERS, 
Include.COOKIES, 
Include.ERRORS, 
Include.TIME_TAKEN

Так что вам нужно будет также добавить Include.PARAMETERS и все, что вы хотели бы иметь в трассировке. Чтобы настроить это, есть свойство конфигурации для этого management.trace.include.

Таким образом, чтобы получить то, что вы хотите (т. Е. parameters), плюс значения по умолчанию, у вас будет:

management.trace.include = parameters, request-headers, response-headers, cookies, errors, time-taken

Добавление тела запроса к информации о трассировке

Чтобы получить body, вам нужно будет добавить это Bean к вашему Context:

@Component
public class WebRequestTraceFilterWithPayload extends WebRequestTraceFilter {

    public WebRequestTraceFilterWithPayload(TraceRepository repository, TraceProperties properties) {
        super(repository, properties);
    }

    @Override
    protected Map<String, Object> getTrace(HttpServletRequest request) {
        Map<String, Object> trace = super.getTrace(request);

        String body = null;
        try {
            body = request.getReader().lines().collect(Collectors.joining("\n"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        if(body != null) {
            trace.put("body", body);
        }

        return trace;
    }

}

Приведенный выше код переопределит bean-компонент AutoConfigure'd WebRequestTraceFilter (который, поскольку он равен @ConditionalOnMissingBean, будет отдавать предпочтение вашему пользовательскому bean-компоненту), и вытянет дополнительное свойство полезной нагрузки из request, а затем добавит его в в Map свойства, которые публикуются в TraceRepository!

Резюме

  1. Параметры запроса можно добавить к TraceRepository trace events с помощью свойства management.trace.include
  2. Тело запроса может быть добавлено к TraceRepository trace events путем создания расширенного Bean для считывания body из HTTP-запроса и дополнения событий трассировки
...