如何在不使用 @EnableWebMvcSecurity 的情况下在 spring security / thymeleaf 中自动生成 csrf 令牌

Posted

技术标签:

【中文标题】如何在不使用 @EnableWebMvcSecurity 的情况下在 spring security / thymeleaf 中自动生成 csrf 令牌【英文标题】:How to automatically generate csrf tokens in spring security / thymeleaf without using @EnableWebMvcSecurity 【发布时间】:2015-10-13 00:49:32 【问题描述】:

我一直试图弄清楚为什么隐藏的 csrf 字段没有自动添加到我的登录表单中。 我将 Spring 4.1.1 与 Spring Security 4.0.1 和 Thymeleaf 2.1.4 一起使用。

我能找到解决问题的方法是使用 thymeleaf 中的 _csrf 变量手动添加字段(尽管 _csrf 对我来说为空),或者在 Java 配置中使用 @EnableWebMvcSecurity。 但是,我使用 xml 来配置安全性并希望保持这种方式。 这一切归结为:我可以在安全 xml 中添加什么以使 thymeleaf 生成 csrf 令牌字段?

我目前的配置是:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:security="http://www.springframework.org/schema/security"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">

    <!-- **************************************************************** -->
    <!--  RESOURCE FOLDERS CONFIGURATION                                  -->
    <!--  Dispatcher configuration for serving static resources           -->
    <!-- **************************************************************** -->
    <mvc:resources mapping="/dist/**" location="file:/var/www/meubelplan/dist/"/>
    <mvc:resources mapping="/css/**" location="file:/var/www/meubelplan/css/"/>
    <mvc:resources mapping="/js/**" location="file:/var/www/meubelplan/js/"/>
    <mvc:resources mapping="/images/**" location="file:/var/www/meubelplan/images/"/>

    <!-- **************************************************************** -->
    <!--  SPRING ANNOTATION PROCESSING                                    -->
    <!-- **************************************************************** -->
    <mvc:annotation-driven/>
    <context:component-scan base-package="com.wwk.meubelplan"/>

    <!-- **************************************************************** -->
    <!--  SPRING SECURITY                                                 -->
    <!-- **************************************************************** -->

    <security:authentication-manager>
        <security:authentication-provider>
            <security:user-service>
                <security:user name="sem" password="rtyfghvbn" authorities="ROLE_USER" />
                <security:user name="winnie" password="ikbenwinnie" authorities="ROLE_USER" />
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>

    <security:http pattern="/account/login" security="none"/>
    <security:http pattern="/account/logout" security="none"/>
    <security:http pattern="/account/create" security="none"/>
    <security:http use-expressions="false">
        <security:csrf/>
        <security:intercept-url pattern='/account/**' access='ROLE_USER' />
        <security:form-login login-page='/account/login' default-target-url='/account' always-use-default-target='true'/>
        <security:logout logout-url="/account/logout" delete-cookies="JSESSIONID" logout-success-url="/account/login"/>
    </security:http>

    <!-- **************************************************************** -->
    <!--  THYMELEAF-SPECIFIC ARTIFACTS                                    -->
    <!--  TemplateResolver <- TemplateEngine <- ViewResolver              -->
    <!-- **************************************************************** -->

    <bean id="templateResolver"
          class="org.thymeleaf.templateresolver.FileTemplateResolver">
        <property name="prefix" value="/var/www/meubelplan/" />
        <property name="suffix" value=".html" />
        <property name="templateMode" value="HTML5" />
        <property name="characterEncoding" value="UTF-8" />
        <property name="cacheable" value="false"/>
    </bean>

    <bean id="templateEngine"
          class="org.thymeleaf.spring4.SpringTemplateEngine">
        <property name="templateResolver" ref="templateResolver" />
    </bean>

    <bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
        <property name="templateEngine" ref="templateEngine" />
        <property name="characterEncoding" value="UTF-8" />
    </bean>

</beans>

我的表单百里香模板是:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head th:include="partials/general/head"></head>
<body>

    <div class="container">

        <nav th:replace="partials/general/navbar"></nav>

        <div th:replace="partials/general/logobar"></div>

        <div class="row">
            <div class="col-md-6 col-md-offset-3">

                <br/><br/>

                <div class="panel panel-default">
                    <div class="panel-heading">Login om uw account gegevens te bekijken</div>
                    <div class="panel-body">
                        <form name="loginForm" method="POST" th:action="@'~/account'">
                            <div class="form-group">
                                <label for="username">Email address</label>
                                <input type="text" class="form-control" id="username" name="username" placeholder="Gebruikersnaam"/>
                            </div>
                            <div class="form-group">
                                <label for="password">Password</label>
                                <input type="password" class="form-control" id="password" name="password" placeholder="Password"/>
                            </div>
                            <button type="submit" class="btn btn-default" value="Submit">Inloggen</button>
                        </form>
                    </div>
                </div>

            </div>
        </div>

    </div><!-- /.container -->

    <span th:replace="partials/general/scripts"></span>

</body>
</html>

在此先感谢您提供正确方向的任何指示:)

问候,

Sem

【问题讨论】:

你能尝试声明一个org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor类型的bean吗? 感谢您的评论,虽然这最初没有奏效,但它确实将我推向了正确的方向。经过一番搜索,我遇到了这个问题:***.com/questions/21757222/… 虽然模板引擎不同,但问题是一样的,我得到了它与该问题的解决方案一起工作。 @semvdwal 能否请您分享解决方案。我一直在努力让它发挥作用。提前致谢 @RachitAgrawal 我前段时间回答了我的问题,请参阅此问题的第二个答案,我现在也标记了它,以便您轻松查看它是哪一个。但是,您的情况可能会有所不同,因此如果提供的解决方案没有帮助,请随时向我提供一些详细信息,以便我可以帮助您解决(希望如此)。问候 【参考方案1】:

如果它没有自动插入 CSRF 令牌,您可以通过以下行强制它:

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

【讨论】:

感谢您的回答,但是,我希望 thymeleaf 自动生成该字段。 Thymeleaf 按原样自动生成参数。能否检查一下你生成的html页面源代码,确认是否有隐藏输入【参考方案2】:

我在另一个问题中找到了我需要的信息: spring security 3.2.0 csrf token not working in freemarker template

答案是这样的:

将以下 xml 添加到您的 xml 配置中将使 thymeleaf 能够自动将 csrf 令牌输入添加到您的表单中。

安全性.xml

<bean id="requestDataValueProcessor" class="org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor"/>

<bean id="csrfFilter" class="org.springframework.security.web.csrf.CsrfFilter">
    <constructor-arg>
        <bean class="org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository">
            <property name="headerName" value="X-SECURITY" />
        </bean>
    </constructor-arg>
</bean>

web.xml

<filter>
    <filter-name>csrfFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <async-supported>true</async-supported>
  </filter>

<filter-mapping>
    <filter-name>csrfFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

【讨论】:

以上是关于如何在不使用 @EnableWebMvcSecurity 的情况下在 spring security / thymeleaf 中自动生成 csrf 令牌的主要内容,如果未能解决你的问题,请参考以下文章

如何在不更改链接结构的情况下使用 \ 转义字符 (、)、[、]、*、_、:[]()

如何在不使用 sleep() 的情况下使用 ontimer 函数延迟进程?

如何在不安装的情况下使用数据库?

如何在不使用 Flexbox 的情况下水平对齐元素?

如何在不使用 DESCRIBE 子句的情况下描述 ORACLE 包?

如何在不使用滤镜的情况下使图像变暗? [复制]