2 changed files with 203 additions and 0 deletions
@ -0,0 +1,201 @@
@@ -0,0 +1,201 @@
|
||||
[[cors]] |
||||
= CORS Support |
||||
|
||||
== Introduction |
||||
|
||||
For security reasons, browsers prohibit AJAX calls to resources residing outside the |
||||
current origin. For example, as you're checking your bank account in one tab, you |
||||
could have the evil.com website in another tab. The scripts from evil.com should not |
||||
be able to make AJAX requests to your bank API (withdrawing money from your account!) |
||||
using your credentials. |
||||
|
||||
http://en.wikipedia.org/wiki/Cross-origin_resource_sharing[Cross-origin resource sharing] |
||||
(CORS) is a http://www.w3.org/TR/cors/[W3C specification] implemented by |
||||
http://caniuse.com/#feat=cors[most browsers] that allows you to specify in a flexible |
||||
way what kind of cross domain requests are authorized, instead of using some less secured |
||||
and less powerful hacks like IFrame or JSONP. |
||||
|
||||
As of Spring Framework 4.2, CORS is supported out of the box. CORS requests |
||||
(https://github.com/spring-projects/spring-framework/blob/master/spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java#L906[including preflight ones with an `OPTIONS` method]) |
||||
are automatically dispatched to the various `HandlerMapping` registered. They handle |
||||
CORS preflight requests and intercept CORS simple and actual requests thanks to a |
||||
http://docs.spring.io/spring/docs/4.2.x/javadoc-api/org/springframework/web/cors/CorsProcessor.html[CorsProcessor] |
||||
implementation (https://github.com/spring-projects/spring-framework/blob/master/spring-web/src/main/java/org/springframework/web/cors/DefaultCorsProcessor.java[DefaultCorsProcessor] |
||||
by default) in order to add the relevant CORS response headers (like `Access-Control-Allow-Origin`) |
||||
based on the CORS configuration you have provided. |
||||
|
||||
[NOTE] |
||||
==== |
||||
Since CORS requests are automatically dispatched, you *do not need* to change |
||||
`DispatcherServlet` `dispatchOptionsRequest` init parameter value, using its default value |
||||
(`false`) is the recommended approach. |
||||
==== |
||||
|
||||
== Controller method CORS configuration |
||||
|
||||
You can add to your `@RequestMapping` annotated handler method a |
||||
http://docs.spring.io/spring/docs/4.2.x/javadoc-api/org/springframework/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`] |
||||
annotation in order to enable CORS on it (by default `@CrossOrigin` allows all origins |
||||
and the HTTP methods specified in the `@RequestMapping` annotation): |
||||
|
||||
[source,java,indent=0] |
||||
[subs="verbatim,quotes"] |
||||
---- |
||||
@RestController |
||||
@RequestMapping("/account") |
||||
public class AccountController { |
||||
|
||||
@CrossOrigin |
||||
@RequestMapping("/{id}") |
||||
public Account retrieve(@PathVariable Long id) { |
||||
// ... |
||||
} |
||||
|
||||
@RequestMapping(method = RequestMethod.DELETE, value = "/{id}") |
||||
public void remove(@PathVariable Long id) { |
||||
// ... |
||||
} |
||||
} |
||||
---- |
||||
|
||||
It is also possible to enable CORS for the whole controller: |
||||
|
||||
[source,java,indent=0] |
||||
[subs="verbatim,quotes"] |
||||
---- |
||||
@CrossOrigin(origins = "http://domain2.com", maxAge = 3600) |
||||
@RestController |
||||
@RequestMapping("/account") |
||||
public class AccountController { |
||||
|
||||
@RequestMapping("/{id}") |
||||
public Account retrieve(@PathVariable Long id) { |
||||
// ... |
||||
} |
||||
|
||||
@RequestMapping(method = RequestMethod.DELETE, value = "/{id}") |
||||
public void remove(@PathVariable Long id) { |
||||
// ... |
||||
} |
||||
} |
||||
---- |
||||
|
||||
In this example CORS support is enabled for both `retrieve()` and `remove()` handler methods, and you can also see how you can customize the CORS configuration using `@CrossOrigin` attributes. |
||||
|
||||
You can even use both controller and method level CORS configurations, Spring will then combine both annotation attributes to create a merged CORS configuration. |
||||
|
||||
[source,java,indent=0] |
||||
[subs="verbatim,quotes"] |
||||
---- |
||||
@CrossOrigin(maxAge = 3600) |
||||
@RestController |
||||
@RequestMapping("/account") |
||||
public class AccountController { |
||||
|
||||
@CrossOrigin(origins = "http://domain2.com") |
||||
@RequestMapping("/{id}") |
||||
public Account retrieve(@PathVariable Long id) { |
||||
// ... |
||||
} |
||||
|
||||
@RequestMapping(method = RequestMethod.DELETE, value = "/{id}") |
||||
public void remove(@PathVariable Long id) { |
||||
// ... |
||||
} |
||||
} |
||||
---- |
||||
|
||||
== Global CORS configuration |
||||
|
||||
In addition to fine-grained, annotation-based configuration you'll probably want to |
||||
define some global CORS configuration as well. This is similar to using filters but can |
||||
be declared withing Spring MVC and combined with fine-grained `@CrossOrigin` configuration. |
||||
By default all origins and `GET`, `HEAD` and `POST` methods are allowed. |
||||
|
||||
=== JavaConfig |
||||
|
||||
Enabling CORS for the whole application is as simple as: |
||||
|
||||
[source,java,indent=0] |
||||
[subs="verbatim,quotes"] |
||||
---- |
||||
@Configuration |
||||
@EnableWebMvc |
||||
public class WebConfig extends WebMvcConfigurerAdapter { |
||||
|
||||
@Override |
||||
public void addCorsMappings(CorsRegistry registry) { |
||||
registry.addMapping("/**"); |
||||
} |
||||
} |
||||
---- |
||||
|
||||
You can easily change any properties, as well as only apply this CORS configuration to a |
||||
specific path pattern: |
||||
|
||||
[source,java,indent=0] |
||||
[subs="verbatim,quotes"] |
||||
---- |
||||
@Configuration |
||||
@EnableWebMvc |
||||
public class WebConfig extends WebMvcConfigurerAdapter { |
||||
|
||||
@Override |
||||
public void addCorsMappings(CorsRegistry registry) { |
||||
registry.addMapping("/api/**") |
||||
.allowedOrigins("http://domain2.com") |
||||
.allowedMethods("PUT", "DELETE") |
||||
.allowedHeaders("header1", "header2", "header3") |
||||
.exposedHeaders("header1", "header2") |
||||
.allowCredentials(false).maxAge(3600); |
||||
} |
||||
} |
||||
---- |
||||
|
||||
=== XML namespace |
||||
|
||||
This minimal XML configuration enable CORS on `/**` path pattern with the same default properties than the JavaConfig one: |
||||
|
||||
[source,xml,indent=0] |
||||
[subs="verbatim"] |
||||
---- |
||||
<mvc:cors> |
||||
<mvc:mapping path="/**" /> |
||||
</mvc:cors> |
||||
---- |
||||
|
||||
It is also possible to declare several CORS mappings with customized properties: |
||||
|
||||
[source,xml,indent=0] |
||||
[subs="verbatim"] |
||||
---- |
||||
<mvc:cors> |
||||
|
||||
<mvc:mapping path="/api/**" |
||||
allowed-origins="http://domain1.com, http://domain2.com" |
||||
allowed-methods="GET, PUT" |
||||
allowed-headers="header1, header2, header3" |
||||
exposed-headers="header1, header2" allow-credentials="false" |
||||
max-age="123" /> |
||||
|
||||
<mvc:mapping path="/resources/**" |
||||
allowed-origins="http://domain1.com" /> |
||||
|
||||
</mvc:cors> |
||||
---- |
||||
|
||||
== Advanced Customizations |
||||
|
||||
http://docs.spring.io/spring/docs/4.2.x/javadoc-api/org/springframework/web/cors/CorsConfiguration.html[CorsConfiguration] |
||||
allows you to specify how the CORS requests should be processed: allowed origins, headers, methods, etc. |
||||
It can be provided in various ways: |
||||
|
||||
* http://docs.spring.io/spring/docs/4.2.x/javadoc-api/org/springframework/web/servlet/handler/AbstractHandlerMapping.html#setCorsConfiguration-java.util.Map-[`AbstractHandlerMapping#setCorsConfiguration()`] |
||||
allows to specify a `Map` with several http://docs.spring.io/spring/docs/4.2.x/javadoc-api/org/springframework/web/cors/CorsConfiguration.html[CorsConfiguration] |
||||
mapped on path patterns like `/api/**` |
||||
* Subclasses can provide their own `CorsConfiguration` by overriding |
||||
`AbstractHandlerMapping#getCorsConfiguration(Object, HttpServletRequest)` method |
||||
* Handlers can implement http://docs.spring.io/spring/docs/4.2.x/javadoc-api/org/springframework/web/cors/CorsConfigurationSource.html[`CorsConfigurationSource`] |
||||
interface (like https://github.com/spring-projects/spring-framework/blob/master/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java[`ResourceHttpRequestHandler`] |
||||
now does) in order to provide a http://docs.spring.io/spring/docs/4.2.x/javadoc-api/org/springframework/web/cors/CorsConfiguration.html[CorsConfiguration] |
||||
for each request. |
||||
Loading…
Reference in new issue