引用Spring Security 專案的跨域處理
阿新 • • 發佈:2019-02-20
最近專案採用了前後端分離的框架,前端和後臺介面沒有部署到一個站點,出現了跨域問題,什麼是跨域,這裡就不再贅述,直接說解決辦法。Spring 解決跨域的方式有很多,個人採用了Crosfilter的方式。具體程式碼如下:
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
final CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowCredentials(true);
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(urlBasedCorsConfigurationSource);
}
配置完成後,測試呼叫,報錯401,依然不行。網上查資料得知,跨域請求會進行兩次。具體流程見下圖:
每次跨域請求,真正請求到達後端之前,瀏覽器都會先發起一個preflight request,請求方式為OPTIONS 詢問服務端是否接受該跨域請求,具體引數如下圖:
但是該請求不能攜帶cookie和自己定義的header。
由於專案中引入了Spring security ,而我使用的token傳遞方式是在header中使用authorization 欄位,這樣依賴Spring Security攔截到 preflight request 發現它沒有攜帶token,就會報錯401,沒有授權。
解決這個問題很簡單,可以使用以下配置,讓Spring security 不校驗preflight request 。
@Override
public void configure(HttpSecurity http) throws Exception {
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry
= http.authorizeRequests();
registry.requestMatchers(CorsUtils::isPreFlightRequest).permitAll();//讓Spring security放行所有preflight request
}
再試就搞定了,但是後端直接配置支援跨域會導致兩次請求。還使用另一種方式,使用Nginx 轉發一下請求也可以。