问题描述
我正在使用Spring Security 5.0.13,我想为登录页面激活csrf保护。我使用的是xml配置,我将其更改为
<http>
...
<csrf disabled="true"/>
</http>
到
<bean id="csrfMatcher" class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<constructor-arg name="pattern" value="/j_spring_security_check"/>
<constructor-arg name="httpMethod" value="POST"/>
</bean>
<csrf request-matcher-ref="csrfMatcher" />
然而,j_spring_security_logout
端点现在期望一个POST
请求,而它过去接受一个GET
请求。我知道最好有一个POST
请求注销按钮,但是我不能破坏此功能,因为它已在我的控制范围之外的其他地方使用。
如何在不影响注销url动词的情况下为登录页面激活csrf保护?
解决方法
CSRF保护要求您为所有引起更改的请求发送包含CRSF属性值的隐藏输入。这就是保护您的原因-该CSRF属性是由服务器生成的,因此无法通过从网站以外的其他位置发送请求来伪造。
您只能在带有post
请求的表单内发送隐藏的输入,因此,如果要使用csrf,则需要使用post
。好消息是-这很容易,大多数模板引擎都会自动为您设置所有内容。
使用Thymeleaf,您甚至不需要更改任何内容,它就会在您的帖子请求中自动生成此属性。
使用小胡子,您需要添加以下属性:
spring.mustache.expose-request-attributes=true
然后使用以下格式:
<form id="logoutForm" method="POST" action="/logout">
<input type="hidden" name="_csrf" value="{{_csrf.token}}"/>
<button type=submit>Logout</button>
</form>
如您所见,这确实相对容易,但是您必须将隐藏的crsf.token值添加到每个帖子请求,实现(取决于模板引擎),就像我对thymeleaf所说的那样,您不必担心它。
,根据Spring Security reference docs,您可以修改Spring Security与/logout
端点的匹配方式。默认情况下,它查找POST /logout
,但是您可以将其配置为查找GET /logout
:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) {
http
// ... other configs
.logout(logout -> logout
.logoutRequestMatcher(new AntPathRequestMatcher("/logout","GET"))
);
}
}
尽管可以声明自己的LogoutFilter
和register it类型的<logout>
,但<bean>
元素没有直接的XML等效项。或选择logging a ticket将其添加到<logout>
。