【问题标题】:servlet Filter is not allowing to load application resourcesservlet 过滤器不允许加载应用程序资源
【发布时间】:2016-10-21 20:02:59
【问题描述】:

我试图阻止CSRF(Cross site request forgery)。为了防止CSRF,我创建了过滤器来过滤每个请求。

在按预期实施javax.servlet.Filter 后,过滤器就完成了它的工作。但是在实现 servlet 过滤器后,我的应用程序资源没有正确加载。

CSS、jQuery、datatable,所有资源都没有正确加载,有时它们正在加载,有时没有。

在实施过滤器之前,它工作正常。

firebug 中的示例错误:

"NetworkError: 500 Internal Server Error - http://localhost:8080/myApp/resources/images/bg-report-content.jpg"

"NetworkError: 500 Internal Server Error - http://localhost:8080/myApp/resources/images/bg-header.jpg"

tworkError: 500 Internal Server Error - http://localhost:8080/myApp/resources/css/dataTables.bootstrap.css"

"NetworkError: 500 Internal Server Error - http://localhost:8080/myApp/resources/js/fnStandingRedraw.js"

"NetworkError: 500 Internal Server Error - http://localhost:8080/myApp/resources/js/dataTables.tableTools.js"

这就是我如何为 CSRF 实现过滤器

我正在做的是,我创建了一个名为LoadSalt 的类,它创建了salt(随机数)。我在jsp中接受的那个随机数。并与 jsp 一起发送请求。

LoadSalt 类

public class LoadSalt implements Filter{

    public Cache<String, Boolean> csrfPreventionSaltCache= null;
    HttpServletRequest httpReq=null;
    //int count=0;

    @SuppressWarnings("unchecked")
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        //count++;

        // Assume its HTTP  
        httpReq = (HttpServletRequest)request;

        if(httpReq.getAttribute("csrfPreventionSaltCache")!=null)
            {
            csrfPreventionSaltCache= (Cache<String, Boolean>) httpReq.getAttribute("csrfPreventionSaltCache");
            }

        if(csrfPreventionSaltCache == null)
        {
            // creating a new cache 
            csrfPreventionSaltCache = CacheBuilder.newBuilder().maximumSize(5000)
                    .expireAfterAccess(5, TimeUnit.MINUTES).build();
            // Setting to httpReq
            httpReq.setAttribute("csrfPreventionSaltCache", csrfPreventionSaltCache);
        }

        // Generate the salt and store it in the users cache
        String salt = RandomStringUtils.random(20, 0, 0, true, true, null, new SecureRandom());
        //System.out.println("Salt: "+salt);
        csrfPreventionSaltCache.put(salt, Boolean.TRUE);

        // Add the salt to the current request so it can be used
        // by the page rendered in this request
        httpReq.setAttribute("csrfPreventionSalt", salt);

        chain.doFilter(httpReq, response);

    }

    public void init(FilterConfig arg0) throws ServletException {
    }
    public void destroy() {
    }
}

另一个验证盐的过滤器

public class ValidateSalt implements Filter {

    public Cache<String, Boolean> csrfPreventionSaltCache= null;

    @SuppressWarnings("unchecked")
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        // Assume its HTTP
        HttpServletRequest httpReq = (HttpServletRequest) request;
        HttpServletResponse httpResponse =(HttpServletResponse) response;

        String salt =(String) httpReq.getAttribute("csrfPreventionSalt");

     // Validate that the salt is in the cache
        if(httpReq.getAttribute("csrfPreventionSaltCache")!=null)
        {
         csrfPreventionSaltCache = (Cache<String, Boolean>) httpReq.getAttribute("csrfPreventionSaltCache");
        }

        if(csrfPreventionSaltCache !=null && salt !=null && csrfPreventionSaltCache.getIfPresent(salt)!=null)
        {

                String metodName =httpReq.getMethod();
                String saltFromJspPage = httpReq.getParameter("salt");  
                //String saltFromRequest =(String) httpReq.getAttribute("csrfPreventionSalt");


                if(metodName.equalsIgnoreCase("POST"))
                    {

                        if(saltFromJspPage!=null && csrfPreventionSaltCache.getIfPresent(saltFromJspPage)!=null)
                        {
                            chain.doFilter(httpReq, response);
                        else
                        {
                            //throw new ServletException("Potential CSRF detected!! Please contact to system admin ASAP.");
                            httpResponse.sendRedirect("/myApp/pages/pageNotFound.jsp");
                        }
                    }
                else
                {
                     chain.doFilter(httpReq, response);
                }
        }
        else
        {
            // Otherwise we throw an exception aborting the request flow
            //throw new ServletException("Potential CSRF detected!! Inform a scary sysadmin ASAP.");
            httpResponse.sendRedirect("/myApp/pages/pageNotFound.jsp");
        }
    }

    public void init(FilterConfig arg0) throws ServletException {
    }
    public void destroy() { 
    }
}

web.xml 中的 servlet 过滤器映射

  <filter>
       <filter-name>loadSalt</filter-name>
       <filter-class>com.mpApp.security.LoadSalt</filter-class>
   </filter>

   <filter-mapping>
      <filter-name>loadSalt</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>

   <filter>
       <filter-name>validateSalt</filter-name>
       <filter-class>com.mpApp.security.ValidateSalt</filter-class>
   </filter>            

  <filter-mapping>
       <filter-name>validateSalt</filter-name>
        <url-pattern>/*</url-pattern>
   </filter-mapping>

我的申请有什么问题?

为什么 servlet 过滤器不允许加载资源?虽然有时它可以工作,但有时它不能,

这是什么路径原因?

我是否以错误的方式实现 servlet 过滤器。

请帮忙。

【问题讨论】:

  • 正如我在问题中提到的,有时它允许加载资源,但有时却不允许。我在新的浏览器选项卡中检查了各个资源的 URL,它们是可见的。你能帮我解决他的问题吗
  • 服务器在我的情况下没有抛出异常,但我的大部分 jQuery 在实现过滤器后无法加载到页面上
  • 你找到根本原因了吗?

标签: filter csrf servlet-filters csrf-protection


【解决方案1】:

网址格式太宽,将尝试将盐应用于每个请求。将其保留在您可以设置和检查盐值的动态部分,例如 /transferOperationServlet 或 /prettyImportantServlet 或 *.jsp

【讨论】:

    猜你喜欢
    • 2015-04-14
    • 2017-12-31
    • 2017-04-10
    • 2016-10-08
    • 2016-11-04
    • 2014-12-10
    • 1970-01-01
    相关资源
    最近更新 更多