spring boot 集成 spring securty登陆时报 403

今天想把springsecurity集成到boot中,然后一个奇怪的错误就出现了,登陆地址老是出现403,搞了半天,找了各种问题,没想到只是需要关掉 csrf这个东西,如果你集成时出现登陆一直报403或者一直往登陆页面跳,那么你可能需要配置如下:

http.and().csrf().disable();

案例如下:

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
             .loginPage("/login.html")
             .loginProcessingUrl("/login")
             .and()
             .authorizeRequests()
             .antMatchers("/login.html", "/login", "/error")
             .permitAll()
             .anyRequest().authenticated()

             .and().csrf().disable();
    }

}

出现的原因:
spring security默认开启了csrf防护,也就是他会在他的拦截器链上加上
org.springframework.security.web.csrf.CsrfFilter 这个类,这个类中的
doFilterInternal 方法如下:

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
	//获取你当前请求(Session或Cookie)中的CsrfToken
	CsrfToken csrfToken = this.tokenRepository.loadToken(request);
	final boolean missingToken = csrfToken == null;
	//如果不存在就给你生成一个并保存到请求(Session或Cookie)中;
	if (missingToken) {
		csrfToken = this.tokenRepository.generateToken(request);
		this.tokenRepository.saveToken(csrfToken, request, response);
	}
	// 这里就是关键,这个匹配器,代码在如下:	
	//private final HashSet<String> allowedMethods = new HashSet<>(
	//			Arrays.asList("GET", "HEAD", "TRACE", "OPTIONS"));
	//public boolean matches(HttpServletRequest request) {
	//	return !this.allowedMethods.contains(request.getMethod());
	//}
	// 根据上面的代码我们可以看出来,请求的方法类型只包括GET,HEAD,TRACE,OPTION 
	//而没有Post,但是你得登陆拦截地址是Post的,所以会不走下面的代码,继续往下走
	if (!this.requireCsrfProtectionMatcher.matches(request)) {
		filterChain.doFilter(request, response);
		return;
	}
	// 他开始从请求头部取token了,如果没取到,那么他会去参数里面取
	String actualToken = request.getHeader(csrfToken.getHeaderName());
	if (actualToken == null) {
		actualToken = request.getParameter(csrfToken.getParameterName());
	}
	// 如果存到请求(Session或Cookie)中的csrfToken不是取出来的token,就会抛出对应的异常,
	//如果你不开启 logging.level.org.springframework.security.web.csrf.CsrfFilter = debug
	// 信息你都看不到,这个错误就会显得那么奇怪,
	if (!csrfToken.getToken().equals(actualToken)) {
		 
		if (missingToken) {
			this.accessDeniedHandler.handle(request, response, new MissingCsrfTokenException(actualToken));
		}else {
			this.accessDeniedHandler.handle(request, response, new InvalidCsrfTokenException(csrfToken, actualToken));
		}
		return;
	}

	filterChain.doFilter(request, response);
	}

 

解决办法也不止关闭 csrf,你还可以自定义这个匹配类,然后配置进来!

/**
 * 自定义跨站请求攻击匹配类
 * @author qiaolin
 * @version 2019/1/8
 **/
 @Component
public class MyRequestMatcher implements RequestMatcher {
    @Override
    public boolean matches(HttpServletRequest request) {
        // 自定义一些访问规则
        return false;
    }
}

//下面代码为配置类中(简写了),我们需要把自己的匹配规则类配置
@Autowired
private RequestMatcher requestMatcher;

protected void configure(HttpSecurity http) throws Exception {
	http.csrf().requireCsrfProtectionMatcher(requestMatcher);
}

如果你害怕 csrf 攻击,那么你可以看看spring secuirty的官方文档,
https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#csrf-include-csrf-token

文档上介绍了JSP怎么做,ajax的时候怎么做,但是看代码模式都是前后端不分离的!如果是前后端分离暂时还没想好怎么做!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值