Spring MVC Configuration Cors (resolve cross-domain requests)

Source: Internet
Author: User

1. Introduction to CORS

The homologous strategy (same origin policy) is the cornerstone of browser security. Under the same-Origin policy restrictions, AJAX requests cannot be sent between sites that are not homologous.

In order to solve this problem, a cross-source resource sharing, CORS (Cross-origin Resource sharing) is proposed.

CORS achieved two points:

    1. There are rules that do not break
    2. The server implements the CORS interface and can communicate across the source

Based on these two points, CORS divides the requests into two categories: simple and non-simple requests.

1.1 Simple Requests

You can start by looking at the pre-CORS scenario where you can trigger a GET request or send a POST request through a form through a script or an image tag across sources, but neither of these request HTTP header messages can contain any custom fields.

Simple request pairs should rule, so the definition of a simple request is:

The request method is HEAD , or is, GET POST and the HTTP header information does not exceed the following fields:,,,, Accept Accept-Language Content-Language Last-Event-ID Content-Type (only application/x-www-form-urlencoded ,, multipart/form-data text/plain ).

For example, there is a simple request:

*/*Accept-Encoding: gzip, deflate, sdch, brOrigin: http://www.examples.comHost: www.examples.com

For such a simple request, CORS's policy is to request, * * Add an Origin field in the header information * *, after the server receives the request, according to the field to determine whether to allow the request.

    1. If allowed, adds a field to the HTTP header information Access-Control-Allow-Origin and returns the correct result
    2. If not allowed, the field is not added to the header information Access-Control-Allow-Origin .

The browser first gets the results back to the user, depending on Access-Control-Allow-Origin whether or not the field is available to intercept the return result.

For some of the pre-cors services, cors affects them in two different situations:

    1. A script or image-triggered GET request does not contain the Origin header, so it is not restricted by CORS and is still available.
    2. In the case of an AJAX request, the HTTP header contains the Origin field, and because the server does not have any configuration, the returned result is not included Access-Control-Allow-Origin , so the returned result is blocked by the browser and the interface is still not accessible by Ajax across the source.

As you can see, the advent of CORS does not have any effect on the "old" service.

In addition, Access-Control-Allow-Origin there are several fields mentioned to describe the CORS return result:

    1. Access-control-allow-credentials: Optional, whether the user can send or process cookies.
    2. Access-control-expose-headers: Optional, allows the user to get the field. There are several fields that can be obtained whether set or not, including: Cache-control, Content-language, Content-type, Expires, Last-modified, Pragma.
1.2 Non-trivial requests

A request other than a simple request is a non-simple request.

For cross-origin requests for non-simple requests, * * The browser adds an OPTION request, called a preflight request, before the real request is issued. The preflight request adds the information for the real request, including the request method, the Custom header field, and the source information to the HTTP header information field, asking the server if it allows such an operation.

For example DELETE , for a request:

OPTIONS /test HTTP/1.1Origin: http://www.examples.comAccess-Control-Request-Method: DELETEAccess-Control-Request-Headers: X-Custom-HeaderHost: www.examples.com

The CORS-related fields are:

    1. Access-Control-Request-Method: The HTTP method used by the real request.
    2. Access-Control-Request-Headers: A custom header field contained in a real request.

When the server receives the request, it needs to verify the Origin, Access-control-request-method, and Access-control-request-headers separately, and after the validation is passed, the Http header information is added

Access-Control-Allow-Origin: http://www.examples.comAccess-Control-Allow-Methods: GET, POST, PUT, DELETEAccess-Control-Allow-Headers: X-Custom-HeaderAccess-Control-Allow-Credentials: trueAccess-Control-Max-Age: 1728000

Their meanings are:

    1. Access-control-allow-methods: Methods allowed for real requests
    2. Access-control-allow-headers: The fields that the server allows to use
    3. Access-control-allow-credentials: Whether to allow users to send, process cookies
    4. Access-control-max-age: The validity period of the preflight request, in seconds. The pre-check request is not repeated during the validity period

When the preflight request passes, the browser sends a real request to the server. This enables cross-origin requests.

Now that you've learned about Cors, let's build a simple spring MVC service and learn more about how spring MVC configures CORS.

2. Spring MVC Environment Setup

Open http://start.spring.io/, add Web Dependency, and select Generate Project, download the zip file and get a spring boot demo.

Unzip the zip file, double-click Pom.xml to open it or use idea, Eclipse to import the project according to Maven.

Depending on the Group, Artifact, Dependencies, the project directory structure may be slightly different, my project structure is as follows:

├── src│   ├── main/java│   |        └── net/xiayule/spring/cors│   |            └── SpringBootCorsTestApplication.java|   └── resources|       ├── static|       ├── templates|       └── application.properties|    └── pom.xml

The only thing we need to care about is Springbootcorstestapplication.java. Add the following code to Springbootcorstestapplication.java:

@RestController@SpringBootApplicationpublic class SpringBootCorsTestApplication {    @RequestMapping(value = "/test")    public String greetings() {        return "{\"project\":\"just a test\"}";    } public static void main(String[] args) { SpringApplication.run(SpringBootCorsTestApplication.class, args); }}

@RequestMapping(value = "/test")means that the method accepts requests from /test , and provides support for methods such as GET, POST, DELETE, and so on for HTTP.

To run the project, start the app at the root of the project mvn spring-boot:run and open the browser access to http://localhost:8080 see the effect:

The backend service is set up and then the front end is implemented. For simplicity, create a test.html file directly and add the following:

<! DOCTYPE html><Html><Head><title>hello cors</title><script src= "Https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" ></script> <script> $ (document). Ready (function () {  $.ajax ({ URL: "Http://localhost:8080/test",  method: "POST",  ContentType: "Application/json; Charset=utf-8 "}). Then (function (data, status, JQXHR) { alert (data) Span class= "Hljs-code" >});  </script></ Head><body></body></HTML>            

When the file is opened with a browser, a request to the message is triggered http://localhost:8080 . You can trigger different types of requests by modifying the method of the above code.

Because it is opened directly using the browser, * * The source of the Web page is null**, when the request to the source, http://localhost:8080 it becomes a cross-origin request, so if the backend is not CORS configuration, the returned HTTP header information will not be included Access-Control-Allow-Origin , so the browser will report the following error:

3. Configure CORS

An app may have multiple cors configurations, and each cors configuration can be set up for an interface or a series of interfaces or for all interfaces to take effect.

For example, we need:

    1. Let the/test interface support cross-source access, while other interfaces, such as/TEST/1 or/API, do not support cross-source access
    2. Let/test/* this type of interface support cross-source access, while other interfaces such as/API do not support cross-source access
    3. All interfaces of the site support cross-origin access

In the first case, if you want to configure CORS on an interface, you can add crossorigin annotations on the method:

@CrossOrigin(origins = {"http://localhost:9000", "null"})@RequestMapping(value = "/test", method = RequestMethod.GET)public String greetings() {    return "{\"project\":\"just a test\"}";}

In the second case, if you want to add a CORS configuration to a series of interfaces, you can add annotations on the class that declare all interfaces valid:

CrossOrigin(origins = {"http://localhost:9000", "null"})@RestController@SpringBootApplicationpublic class SpringBootCorsTestApplication {    // xxx}

In the third case, to add a global configuration, you need to add a configuration class:

@Configurationpublic class WebConfig extends WebMvcConfigurerAdapter {    @Override    public void addCorsMappings(CorsRegistry registry) {        registry.addMapping("/**")                .allowedOrigins("http://localhost:9000", "null") .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") .maxAge(3600) .allowCredentials(true); }}

In addition, you can configure CORS rules by adding a Filter, and manually specify which interfaces are valid.

@Beanpublic FilterRegistrationBean corsFilter() {    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();    CorsConfiguration config = new CorsConfiguration();    config.setAllowCredentials(true);config.addAllowedOrigin("http://localhost:9000");    config.addAllowedOrigin("null"); config.addAllowedHeader("*"); config.addAllowedMethod("*"); source.registerCorsConfiguration("/**", config); // CORS 配置对所有接口都有效 FilterRegistrationBean bean = newFilterRegistrationBean(new CorsFilter(source)); bean.setOrder(0); return bean;}
4. Implementation profiling

Regardless of the way you configure CORS, you are actually constructing corsconfiguration.
A CORS configuration CorsConfiguration is represented by a class, which is defined as follows:

public class CorsConfiguration {    private List<String> allowedOrigins;    private List<String> allowedMethods;    private List<String> allowedHeaders;    private List<String> exposedHeaders; private Boolean allowCredentials; private Long maxAge;}

The validation of CORS rules in Spring MVC is done by delegating to Defaultcorsprocessor.

The Defaultcorsprocessor processing process is as follows:

    1. The decision is based on whether the Header contains Origin. If it contains a cors request, go to 2; otherwise, the description is not a cors request and no processing is made.
    2. Determine if the Header of the response already contains access-control-allow-origin, if it contains, the proof has been processed, go to 3, otherwise no longer processed.
    3. Determine if it is homologous, and if so, transfer it to the class responsible for the request.
    4. If a CORS rule is configured, if it is not configured and is a preflight request, the request is rejected, and if it is not configured and is not a preflight request, it is given to the class that is responsible for the request. If configured, the request is verified.

The checksum is based on the configuration of the Corsconfiguration class:

    1. Determine if Origin is legal
    2. Determine if method is legal
    3. Determine if the header is legal
    4. If all is legal, the field of the response is added to the response header, and the class handling the request is given, and if it is not legal, the request is rejected.
5. Summary

This article describes the knowledge of cors and how to configure Cors in Spring MVC.

Spring MVC Configuration Cors (resolve cross-domain requests)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.