Spring Cloud project front end separation cross domain operation

  • 2021-10-11 18:50:51
  • OfStack

Cross-domain problems, in fact, Baidu has a pile of solutions

In view of the ordinary situation, Baidu's above schemes are feasible.

I will mainly introduce two situations here.

Of course, my configuration here is based on gateway, not service.

1. Permission verification has not been increased.

2. Added the permission verification of spring security (I am based on keyCloak here) and added Authorization

First of all, we introduce the solution of the first case, which is very simple and can be solved only by configuring filters in the startup class.


@Bean
    public CorsFilter corsFilter() {
        //1. Add CORS Configuration information 
        CorsConfiguration config = new CorsConfiguration();
          // Which original domains are released 
          config.addAllowedOrigin("*");
          // Whether to send Cookie Information 
          config.setAllowCredentials(true);
          // Which original domains are released ( Request mode )
          config.addAllowedMethod("*");
          // Which original domains are released ( Header information )
          config.addAllowedHeader("*");
          // What header information is exposed (because cross-domain access cannot get all header information by default) 
          config.addExposedHeader("*");
 
        //2. Add mapping path 
        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);
 
        //3. Returns the new CorsFilter.
        return new CorsFilter(configSource);
    }

I encounter the situation is the second kind, this kind of situation the above way basically does not work, I use here is keyCloak to do the authority verification.

First, add the filter configuration:


@Component
public class CorsControllerFilter implements Filter{
	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}
 
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		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", "3600");
		res.setHeader("Access-Control-Allow-Headers", "*");
		res.setHeader("Access-Control-Allow-Credentials", "true");
		res.setHeader("XDomainRequestAllowed", "1");
		chain.doFilter(request, response);
	}
 
	@Override
	public void init(FilterConfig arg0) throws ServletException {
		// TODO Auto-generated method stub	
	}
}

Add configuration to startup class


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

However, for some requests, he will first request the OPTIONS request, causing permission verification to fail. So add interceptor configuration, to all OPTIONS requests directly release, return to the status of 200.


public class OptionsInterceptor implements HandlerInterceptor {
 
	@Override
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		// TODO Auto-generated method stub
	}
 
	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		// TODO Auto-generated method stub
	}
 
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		// TODO Auto-generated method stub
        if(request.getMethod().equals("OPTIONS")){
            response.setStatus(HttpServletResponse.SC_OK);
            return false;
        }
        return true;
	}
}

Configure the web configuration file and load the interceptor.


@Configuration
public class WebMvcConfiguration extends WebMvcConfigurationSupport{
 @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new OptionsInterceptor()).addPathPatterns("/**");
 }
}

Originally thought this configuration should be OK, but at the time of request, the request of OPTIONS actually reported the cross-domain problem, and added interceptor allowed cross-domain configuration


public class CrossInterceptor implements HandlerInterceptor{
 @Override
 public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
   throws Exception {
  // TODO Auto-generated method stub
 }
 
 @Override
 public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
   throws Exception {
  // TODO Auto-generated method stub
 }
 
 @Override
 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  // TODO Auto-generated method stub
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT, HEAD");
        response.setHeader("Access-Control-Allow-Headers", "*");
        response.setHeader("Access-Control-Max-Age", "3600");
        return true;
 }
}

Add configuration in WebMvcConfiguration, note to write in front of OptionsInterceptor


registry.addInterceptor(new CrossInterceptor()).addPathPatterns("/**");

Continue testing and cross-domain problem solving. In fact, I am not sure about the principle. Welcome to communicate.


Related articles: