Spring @CrossOrigin annotation principle

Keywords: Programming Spring Attribute

In real development, we inevitably encounter cross domain problems. In the past, I only knew about the solution of jsonp. Later, I heard that spring can solve cross domain problems only by joining @ CrossOrigin. In the spirit of curiosity, I read the working principle of @ CrossOrigin and wrote this blog.

Let's start with the principle: actually, it's very simple to use spring's interceptor to add response header information such as access control allow origin to the response. We can see how spring is done

Note: the version of spring used here is 5.0.6

We can first make a breakpoint to the initCorsConfiguration method of RequestMappingHandlerMapping, and find that the method call is as follows

If the controller marks @ CrossOrigin on the class or @ CrossOrigin annotation on the method, spring will record the corresponding cross domain request mapping when recording the mapper mapping. The code is as follows

RequestMappingHandlerMapping
protected CorsConfiguration initCorsConfiguration(Object handler, Method method, RequestMappingInfo mappingInfo) {
		HandlerMethod handlerMethod = createHandlerMethod(handler, method);
		Class<?> beanType = handlerMethod.getBeanType();
        //Get CrossOrigin annotation on handler
		CrossOrigin typeAnnotation = AnnotatedElementUtils.findMergedAnnotation(beanType, CrossOrigin.class);
       //Get CrossOrigin annotation on handler method
		CrossOrigin methodAnnotation = AnnotatedElementUtils.findMergedAnnotation(method, CrossOrigin.class);
        
		if (typeAnnotation == null && methodAnnotation == null) {
            //If there is no CrossOrigin annotation on the class and method, a null is returned
			return null;
		}
        //Build a CorsConfiguration and return
		CorsConfiguration config = new CorsConfiguration();
		updateCorsConfig(config, typeAnnotation);
		updateCorsConfig(config, methodAnnotation);

		if (CollectionUtils.isEmpty(config.getAllowedMethods())) {
			for (RequestMethod allowedMethod : mappingInfo.getMethodsCondition().getMethods()) {
				config.addAllowedMethod(allowedMethod.name());
			}
		}
		return config.applyPermitDefaultValues();
	}

The result is returned to abstracthandlermethodmapping ා, and the main code is as follows

	CorsConfiguration corsConfig = initCorsConfiguration(handler, method, mapping);
				if (corsConfig != null) {
//The configuration of handlerMethod processing cross domain requests will be saved
					this.corsLookup.put(handlerMethod, corsConfig);
				}

When a cross domain request comes, spring will judge whether the request is a cross domain request when it gets the handler. If so, it will return a handler that can handle the cross domain

AbstractHandlerMapping#getHandler	
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
		//If it is a cross domain request
if (CorsUtils.isCorsRequest(request)) {
        //Get cross domain global configuration
			CorsConfiguration globalConfig = this.globalCorsConfigSource.getCorsConfiguration(request);
          //Get the cross domain configuration of handler
			CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
			CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig);
           //Processing cross domain (that is, adding access control allow origin information to the response header) and returning the corresponding handler object
			executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
		}

We can see how to determine whether a request is a cross domain request,

public static boolean isCorsRequest(HttpServletRequest request) {
//Determine whether the request header has Origin attribute
		return (request.getHeader(HttpHeaders.ORIGIN) != null);
	}

, it's time to go to bed, write again tomorrow

Posted by siri_suresh on Mon, 02 Dec 2019 04:40:03 -0800