在使用Spring Security时发现,所有的get请求都可以正常访问,但是post请求一直提示403.最终发现SpringSecrity默认开启CSRF保护。
CSRF(Cross Site Request Forgery, 跨站域请求伪造)是一种网络的攻击方式。
可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账…造成的问题包括:个人隐私泄露以及财产安全。
方式1:禁用CSRF保护
这种比较暴力,如果禁用可能就违背了SpringSecrity的安全认证了。
@Configuration
@Order
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
//禁用csrf保护
http.csrf().disable();
http.authorizeRequests()
.antMatchers("/hello", "/hellopost").permitAll()
.anyRequest().authenticated()
.and().formLogin().and().httpBasic();
}
}
方式2:使用csrf忽略部分接口
@Configuration
@Order
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
//忽略hellopost接口
http.csrf().ignoringAntMatchers("/hellopost");
http.authorizeRequests()
.antMatchers("/hello", "/hellopost").permitAll()
.anyRequest().authenticated()
.and().formLogin().and().httpBasic();
}
}
方式3:重写CSRF保护策略
推荐用这种方式
import org.springframework.security.web.util.matcher.RequestMatcher;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
public class CsrfSecurityRequestMatcher implements RequestMatcher {
private Pattern allowedMethods = Pattern.compile("^(GET|HEAD|TRACE|OPTIONS)$");
@Override
public boolean matches(HttpServletRequest request) {
List<String> unExecludeUrls = new ArrayList<>();
//unExecludeUrls.add("/api/test");//(不允许post请求的url路径)此处根据自己的需求做相应的逻辑处理
if (unExecludeUrls != null && unExecludeUrls.size() > 0) {
String servletPath = request.getServletPath();
request.getParameter("");
for (String url : unExecludeUrls) {
if (servletPath.contains(url)) {
return true;
}
}
}
return allowedMethods.matcher(request.getMethod()).matches();
}
}