如何在JSF-Spring集成应用程序中启用CSRF保护 [英] How to enable CSRF protection in JSF-Spring integrated application

查看:89
本文介绍了如何在JSF-Spring集成应用程序中启用CSRF保护的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个JSF-Spring集成应用程序. Spring Security也集成在此应用程序中.这些是我的应用程序中的版本:

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
  • 春季4.0.3.发布
  • Spring Security 3.2.4.发布

根据 JSF doc JSF2.x(甚至旧版本)中的所有POST请求都将受CSRF保护.但是我可以通过CSRF攻击渗透我的应用程序.

As per the JSF doc all the POST request in JSF2.x [or even old versions] will be CSRF protected. However I am able to penetrate my application with CSRF attack.

我尝试了另一个仅JSF2.2的[no Spring]示例应用程序,在这种情况下,我可以看到此示例应用程序受CSRF保护.

I tried a different JSF2.2 only [no Spring] example application, in that case I can see this example application is CSRF protected.

所以我的理解是,JSF/Spring/Spring安全组合在我的原始应用程序中出现了问题. 不幸的是,日志文件中没有任何帮助信息.

So my understanding is, the JSF/Spring /Spring security combination is giving issue in my original application. Unfortunately there is no helping info from the log files.

我可以尝试使用 Spring Security CSRF保护.在那种情况下,挑战在于我需要在所有POST情况下都编辑代码.

I can try with the Spring Security CSRF protection. In that case the challenge is I need to edit the code in all POST cases.

我正在寻求启用JSF CSRF保护以避免此代码更改.有什么建议吗?

I am looking to enable JSF CSRF protection to avoid this code change. Any suggestion?

我正在使用皮纳塔进行测试.

推荐答案

经过Spring 4.3.7和Spring Security 4.2.2的测试.

您需要将CSRF令牌添加到应用程序中的每个form. 任何PATCH, POST,PUT和DELETE 将受Spring安全性保护(用于基本动词). 为了避免在每个表单中手动插入隐藏的输入,您可以在提供的表单之上创建一个FormRenderer:

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

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

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

<?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>

也不要忘记在您的spring上下文中启用CSRF:

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

<security:http auto-config="true" entry-point-ref="preAuthenticatedProcessingFilterEntryPoint"
               use-expressions="true">
    <security:csrf/>
    <security:access-denied-handler error-page="/exception/accessDenied.xhtml"/>

    <security:intercept-url pattern="/**" access="hasAnyRole('ROLE_ADMINISTRATOR','ROLE_GUEST')"/>
    <security:intercept-url pattern="/exception/accessDenied.xhtml" access="permitAll"/>
</security:http>

对于AJAX调用,您还需要将此令牌添加到任何受保护的HTTP动词的数据中.您可以直接从DOM中检索令牌.

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.

这篇关于如何在JSF-Spring集成应用程序中启用CSRF保护的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆