Spring Boot、Spring Security 和 Thymeleaf:将 CsrfFilter 应用到带有表单的网站
Posted
技术标签:
【中文标题】Spring Boot、Spring Security 和 Thymeleaf:将 CsrfFilter 应用到带有表单的网站【英文标题】:Spring Boot, Spring Security and Thymeleaf: Apply CsrfFilter to website with form 【发布时间】:2015-10-21 20:33:07 【问题描述】:我正在使用带有 Thymeleaf 的 Spring Security,并希望在同时使用 CSRF 保护的不同站点上创建登录和注册表单。与以下 WebSecurity 配置一样,保护登录站点很容易
@Override
protected void configure(final HttpSecurity http) throws Exception
http
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.requestMatchers()
.antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access")
.and()
.authorizeRequests()
.anyRequest()
.authenticated();
Spring 通常支持通过在 configure 方法中构建的 Security Filter Chain 添加 CSRF 保护。此过滤器链包含一个 CSRFFilter,用于添加/评估 CSRF 令牌。然后,此过滤器链将用于上述配置中定义的所有匹配项。获取应用于请求的过滤器的机制可以在方法中找到here
doFilterInternal(ServletRequest, ServletResponse, FilterChain)
问题是,如果我将“/register”站点添加到此配置中,用户首先会被重定向到“/login”站点。如果我不将其添加到上述配置中,则不会应用提到的 FilterChain(因此不会应用 CsrfFilter)。
所以我想要重用“/register”站点的过滤器链中的CsrfFilter,但我不知道该怎么做。
我更喜欢这种方法而不是其他想法,例如按照 here 或 here 的建议编写自定义 CSRF 过滤器。
【问题讨论】:
【参考方案1】:从所有这些我了解到问题是您希望人们无需先登录即可访问/注册。这是一个简单的修复:
@Override
protected void configure(final HttpSecurity http) throws Exception
http
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.requestMatchers()
// add this line
.antMatchers("/register").permitAll().and
//
.antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access")
.and()
.authorizeRequests()
.anyRequest()
.authenticated();
【讨论】:
嗨阿瑟尔!那不是问题。我的目标是在我的 /register 表单中启用 CSRF 保护。 Spring 支持通过在 configure 方法中构建的 Security Filter Chain 通常添加 CSRF 保护。此过滤器链包含一个 CSRFFilter,用于添加/评估 CSRF 令牌。如果我按照您建议的方式添加 /register 站点,过滤器链将忽略该站点,因此将不会使用 CSRF 保护。我在帖子中添加的链接建议了添加手动 CSRF 保护机制的方法,但我宁愿重用 Spring 现有的。 我一定是误会了。因此,您创建了一个自定义安全过滤器链而不是使用现有的安全过滤器链,从而导致问题?【参考方案2】:原来 Spring Security Filter 链适用于提供给 requestMatchers().antMatchers() 的列表中提到的所有端点。
所以要对不是登录站点的站点使用 CSRF 保护,我只需将其添加到此列表中,然后允许对其进行所有访问,因此不会重定向到登录页面。我的最终配置如下所示
@Override
protected void configure(final HttpSecurity http) throws Exception
http.requestMatchers()
// consider these patterns for this config and the Security Filter Chain
.antMatchers("/login", "/register", "/oauth/authorize", "/oauth/confirm_access", "/oauth/token_key",
"/oauth/check_token", "/oauth/error")
.and()
// define authorization behaviour
.authorizeRequests()
// /register is allowed by anyone
.antMatchers("/register").permitAll()
// /oauth/authorize needs authentication; enables redirect to /login
.antMatchers("/oauth/authorize").authenticated()
// any other request in the patterns above are forbidden
.anyRequest().denyAll()
.and()
.formLogin()
// we have a custom login page at /login
// that is permitted to everyone
.loginPage("/login").permitAll();
【讨论】:
以上是关于Spring Boot、Spring Security 和 Thymeleaf:将 CsrfFilter 应用到带有表单的网站的主要内容,如果未能解决你的问题,请参考以下文章
Grails Spring Core 安全插件 - 无法解析类