原因
springSecurity会对所有http请求以及所有静态资源进行拦截,一般情况下静态资源以及http请求则不需要进行拦截。
http.authorizeRequests()
.antMatchers("/api/**", "/css/**", "/js/**", "/fonts/**", "/images/**")
.permitAll()
.anyRequest()
.authenticated()
以上是基本配置,就是允许拦截通过。
但是springSecurity在2.0之后会默认自动开启CSRF跨站防护,而一旦开启了CSRF,所有经的http请求以及资源都被会CsrfFilter拦截,仅仅GET|HEAD|TRACE|OPTIONS这4类方法会被放行,也就是说post,delete等方法依旧是被拦截掉的,限制了除了get以外的大多数方法,报出403错误。
解决方案
查阅了一些帖子,最多的就是关闭CSRF或者重写过滤器。当然方法很多,毕竟跨域的作用也很大。所以就有ignoring方法的使用了。它是完全绕过spring security的所有filter的。罗列以下三种方式:
1.法一
直接配置configure(HttpSecurity http),直接关闭,这样的话都不会被拦截,所以还是不建议这样做
http.csrf().disable();
2.法二
通过配置方形的url,这样就不会拦截
http.csrf().ignoringAntMatchers("/druid/*");
3.法三
单独拿出来配置,与前两者不同,配置类中再次重写configure方法
@Override
public void configure(WebSecurity web){
web.ignoring().antMatchers("/api/**", "/css/**", "/js/**", "/fonts/**", "/images/**", "/lib/**","/ws/**");
}
完整配置展示
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyAuthenctiationSuccessHandler myAuthenctiationSuccessHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers().frameOptions().disable(); //用于加载页面iframe部分
http.authorizeRequests()
.antMatchers("/druid/**","/getVerify","/css/**", "/js/**", "/fonts/**")
.permitAll() // 允许所有用户访问
.anyRequest().authenticated()
.and()
.formLogin() // 定义当需要用户登录时候,转到的登录页面
.loginPage("/login")
.failureUrl("/login?error=true")
.defaultSuccessUrl("/index")//成功登录后跳转页面
.successHandler(myAuthenctiationSuccessHandler)
.permitAll()
.and()
.sessionManagement()
.invalidSessionUrl("/login")
.and()
.requestCache().disable()
.logout()
.logoutSuccessUrl("/login") //成功退出后跳转到的页面
.permitAll()//退出
.and()
.csrf()//.disable();
.ignoringAntMatchers("/pushLog/**","/druid/**");
}
@Override
public void configure(WebSecurity web){
web.ignoring().antMatchers("/swagger-ui.html","/doc.html", "/v2/**", "/webjars/**", "/swagger-resources/**");
}
@Bean
public AuthenticationProvider authenticationProvider() {
AuthenticationProvider provider = new MyAuthenticationProvider();
return provider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
}
}
总结
这样的方式也比较直接简单,本文也没有对源码进行阐述,以后会不上,也是因为正好遇到这个问题,写出来大家一起学习吧,对于接口的认证则需要自己在接口中进行验证了。