需要帮助解决和理解com.adobe.granite.csrf.impl.CSRFFilter doFilter:提供的CSRF令牌在AEM 6.1中无效

时间:2015-12-03 10:47:03

标签: cq5 aem

问题概述:

我们正在将我们的系统从CQ5.4升级到AEM 6.1。 在现有代码中,我们使用ajax引用了POST.jsp,我们在其中调用身份验证服务来验证系统的外部用户。 当我们对资源POST.jsp执行ajax发布时,我们收到以下错误。在error.log中。 com.adobe.granite.csrf.impl.CSRFFilter doFilter:提供的CSRF令牌无效

我们尝试了什么:

  1. 要解决此问题,我们按照AEM 6.1 docs https://docs.adobe.com/docs/en/aem/6-1/administer/security/security-checklist.html#par_title_1046104842尝试了解决方案 但它没有奏效。
  2. 我们尝试从system / console / configMgr中的Adobe Granite CSRF过滤器配置中的过滤器方法中删除POST。这有效,但这会影响我们系统的安全性,因为它允许 其他外部系统来POST数据。 (如果我在安全方面出错,请纠正我)
  3. 我们尝试在系统/ console / configMgr的Adobe Granite CSRF过滤器配置中的安全用户代理中添加Google Chrome浏览器用户代理。这可以工作,但应用程序可以用于其他各种用户代理,我们无法在安全用户代理中将其列入白名单。
  4. 我们还解压缩了com.adobe.granite.csrf.impl.CSRFFilter并找到了以下代码:

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain Chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest)req;
        if ((request.getAuthType() != null) && (isFilteredMethod(request)) && (doFilterBasedOnUserAgent(request)) && (!isValidRequest(request))) {
            HttpServletResponse response = (HttpServletResponse)res;
    
            this.logger.info("doFilter: the provided CSRF token is invalid");
            response.sendError(403);
            return;
        }
        chain.doFilter(req, res);
    }
    

    在上面的代码中, isFilteredMethod检查当前请求(POST)是否存在于Adobe Granite CSRF过滤器的已配置过滤方法中。 doFilterBasedOnUserAgent检查配置的用户代理中是否缺少当前请求的用户代理。
    在我们的例子中,request.getAuthType是“FORM”。所以这不会导致(403)。

      

    isValidRequest获取请求参数:cq_csrf_token并检查是否   此参数值有效。 (观察到这一点并在我们的案例中有效   并发送参数)

    那么过滤方法和用户代理的意义何在?为什么CSRF为POST.jsp发送403,尽管所有CQ和AEM 5.x版本都支持这种POSTING请求?

2 个答案:

答案 0 :(得分:2)

所以你可以做几件事 -

  1. 使用cq.jquery clientlib进行jquery,而不是手动创建和包含jquery lib。 aem提供了jquery有代码来处理csrf令牌。
  2. 在您的代码中包含granite.csrf.standalone clientlib。它会为你做的。
  3. 您可以从/libs/granite/csrf/token.json手动获取令牌的值。使用CSRF-Token标头中的每个请求发送此值。

答案 1 :(得分:0)

或者,您可以在“ Adob​​e Granite CSRF过滤器配置”下过滤自己的servlet,而不是使用cq jquery允许所有POST请求或更高版本。