返回HTTP错误401代码和跳过筛选链

Kev*_*ith 18 spring-security

使用自定义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);
   }
Run Code Online (Sandbox Code Playgroud)

据我了解,我可以做以下事情:

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

要么

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

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

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

Sha*_*eep 22

从该方法API文档中doFilter,您可以:

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

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


Cyv*_*yva 20

我建议在下面解决这个问题

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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • 它可以工作,但它在日志“java.lang.IllegalStateException:响应已提交后无法调用 sendError()”中出现此错误。 (3认同)

小智 6

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

res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);  
return;
Run Code Online (Sandbox Code Playgroud)


小智 5

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

@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.");
    }
}
Run Code Online (Sandbox Code Playgroud)