【问题标题】:Return HTTP Error 401 Code & Skip Filter Chains返回 HTTP 错误 401 代码并跳过过滤器链
【发布时间】: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:stackoverflow.com/questions/19767267/…

标签: spring-security


【解决方案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。
      猜你喜欢
      • 1970-01-01
      • 2015-05-06
      • 1970-01-01
      • 1970-01-01
      • 2012-07-02
      • 2013-08-15
      • 1970-01-01
      • 1970-01-01
      • 2021-12-05
      相关资源
      最近更新 更多