需要帮助解决和理解com.adobe.granite.csrf.impl.CSRFFilter doFilter:提供的



问题概述:

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

我们尝试过什么:

  1. 为了解决这个问题,我们根据AEM 6.1文档尝试了解决方案https://docs.adobe.com/docs/en/aem/6-1/administer/security/security-checklist.html#par_title_1046104842.
    但这并没有奏效
  2. 我们尝试从system/console/configMgr的Adobe Granite CSRF filter配置中的筛选器方法中删除POST。这起到了作用,但这影响了我们系统的安全性,因为它允许其他外部系统到POST数据。(如果我在安全方面说错了,请纠正我)
  3. 我们尝试从system/console/configMgr在Adobe Granite CSRF Filter配置中的安全用户代理中添加谷歌chrome浏览器用户代理。这起到了作用,但该应用程序可以从各种其他用户代理中使用,我们无法将其保留在安全用户代理的白名单中

此外,我们对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 Filter的已配置过滤方法中
doFilterBasedOnUserAgent检查当前请求的用户代理在配置的用户代理中是否不存在
request.getAuthType在我们的例子中是"FORM"。因此,这不会导致(403)

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

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

所以你可以做几件事-

  1. 将cq.jquery客户端库用于jquery,而不是手动创建并包含jquery库。aem提供的jquery有处理csrf令牌的代码
  2. 在代码中包含granite.csrf.standalone clientlib。它会为你做这些事情
  3. 您可以从/libs/agrante/csrf/token.json手动获取令牌的值。在csrf令牌头中的每个请求中都发送此值

或者,您可以在"Adobe Granite CSRF filter configuration"下过滤自己的servlet,而不是使用cq-jquery允许所有POST请求或以上请求。

最新更新