Spring «Запрос был отклонен, поскольку URL-адрес не был нормализован». Как узнать, какой URL-адрес использовался?

Я получаю массу ошибок в производстве для

org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL was not normalized.

Предположительно, это вызвано // в моих URL-адресах, но я понятия не имею, откуда они берутся. Как я могу узнать, какой URL-адрес вызывает это? Трудно исправить, когда не знаешь, что происходит.

Я понимаю, что существует связанный вопрос, но это не касается того, как диагностировать проблемные URL-адреса. Он касается только того, как отключить строгий брандмауэр.

@Deadpool Это вопрос о том, как остановить эту ошибку, изменив конфигурацию Spring. Я хочу знать, как определить причину ошибки. (Какие URL-адреса вызывают это.) И в этом вопросе нет ответов на мой вопрос, хотя он тесно связан.

CorayThan 02.02.2019 04:20

Привет @CorayThan, Получили ли вы какое-либо решение проблемы, поскольку я вижу похожие проблемы в своих журналах UAT и Prod. С уважением, Маулик

Maulik Kayastha 08.04.2020 09:56

@MaulikKayastha Не думаю, что я это сделал. Был довольно давно. Я бы попробовал ответы, которые дали люди, если бы я был на вашем месте.

CorayThan 09.04.2020 11:18
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
15
3
11 391
3

Ответы 3

Извините, что не опубликовал это как комментарий, но я пока не могу этого сделать.

Вы пробовали другой уровень ведения журнала и запись в файл? Меня сейчас нет дома, но если нет, попробуйте эти строки:

logging.level.=ERROR
logging.file=/home/spring.log

Возможно, также попробуйте ОТЛАЖИВАТЬ в качестве уровня ведения журнала.

В противном случае (хотя и немного хакерски) попробуйте просто заменить каждый // на /

В качестве третьего варианта я нашел этот скрипт, вы можете заставить его работать.

@ExceptionHandler(RequestRejectedException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public String handleRequestRejectedException(final HttpServletRequest request, final RequestRejectedException ex)
{
    if (LOGGER.isLoggable(Level.INFO))
    {
        LOGGER.log(Level.INFO, "Request Rejected", ex);
    }

    LOGGER.log(Level.WARNING, "Rejected request for [" + request.getRequestURL().toString() + "]. Reason: " + ex.getMessage());
    return "errorPage";
}

Удачи, если не получится, я вернусь завтра.

Я думаю, вам нужно вернуться завтра, так как я боюсь, что это не сработает, поскольку @ExceptionHandler - это механизм обработки исключений только для Spring MVC...........

Ken Chan 02.02.2019 11:28

HttpFirewall проверит запрос в самом начале в FilterChainProxy, даже до вызова каких-либо фильтров в SecurityFilterChain. Таким образом, лучше всего настроить Filter, который помещается перед FilterChainProxy, и этот Filter используется для захвата RequestRejectedException и регистрации его сведений.

(1) Реализуйте фильтр, который улавливает это исключение:

public class LogFilter implements Filter{

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {
        try {
            chain.doFilter(request, response);
        } catch (Exception e) {
            if ( e instanceof RequestRejectedException ) {
                logger.info("Catch RequestRejectedException....");
                logger.info((HttpServletRequest)request).getRequestURI()); //log the request detail such as its URI
            }
            throw e;
        }
    }
}

(2) Настройте и зарегистрируйте фильтр

@Bean
public FilterRegistrationBean someFilterRegistration() {
    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(new LogFilter());
    registration.addUrlPatterns("/*");
    registration.setOrder(RegistrationBean.HIGHEST_PRECEDENCE); //Must has higher precedence than FilterChainProxy
    return registration;
} 

Моя проблема заключалась в том, что у меня была конфигурация для использования Spring Security, а также включена аннотация @CrossOrigin для класса контроллера, вот что я только что добавил в свой метод конфигурации.

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // ...
        http.cors(); //Only this
    }
}

Вы также можете проверить здесь для справки: https://www.baeldung.com/spring-cors

Другие вопросы по теме