Spring “请求被拒绝,因为 URL 未规范化。”如何判断使用了啥网址?

Posted

技术标签:

【中文标题】Spring “请求被拒绝,因为 URL 未规范化。”如何判断使用了啥网址?【英文标题】:Spring "The request was rejected because the URL was not normalized." How to tell what url was used?Spring “请求被拒绝,因为 URL 未规范化。”如何判断使用了什么网址? 【发布时间】:2019-06-26 15:06:37 【问题描述】:

我在生产中遇到了很多错误

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

据说这是由我的网址中的// 引起的,但我不知道它们来自哪里。我怎么知道是什么 url 导致了这个?当您不知道发生了什么时很难解决。

我确实意识到有一个相关的question,但这并没有解决如何诊断问题 URL。它只涉及如何关闭严格的防火墙。

【问题讨论】:

@Deadpool 这是一个关于如何通过更改 Spring 配置来停止此错误的问题。我想知道如何确定错误的原因。 (是什么 URL 造成的。)尽管它密切相关,但我在该问题中的问题没有答案。 嗨@CorayThan,你有没有解决这个问题,因为我在我的 UAT 和 Prod 日志中看到了类似的问题。问候,毛利克 @MaulikKayastha 我想我没有。是很久以前的事了。如果我是你,我会尝试人们给出的答案。 【参考方案1】:

很抱歉没有将此作为评论发布,但我还不能这样做。

您是否尝试过其他日志记录级别并记录到文件?我现在不在家,但如果不试试以下几行:

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

也许也可以尝试 DEBUG 作为日志记录级别

Otherwhys(虽然有点 hacky)尝试将每个 // 替换为 /

作为第三个选项,我找到了这个脚本,你可以让它工作。

@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 的异常处理机制............【参考方案2】:

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;
 

【讨论】:

【参考方案3】:

我的问题是我有一个使用 Spring Security 的配置,并且还在控制器类上启用了@CrossOrigin Annotation,下面是我刚刚添加到我的配置方法中的内容。

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

您也可以在这里查看参考:https://www.baeldung.com/spring-cors

【讨论】:

以上是关于Spring “请求被拒绝,因为 URL 未规范化。”如何判断使用了啥网址?的主要内容,如果未能解决你的问题,请参考以下文章

Spring框架系列 - Spring和Spring框架组成

你了解Spring从Spring3到Spring5的变迁吗?

Spring全家桶笔记:Spring+Spring Boot+Spring Cloud+Spring MVC

学习笔记——Spring简介;Spring搭建步骤;Spring的特性;Spring中getBean三种方式;Spring中的标签

Spring--Spring入门

Spring框架--Spring事务管理和Spring事务传播行为