CSRF 防御实战主流的框架一般都包含了CSRF的拦截 。
非框架型 - 自定义XXXCsrfFilter可以通过自定义xxxCsrfFilter去拦截实现,这里建议你参考 Spring Security - org.springframework.security.web.csrf.CsrfFilter.java 。
Spring Security - 什么时候禁用CSRF你开发的应用在何时,会考虑禁用CSRF呢? 这时候需要考虑CSRF本质是盗用cookie, 无cookie方案就可以禁用 。
- 如果你只是创建一个非浏览器客户端使用的服务,你可能会想要禁用CSRF保护
@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.csrf().disable();// 默认是启用的,需要禁用CSRF保护}}
Spring Security - CookieCsrfTokenRepository.withHttpOnlyFalse()存Cookie,比如前后端分离方案:Spring Security CookieCsrfTokenRepository + 前端路由统一设置Spring Security依赖包
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>
Spring Security - CookieCsrfTokenRepository.withHttpOnlyFalse()@Overrideprotected void configure(HttpSecurity http) throws Exception {// 本例子给个范例而已,对于xxx的部分,自己根据业务定义http.authorizeRequests()/* allow */.antMatchers("/plugins/**", "/api-docs/**") .permitAll().antMatchers("/login", "/logout").permitAll()/* auth control */.antMatchers("/xxx/user", "/xxx/user/**").access("hasAuthority('xxx:user')").antMatchers("/xxx/role", "/xxx/role/**").access("hasAuthority('xxx:role')")/* others */.anyRequest().authenticated()/* other Filters */.and().addFilterBefore(xxxFilter(), UsernamePasswordAuthenticationFilter.class)/* iframe */.headers().frameOptions().sameOrigin()/* form login & logout */.and().formLogin().loginPage("/login").usernameParameter("username").passwordParameter("password").defaultSuccessUrl("/admin/", true).and().rememberMe().rememberMeParameter("remember").rememberMeCookieName("remember").and().logout().deleteCookies("JSESSIONID").invalidateHttpSession(true).logoutSuccessHandler(new XXXLogoutSuccessHandler(localeResolver())).logoutRequestMatcher(new AntPathRequestMatcher("/logout")).permitAll()/* csrf */.and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());//.and().cors()}
后端thymeleaf登录页面"/login":<!DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org"><head><meta charset="UTF-8"><title>登录页面</title></head><body><form id="form" method="post"><label>用户名:</label><input name="username" type="text" value=https://www.isolves.com/it/aq/wl/2020-01-08/"" />