问题场景:
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;
}
}