踩坑日记: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的区别?(网络通讯) 
			          
			        