踩坑日记:SpringSecurity中OPTIONS请求报403
前言
今天在完成一个接口开发时,发现前端发送的OPTIONS请求一直报403错误,花了2个小时的时间才找到问题的根源。泪目~~~
解决方案
问题其实很简单,springSecurity中,有两中跳过验证的方式,一种使用WebSecurity中的ignoring(),一种时用HttpSecurity中的permitAll()。两中方式虽然都能实现绕Security的过验,但方式却不一样,ignoring方式,会绕过security中所有的过滤器,即连过滤器都不进,也可以理解为不会与security有交集,而permitAll则是会进入security的过滤器,但是一路放行。
虽然效果类似,表面上都放行了,当时今天的坑就和它有关,如果将OPTIONS相关请求放到ignoring中,那么在security中配置cors将会失效,这时就会报403-跨域请求错误,此时有一种解决方式,就是在SpringMVC中配置跨域相关的配置,将跨域相关的验证交由springMVC来管理。但是我不想这么做。
此时就可以使用第二种方式,就将ignorig中OPTIONS相关的url放到httpSecurity中配置,即使用permitAll()进行放行。
代码示例
第一种解决方案(未采用,但能用):
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest().authenticated() .and() .csrf().disable() .cors().configurationSource(configurationSource()) .and() .formLogin().loginProcessingUrl("/admin/login").permitAll() .successHandler(new AdminAuthenticationSuccessHandler()) .failureHandler(new AdminAuthenticationFailureHandler()) .and() .sessionManagement() .maximumSessions(1) .expiredSessionStrategy(new AdminSessionInformationExpiredStrategy()); } @Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/subsystem/**"); } CorsConfigurationSource configurationSource(){ CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.setAllowCredentials(true); corsConfiguration.addAllowedOrigin("http://localhost:8080"); corsConfiguration.addAllowedHeader("*"); corsConfiguration.addAllowedMethod("*"); UrlBasedCorsConfigurationSource url = new UrlBasedCorsConfigurationSource(); url.registerCorsConfiguration("/**",corsConfiguration); return url; } // 在springMVC中配置cors @Bean public CorsFilter corsFilter(){ return new CorsFilter(configurationSource()); }
第二种解决方案
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() // 配置放行 .antMatchers("/subsystem/**").permitAll() .anyRequest().authenticated() .and() .csrf().disable() // 指定cors配置 .cors().configurationSource(configurationSource()) .and() .formLogin().loginProcessingUrl("/admin/login").permitAll() .successHandler(new AdminAuthenticationSuccessHandler()) .failureHandler(new AdminAuthenticationFailureHandler()) .and() // 开启session,并限制并发登录数为1(不允许同一用户多端登录) .sessionManagement() .maximumSessions(1) .expiredSessionStrategy(new AdminSessionInformationExpiredStrategy()); } // cors配置 CorsConfigurationSource configurationSource(){ CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.setAllowCredentials(true); corsConfiguration.addAllowedOrigin("http://localhost:8080"); corsConfiguration.addAllowedHeader("*"); corsConfiguration.addAllowedMethod("*"); UrlBasedCorsConfigurationSource url = new UrlBasedCorsConfigurationSource(); url.registerCorsConfiguration("/**",corsConfiguration); return url; }
总结:
该问题主要的是因为security中两个放行方式的不同导致的。建议在HttpSecurity中配置放行。
上一篇:
Java架构师技术进阶路线图
下一篇:
http和https的区别?(网络通讯)