2016-08-13 124 views
1

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

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

,使得所有的表单提交才会有这种形式的数据。我不想将此参数添加到每个单独的FORM提交。

+0

也许你想使用ajax? – FreezY

+0

我正要问同样的问题,我也试图创建自己的表单标签,但属性有点复杂,包括/传递给内部表单。接下来是在渲染时重写表单行为。将让你张贴 – TecHunter

+0

最简单的方法是使用JavaScript将此元素添加到每个表单 – TecHunter

回答

0

所以我终于找到了一个可行的解决方案。基本上我创建一个自定义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> 

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

+0

为什么你需要这个?这解决了PrimeFaces尚未解决的问题吗? – Kukeltje

+0

自从您添加与原始问题完全无关的标记(jsf例如)后,我恢复了标记编辑。 – Kukeltje