How to enable CSRF protection in JSF-Spring integrated application

后端 未结 1 1766
一个人的身影
一个人的身影 2021-01-07 07:25

I have a JSF-Spring integrated application. Spring security is also integrated in this application. These are the versions in my application:

  • JSF 2.2
1条回答
  •  天涯浪人
    2021-01-07 07:28

    Tested with Spring 4.3.7 and Spring Security 4.2.2.

    You need to add a CSRF token to every form in your application. Any PATCH, POST, PUT and DELETE will be protected by Spring security (for the basic verbs). To avoid inserting a hidden input in every form manually you can create a FormRenderer on top of the provided one :

    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);
        }
    }
    

    Then register it to override the FormRenderer by setting it in faces-config.xml :

    
    
        
            
                javax.faces.Form
                javax.faces.Form
                com.acme.FormWithCSRFRenderer
            
        
    
    

    Also don't forget to enable CSRF in your spring context :

    
        
        
    
        
        
    
    

    For your AJAX calls, you will also need to add this token in the data of any protected HTTP Verb. You can retrieve the token directly from the DOM.

    0 讨论(0)
提交回复
热议问题