問題場景:
Spring boot + Spring security 跨域鑑權失敗當我重寫 AuthenticationEntryPoint 的 commence 方法,
@Component
public class CustomAuthExceptionEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException arg2) throws IOException {
ResponseData res = new ResponseData();
res.setCode(REQ_FORBIDDEN);
res.setMsg("還未登錄,沒有權限訪問。");
res.setData("定義自己的數據");
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_OK);
final ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(response.getOutputStream(), res);
}
}
依然不能返回JSON,前端是報出跨域錯誤
Access to XMLHttpRequest at 'http://localhost:8081/user/detailInfo' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
其實已經配置好跨域
@Configuration
public class CorsConfig {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); // 1允許任何域名使用
corsConfiguration.addAllowedHeader("*"); // 2允許任何頭
corsConfiguration.addAllowedMethod("*"); // 3允許任何方法(post、get等)
corsConfiguration.setAllowCredentials(true);// 4使用相同的sessionid
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig()); // 4
return new CorsFilter(source);
}
}
思考:
首先回想跨域問題,其實我已經設置跨域的配置,並且對於OPTIONAL 請求,我已經在Spring security 中進行處理不去對它進行處理(這快也需要注意,是否進行了配置),此時我的CORS 配置還沒有生效,所以和 spring security 中使用的跨域需要設置新的變化,Spring Security 其實也是filter 鏈,那就牽扯到 順序的問題
解決方案:
@Configuration
public class CorsConfig {
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); // 1允許任何域名使用
corsConfiguration.addAllowedHeader("*"); // 2允許任何頭
corsConfiguration.addAllowedMethod("*"); // 3允許任何方法(post、get等)
corsConfiguration.setAllowCredentials(true);// 4使用相同的sessionid
source.registerCorsConfiguration("/**", corsConfiguration);
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new CorsFilter(source));
// 代表這個過濾器在衆多過濾器中級別最高,也就是過濾的時候最先執行
filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return filterRegistrationBean;
}
}