【问题标题】:Add CSRF token to all the FORM submissions将 CSRF 令牌添加到所有 FORM 提交
【发布时间】:2016-12-20 06:19:32
【问题描述】:

我最近在我的 Web 应用程序中启用了 CSRF 保护。大约有 100 多个 JSP 页面包含 FORM 提交。添加 CSRF 令牌的最佳方法是什么:

<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> 

这样所有的表单提交都会有这个表单数据。我不想将此参数添加到每个单独的 FORM 提交中。

【问题讨论】:

  • 也许你想用ajax?
  • 我正要问同样的问题,我也在尝试创建自己的表单标签,但属性有点复杂,无法包含/传递给内部表单。接下来是在呈现时覆盖表单行为。会及时通知您
  • 最简单的方法是使用 javascript 将此元素添加到每个表单
  • @TecHunter:部分还原了标签编辑。 jsf 和 java-ee 与原始问题完全无关...您可以创建一个新的特定问题并自己回答或回答this question
  • @Kukeltje 哦,我把这个问题误认为是 jsf 问题......

标签: spring-security csrf csrf-protection


【解决方案1】:

所以我终于找到了一个可行的解决方案。基本上我创建了一个这样的自定义 FormRenderer:

import com.sun.faces.renderkit.html_basic.FormRenderer;

import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import java.io.IOException;

public class FormWithCSRFRenderer extends FormRenderer {

    @Override
    public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
        log.debug("FormWithCSRFRenderer - Adding CSRF Token to form element");
        ELContext elContext = context.getELContext();
        ExpressionFactory expFactory = context.getApplication().getExpressionFactory();

        ResponseWriter writer = context.getResponseWriter();
        writer.startElement("input", component);
        writer.writeAttribute("type", "hidden", null);
        writer.writeAttribute("name", expFactory.createValueExpression(elContext, "${_csrf.parameterName}", String.class).getValue(elContext), null);
        writer.writeAttribute("value", expFactory.createValueExpression(elContext, "${_csrf.token}", String.class).getValue(elContext), null);
        writer.endElement("input");
        writer.write("\n");
        super.encodeEnd(context, component);
    }
}

然后通过在faces-config.xml 中设置它来注册它以覆盖FormRenderer:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
              version="2.2">
    <render-kit>
        <renderer>
            <component-family>javax.faces.Form</component-family>
            <renderer-type>javax.faces.Form</renderer-type>
            <renderer-class>com.acme.FormWithCSRFRenderer</renderer-class>
        </renderer>
    </render-kit>
</faces-config>

我尝试创建一个组件,然后将其添加为子组件,但它不允许我正确设置输入的名称,所以我直接编写它。

【讨论】:

  • 为什么需要这个?这解决了哪些 PrimeFaces 尚未为您解决的问题?
  • 由于您添加了与原始问题完全无关的标签(例如 jsf),因此我恢复了您的标签编辑。
猜你喜欢
  • 2015-04-09
  • 2021-10-29
  • 2018-05-11
  • 2018-10-08
  • 2016-09-19
  • 2020-07-06
  • 2012-11-19
  • 2018-07-28
  • 2019-07-28
相关资源
最近更新 更多