如何在不使用 @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 函数延迟进程?