1. 程式人生 > 其它 >使用spring-security-oauth2做前後端分離時vue axios 報錯‘No ‘Access-Control-Allow-Origin‘ header ‘ 的跨域問題

使用spring-security-oauth2做前後端分離時vue axios 報錯‘No ‘Access-Control-Allow-Origin‘ header ‘ 的跨域問題

技術標籤:vuevue

1.問題由來

以前只用spring-security做許可權認證,也遇到過跨域問題主要是在後端的繼承WebSecurityConfigurerAdapter 的類中配置下面的bean,然後前端vue配置代理來解決。

 /**
     *Security推薦的跨域配置
     */
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfigurationSource source =   new UrlBasedCorsConfigurationSource
(); CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.addAllowedOrigin("*"); //同源配置,*表示任何請求都視為同源,若需指定ip和埠可以改為如“localhost:8080”,多個以“,”分隔; corsConfiguration.addAllowedHeader("*");//header,允許哪些header,本案中使用的是token,此處可將*替換為token; corsConfiguration.
addAllowedMethod("*"); //允許的請求方法,PSOT、GET等 corsConfiguration.setAllowCredentials(true);//允許攜帶cookie ((UrlBasedCorsConfigurationSource) source).registerCorsConfiguration("/**",corsConfiguration); //配置允許跨域訪問的url return source; }

但是換成spring-security-oauth2後由於自己重寫了LoginAuthenticationFilter extends UsernamePasswordAuthenticationFilter 的登陸驗證導致跨域問題重現。而且這次我沒有使用cookie也導致了很多變化,大多數驗證資料都是用redis來實現的。

2.報錯資訊

 Access to XMLHttpRequest at 'http://localhost:81/' from origin 'http://localhost' has been blocked by CORS policy:
  Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Access to XMLHttpRequest at 'http://localhost:81/' from origin 'http://localhost' has been blocked by CORS policy: 
No 'Access-Control-Allow-Origin' header is present on the requested resource

3.解決配置

建立配置類

@Configuration
public class GlobalCorsConfig {

    /**
     * 允許跨域呼叫的過濾器
     */
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        //允許所有域名進行跨域呼叫
        config.addAllowedOrigin("*");
        //允許跨越發送cookie
        //config.setAllowCredentials(true);
        //放行全部原始頭資訊
        config.addAllowedHeader("*");
        //允許所有請求方法跨域呼叫
        config.addAllowedMethod("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);

    }

}

在資源認證伺服器或者WebSecurityConfigurerAdapter 的繼承類中配置
(因為使用的是spring-security-oauth2所以推薦在資源認證伺服器中ResourceServerConfigurerAdapter)
.antMatchers(HttpMethod.OPTIONS).permitAll()//跨域請求會先進行一次options請求

    @Override
    public void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http
                .addFilterBefore(loginAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                .and()
                .requestMatchers().anyRequest()
                .and()
                .anonymous()
                .and()
                .authorizeRequests()
                .antMatchers(
                        "/webjars/**",
                        "/swagger/**",
                        "/v2/api-docs",
                        "/doc.html",
                        "/swagger-ui.html",
                        "/swagger-resources/**",
                        "/open/**","/oauth/**").permitAll()
                .antMatchers(HttpMethod.OPTIONS).permitAll()//跨域請求會先進行一次options請求
                .and()
                .authorizeRequests()
                .antMatchers("/**").authenticated();//配置所有訪問控制,必須認證過後才可以訪問
        // @formatter:on
    }

效果
在這裡插入圖片描述

4.特別注意

(一) 當前端配置withCredentials=true時, 後端配置Access-Control-Allow-Origin不能為*, 必須是相應地址
(二) 當配置withCredentials=true時, 後端需配置Access-Control-Allow-Credentials
(三) 當前端配置請求頭時, 後端需要配置Access-Control-Allow-Headers為對應的請求頭集合

以前應為需要攜帶cookie所以配置了,但是因為現在不使用且會導致和後端配置衝突所以將其註釋
在這裡插入圖片描述