_csrf 令牌在同一个 JSP 中的 2 种形式(CSRF 保护)

Posted

技术标签:

【中文标题】_csrf 令牌在同一个 JSP 中的 2 种形式(CSRF 保护)【英文标题】:_csrf token in 2 forms in the same JSP (CSRF protection) 【发布时间】:2016-02-25 15:08:49 【问题描述】:

我想保护我的应用程序免受跨站请求伪造 (CSRF) 攻击,所以我将其添加到我的

applicationContext.xml:

<security:global-method-security secured-annotations="enabled" />

        <security:http auto-config="true">
            <security:csrf/>    
            <security:intercept-url pattern="/**" access="permitAll"    />
        </security:http>

<security:authentication-manager/>  

这个到我的 web.xml

<!-- spring security csrf -->
        <filter>
            <filter-name>springSecurityFilterChain</filter-name>
            <filter-class>fr.telecom.support.context.DevicesSecurityFilter</filter-class>
        </filter>    
        <filter-mapping>
            <filter-name>springSecurityFilterChain</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>

这是我的过滤器

public class DevicesSecurityFilter extends DelegatingFilterProxy 

    public DevicesSecurityFilter() 
        // TODO Auto-generated constructor stub
    

    public DevicesSecurityFilter(Filter delegate) 
        super(delegate);
    

    public DevicesSecurityFilter(String targetBeanName) 
        super(targetBeanName);
    

    public DevicesSecurityFilter(String targetBeanName,
            WebApplicationContext wac) 
        super(targetBeanName, wac);
    

    public void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain filterChain) throws ServletException, IOException 


        HttpServletRequest httpServletRequest;
        ThreadContext threadContext;

        if (request instanceof HttpServletRequest) 
            httpServletRequest = (HttpServletRequest) request;
            threadContext = ThreadContext.getInstance();

            try 
                EcasUser ecasUser = (EcasUser) httpServletRequest.getUserPrincipal();
                if (ecasUser != null) 
                    threadContext.setDomainUsername(ecasUser.getDomainUsername());
                
             catch (Exception e) 
                e.printStackTrace();
            
            threadContext.setUserID(httpServletRequest.getRemoteUser());
        

        System.out.println ("filterChain -> " + filterChain );  

        if (filterChain != null) 

            filterChain.doFilter(request, response);

        
    

有1个JSP有2种形式,如下: 当我提交第一个表单时一切都很好,但是当我提交第二个表单时,我有这个错误:

此错误(HTTP 403 Forbidden)表示 Internet Explorer 能够连接到该网站,但它无权查看该网页。 有关 HTTP 错误的详细信息,请参阅帮助。

<form name="buttonpanelform1" action="products.do" method="POST">

  <input type="hidden" name="_csrf" value="470bb7e4-1985-42c8-92fe-0b5edbfcd432"/>

    <table align="center" border="0" cellpadding="10" cellspacing="0" >
       <tbody>
<tr>
    <td align="left">
    <input type="submit" name="btn_addItem" value="btn_addItem">
    </td>
    <td align="right">
       <input type="submit" name="btn_saveAndContinue" value="btn_saveAndContinue">
    </td>
</tr>
</tbody>
</table>
</form>


<form name="addItemForm" class="special" action="products.do" method="POST" enctype="multipart/form-data" style="clear:both;">

                        <input type="hidden" name="_csrf" value="470bb7e4-1985-42c8-92fe-0b5edbfcd432"/>


<table align="center" border="0" cellpadding="10" cellspacing="0" >
<tbody>
<tr>
<td align="left"></td>
<td align="right">
   <input type="submit" name="btn_saveItem" value="btn_saveItem">
</td>
</tr>
</tbody>
</table>
</form>

【问题讨论】:

【参考方案1】:

您的第二种形式使用多部分编码,因此 spring 安全过滤器无法提取发布的 csrf 令牌。如果您的表单需要这种编码(它正在上传文件),您可以使用 spring 安全文档提供的 2 种可能的解决方案。

要么确保在请求到达 spring 安全过滤器链之前解析多部分数据,要么将 csrf 令牌作为请求参数发布到表单操作属性中。

有关详细信息,请参阅: http://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html#csrf-multipart

【讨论】:

以上是关于_csrf 令牌在同一个 JSP 中的 2 种形式(CSRF 保护)的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security CSRF 令牌不适用于 AJAX 调用和表单提交在同一个 JSP 中

在 spring-security 中更改 csrf 令牌

带有 CSRF 令牌和会话的 Symfony 4 功能形式测试

尽管以表单形式发送 CSRF 令牌,但不支持 Spring Security CSRF 405 方法 POST

具有多种形式的网页上的 CSRF 令牌?

反应形式 CSRF 安全