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

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

问题描述

我有一个 JSF-Spring 集成应用程序.此应用程序中还集成了 Spring 安全性.这些是我的应用程序中的版本:

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
  • Spring 4.0.3.RELEASE
  • Spring Security 3.2.4.RELEASE

根据 JSFdoc 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 [没有 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?

我正在使用 Pinata 进行测试.

I am doing my testing with Pinata.

推荐答案

已通过 Spring 4.3.7 和 Spring Security 4.2.2 测试.

您需要向应用程序中的每个 form 添加 CSRF 令牌.任何补丁,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("
");
        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天全站免登陆