SpringBoot cross domain and three solutions

Posted by Elemen7s on Mon, 03 Jan 2022 04:21:56 +0100

Let's first understand the definition of [domain]: Protocol + domain name + port. If the three are exactly the same, they are the same domain. Otherwise, there is one difference. They are all different domains. So, what is A cross domain request? The domain and port of the current [originating request] When the domain to which the [request refers] belongs belongs to different domains, the request is called A cross domain request. In short, application A can only access the data from the background of application A, and application B can only access the data from the background of application B. If one of the protocols, ports and domain names in the URL address when application A uses Ajax to obtain data corresponds to application B, application A wants to obtain application B data across domains , is not allowed. Before talking about cross domain, let's take A look at the browser's homology strategy.

01

Several cases of cross domain

  • Allow communication under the same domain name (no port protocol specified)
  • Communication is allowed in different folders under the same domain name
  • Communication is not allowed on different ports of the same domain name
  • Different protocols of the same domain name do not allow communication
  • The domain name and the IP corresponding to the domain name do not allow communication
  • The primary domain name is the same, but the subdomain name is different. Communication is not allowed
  • Communication is not allowed for the same domain name and different secondary domain names
  • Communication is not allowed for different domain names

01

Cross domain examples are as follows:

Method 1: global configuration

Define the Configuration class, add the @ Configuration annotation, implement the WebMvcConfigurer interface, and then rewrite the addcorsmapping method:

// Request cross domain
@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        //Add mapping path
        registry.addMapping("/**")
                //Send Cookie
                .allowCredentials(true)
                //Set which original domains are released, springboot2 4.4 use the lower version allowedOrigins("*")    
                .allowedOriginPatterns("*")
                //Which request methods are released
                .allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"})
                //. allowedMethods("*") / / or release all
                //Which original request header information is released
                .allowedHeaders("*")
                //What original request header information is exposed
                .exposedHeaders("*");
    }
}

Method 2: local cross domain

The Controller layer can add @ CrossOrigin annotation to the class or method that needs to cross domain.

@CrossOrigin(origins = "*",maxAge = 3600)
public class UserController {
 final UserService userService;
 
 @GetMapping("/getOne/{id}")
 public User getOne(@PathVariable("id") Integer id) {
  return userService.getById(id);
 }

We can also set smaller granularity and set cross domain on the method:

@Controller
@RequestMapping("/shop")
public class ShopController {

    @GetMapping("/")
    @ResponseBody
    //Smaller solution cross domain settings can only be accessed at certain addresses
    @CrossOrigin(originPatterns = "http://localhost:8080")
    public Map<String, Object> findAll() {
        //Return data
        return DataSchool.getStudents();
    }
}

Method 3: define cross domain filters

1) Write filter

// Cross domain filter
@Component
public class CORSFilter implements Filter {
 
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  //*The number indicates that cross domain access is allowed for all requests
        HttpServletResponse res = (HttpServletResponse) response;
        res.addHeader("Access-Control-Allow-Credentials", "true");
        res.addHeader("Access-Control-Allow-Origin", "*");
        res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
        res.addHeader("Access-Control-Allow-Headers", "Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN");
        if (((HttpServletRequest) request).getMethod().equals("OPTIONS")) {
            response.getWriter().println("Success");
            return;
        }
        chain.doFilter(request, response);
    }
 
    @Override
    public void destroy() {
 
    }
 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
 
    }
}

2) Register filter

@Configuration
public class CorsConfig {
 
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsFilter(urlBasedCorsConfigurationSource);
    }
 
}

03

Summary

Network security involves a very wide range. Cross domain is only one of "browser security", which is often encountered during development. I hope you will pay more attention.