SpringSecurity(七):Security跨域问题

来源:互联网 发布:url encode 加密 java 编辑:程序博客网 时间:2024/06/05 14:38

本来想继续写权限和oauth2.0和springsocial的,但是前段时间才换了个公司,比较忙,没时间写

这两天碰到跨域问题,按照原来的思路怎么都解决不鸟,网上百度了一些,也都没有成功。昨晚又回去看了下security流程,又理解了一下,搞定,故此记录下


1.不添加跨域设置



2.添加之前用的跨域设置

方法一。

/** * 跨域过滤器 * */@Componentpublic class CorsControllerFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// TODO Auto-generated method stub}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {System.out.println("我是之前的过滤器。。。");HttpServletResponse res = (HttpServletResponse) response;res.setContentType("text/html;charset=UTF-8");res.setHeader("Access-Control-Allow-Origin", "*");res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE ,PUT");res.setHeader("Access-Control-Max-Age", "30");res.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since,"+ " Pragma, Last-Modified, Cache-Control, Expires, Content-Type, "+ "X-E4M-With,userId,token,Authorization,deviceId,Access-Control-Allow-Origin,Access-Control-Allow-Headers,Access-Control-Allow-Methods");res.setHeader("Access-Control-Allow-Credentials", "true");res.setHeader("XDomainRequestAllowed", "1");chain.doFilter(request, response);}@Overridepublic void destroy() {// TODO Auto-generated method stub}}

  @Bean  public FilterRegistrationBean filterRegistrationBean() {      FilterRegistrationBean registrationBean = new FilterRegistrationBean();      CorsControllerFilter corsControllerFilter = new CorsControllerFilter();      registrationBean.setFilter(corsControllerFilter);      return registrationBean;  }


方法二。较方法一简单,但是依旧无法处理security框架内部跨域问题

/** * 跨域请求配置 *  * @author majie * */@Configurationpublic class CorsConfiguration {@Beanpublic WebMvcConfigurer corsConfigurer() {return new WebMvcConfigurerAdapter() {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("*").allowedMethods("GET","POST","PUT","DELETE","OPTIONS","HEAD");}};}}

但是认证成功以后成功处理器无法写出数据到前端。依旧报跨域。

添加注释调的两行就可以正确写回,说明开始的过滤器对security框架内部的处理没有起到作用。

response.setContentType("application/json;charset=UTF-8");//response.setHeader("Access-Control-Allow-Origin", "*");//response.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS, HEAD");response.getWriter().write(objectMapper.writeValueAsString(oAuth2AccessToken));


遇到这个问题的时候我开始是放开了上面被注释掉的两行,没问题,后来又出现了token过期,鉴权问题。

invalid token什么什么的,我debug看源码,是oauth2.0框架直接类似response.wtire("xxxx")出来的,和上面成功处理器类似。

开始的时候本来也打算抱着一颗类似上面的操作添加被注释掉的信息,但是源码太过复杂,看了下,放弃了重写的想法。

就百度找找有没有别的可行的办法。不过很可惜,网上的方法都试了,都不行。

晚上回家以后,我又看了遍security的执行流程,想着是不是内部重定向使得设置的过滤器没生效,所以想出了下面的办法(不对之处望指正)

/** * 跨域过滤器 * */@Componentpublic class CorsControllerFilter extends OncePerRequestFilter {@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)throws ServletException, IOException {System.out.println("我是可行的处理器");HttpServletResponse res = (HttpServletResponse) response;res.setContentType("text/html;charset=UTF-8");res.setHeader("Access-Control-Allow-Origin", "*");res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE ,PUT");res.setHeader("Access-Control-Max-Age", "30");res.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since,"+ " Pragma, Last-Modified, Cache-Control, Expires, Content-Type, "+ "X-E4M-With,userId,token,Authorization,deviceId,Access-Control-Allow-Origin,Access-Control-Allow-Headers,Access-Control-Allow-Methods");res.setHeader("Access-Control-Allow-Credentials", "true");res.setHeader("XDomainRequestAllowed", "1");chain.doFilter(request, response);}}


资源认证服务器里加:
http.addFilterBefore(corsControllerFilter, SecurityContextPersistenceFilter.class);
测试:


后台执行了一次(感觉这里很重要),而且页面报错。

resourceServer里面添加:

.requestMatchers(CorsUtils::isPreFlightRequest).permitAll()// 解决preflight跨域

再继续测试:


ok  正常返回。但是过滤器是执行了两次。


现在我们把上面的接口做成不需要security处理的接口,继续访问



后台过滤器执行一次,页面正常返回。


通过上述处理,成功解决跨域问题,故此记录。不正之处,望指正


原创粉丝点击