400 неправильных запросов возвращено при весенней загрузке еще до того, как запрос достигнет фильтра - PullRequest
0 голосов
/ 07 января 2019

У меня есть приложение весенней загрузки с сервисом GET.

@RequestMapping(value = "/abc/track/{type}", method = RequestMethod.GET)

    public void DummFunc(                            
          @RequestParam(value="subs", required = false) String sub,
,  HttpServletResponse response) {}

значение для subs является закодированным значением.

Если я передам следующее в качестве значения параметра subs

{%22endpoint%22:%22https://def.abc.com/tyu/send/eD3vpGNQW28:APA91bHOo8rYrV0xccdQz3okjZJG-QGrJX8LG6ahJnEUpMNfGedqi3hJxQsJx_8BMbH6oDjaSPPEXqzNWchWrGSkhuTkSdemikkys1U22Ipd7MsRw0owWbw89V2fslIVAJ6G5lkyvYuQ%22,%22expirationTime%22:null,%22keys%22:{%22p256dh%22:%22BK0pktn50CMsTQtqwdPlKlJtdFs0LFeXX14T1zgoz6QWnvSTp5dxtChnUP5P1JX0TsjcopbdPKyN31HfABMUyic%22,%22auth%22:%22qbO_z0vGao9wD-E5g8VU-A%22}}

Не удается захватить запрос, и управление не входит в функцию.

Если вместо этого мы передадим значение в параметрах sub:

%7B%22endpoint%22:%22https://def.abc.com/tyu/send/dX5q5eV7hFQ:APA91bHib-0QXrMzjatcvTR_uaIeeJK8lf6GmXUC9Jxv0Oxth-BzD4GmWnd4-YpDZv8qSFZ0eSg9mB2YkRvkc5ezdXW5KeaHjuQZfdyDxyBXjJgE-25Xbtlk37pdm8vfLk20k0k_VxW9%22,%22expirationTime%22:null,%22keys%22:%7B%22p256dh%22:%22BCCvcBLpRqp4u0auP688_MUJLsAiwWlQSn5kpyl8YVsEo_J-KpSdnhCmVIE_BhDXBcFYflPK52hqhYf3EaOCyuY%22,%22auth%22:%22iKuW_ESkCZnubWcQu_JK8w%22%7D%7D

Работает нормально.

По сути, запрос, по которому была получена проблема, имеет { и } вместо %7B и %7D.

Мой вопрос - вместо сбоя приложения с 400 ошибочными запросами, как мне перехватить такие запросы в моем приложении, правильно их кодировать, а затем обработать или, по крайней мере, обработать эту ошибку

Также я попытался добавить Filter и RestControllerAdvice.

Результаты на данный момент:

  1. Я понял, что, вероятно, запрос даже не достигает приложения, потому что если я удаляю DummFunc из моего кода, который сопоставлен с запросом /abc/track/{type}, он все равно не возвращает 404, а только 400.
  2. CommonsLoggingFilter не регистрирует этот конкретный запрос с 400 неверным кодом ответа, но может регистрировать остальные запросы (еще один намек на то, что запрос не попадает в приложение - я думаю)
  3. Во время отладки я понял, что если я получаю этот API из приложения chrome Postman и браузера, он возвращает 400 плохих запросов, но если я получаю этот API из настольного приложения Postman, он возвращает 200.
  4. Я также пытался добавить обработчик исключений в контроллер через новый класс, никто из них не перехватил запрос

// @ResponseStatus(HttpStatus.BAD_REQUEST)
        @ExceptionHandler(Throwable.class)
        public void handle(HttpMessageNotReadableException e) {
            System.out.println("EXCEPTION HAPPENED");
            System.out.println(e);
        }

В моем application.properties соответствующие реквизиты выглядят следующим образом:

spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true

#security.user.name=user
#security.basic.enabled=true


logging.level.org.springframework.web.filter.CommonsRequestLoggingFilter=DEBUG,stdout
log4j.logger.httpclient.wire=DEBUG,stdout
management.endpoints.web.exposure.include=*
management.endpoint.beans.cache.time-to-live=10s
server.tomcat.accesslog.enabled = true
log4j.logger.org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod=DEBUG,stdout
logging.level.org.springframework.web=DEBUG,stdout
server.tomcat.uri-encoding=UTF-8

Итак, что можно сделать, чтобы правильно с этим справиться?

Я использую IntelliJ и встроенный сервер Tomcat.

Ответы [ 2 ]

0 голосов
/ 07 января 2019

Я настоятельно рекомендую вам использовать RequestMethod.POST вместо RequestMethod.GET.

"{", "}", "|", "\", "^", "~", "[", "]", and " "` все "не безопасные символы", вы были настолько умны, используя% 7B и% 7D, это должно сработать, просто убедитесь, что вы используете% 7B и% 7D в правильном порядке.

В Postman они работают, потому что Postman интерпретирует фигурные скобки как переменные среды. Поправьте меня, если я ошибаюсь, но, думаю, почтальон вернет вам 200, но ваша заявка все еще не получает никаких данных. (Правильно?)

Есть еще одно возможное решение ... 400 означает, что ошибка предполагается на стороне клиента, просто попробуйте отправить зашифрованные данные в виде простой строки, а затем обработать эту строку на стороне сервера.

Удачи!

0 голосов
/ 07 января 2019

По сути, проблема была в том, что Tomcat не пропускал запрос.

Это поведение было введено в Tomcat 7.0.76, 8.0.42 и 8.5.12, чтобы соответствовать RFC 7231.

Эту принудительную проверку можно отменить, используя свойство requestTargetAllow в catalina.properties, чтобы разрешить запрещающие символы:

tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}

Поскольку я использую встроенный кот в Intellij и не могу редактировать cataline.properties напрямую, я добавил

-Dtomcat.util.http.parser.HttpParser.requestTargetAllow=|{}

до VM Options в Run -> Edit Configuration.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...