返回 HTTP 错误 401 代码并跳过过滤器链

Posted

技术标签:

【中文标题】返回 HTTP 错误 401 代码并跳过过滤器链【英文标题】:Return HTTP Error 401 Code & Skip Filter Chains 【发布时间】:2014-06-30 12:34:57 【问题描述】:

使用自定义 Spring Security 过滤器,如果 HTTP 标头不包含特定的键值对,我想返回 HTTP 401 错误代码。

例子:

public void doFilter(ServletRequest req, ServletResponse res,
                     FilterChain chain) throws IOException, ServletException 

   HttpServletRequest request = (HttpServletRequest) req;
   final String val = request.getHeader(FOO_TOKEN)

   if(val == null || !val.equals("FOO")) 
       // token is not valid, return an HTTP 401 error code
       ...
   
   else 
    // token is good, let it proceed
    chain.doFilter(req, res);
   

据我了解,我可以执行以下操作:

(1)((HttpServletResponse) res).setStatus(401) 并跳过剩余的过滤器链

(2) 抛出异常,最终导致 Spring Security 向客户端抛出 401 错误。

如果 #1 是更好的选择,在响应上调用 setStatus(401) 后如何跳过过滤器链?

或者,如果 #2 是正确的方法,我应该抛出哪个异常?

【问题讨论】:

如果您从setStatus 之后的方法返回,将停止进一步处理请求。只有调用chain.doFilter,过滤器链才会继续。 谢谢卢克。我会试试的。发布作为答案?也可以请您发布一个参考,以便我可以阅读更多? 你可能想像这里一样实现一个 AuthenticationEntryPoint:***.com/questions/19767267/… 【参考方案1】:

我在下面推荐这个解决方案。

public void doFilter(ServletRequest req, ServletResponse res,
                         FilterChain chain) throws IOException, ServletException 

        HttpServletRequest request = (HttpServletRequest) req;
        final String val = request.getHeader(FOO_TOKEN)

        if (val == null || !val.equals("FOO")) 
            ((HttpServletResponse) response).sendError(HttpServletResponse.SC_UNAUTHORIZED, "The token is not valid.");
         else 
            chain.doFilter(req, res);
        
    

【讨论】:

它可以工作,但它在日志中给出了这个错误java.lang.IllegalStateException: Cannot call sendError() after the response has been committed【参考方案2】:

从API docs for the doFilter method,您可以:

或者使用 FilterChain 对象 (chain.doFilter()) 调用链中的下一个实体, 不将请求/响应对传递给过滤器链中的下一个实体以阻止请求处理

因此设置响应状态代码并立即返回而不调用chain.doFilter 是您想要在此处实现的最佳选择。

【讨论】:

【参考方案3】:

按照他们在上面的答案中所说的去做。 “所以设置响应状态码并立即返回” 这只是类型:

res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);  
return;

【讨论】:

【参考方案4】:

所以你可以使用这样的东西。

@Override
public void doFilter() 
    if (whiteListOrigins.contains(incomeOrigin)) 
        httpResponse.setHeader("Access-Control-Allow-Origin", incomeOrigin);
        chain.doFilter(request, response);
     else 
        ((HttpServletResponse) response).sendError(HttpServletResponse.SC_FORBIDDEN, "Not Allowed to Access. Please try with valid Origin.");
    

【讨论】:

它给出了这个错误 java.lang.IllegalStateException: Cannot call sendError() after the response has been commited。

以上是关于返回 HTTP 错误 401 代码并跳过过滤器链的主要内容,如果未能解决你的问题,请参考以下文章

收到错误 java.io.IOException:服务器返回 HTTP 响应代码:401

使用 Promise 并跳过代码时,Mocha 测试超时,为啥?

R-从 PurpleAir 传感器读取 csv 文件并跳过某些行末尾包含非标准字符的错误位置

在访问中提取一系列日期并跳过假期

记录一下http请求时各个返回码的定义

读取 C 源文件并跳过 /**/ 注释