cors.adoc 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. [[cors]]
  2. = CORS
  3. Spring Framework provides https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-cors[first class support for CORS].
  4. CORS must be processed before Spring Security, because the pre-flight request does not contain any cookies (that is, the `JSESSIONID`).
  5. If the request does not contain any cookies and Spring Security is first, the request determines that the user is not authenticated (since there are no cookies in the request) and rejects it.
  6. The easiest way to ensure that CORS is handled first is to use the `CorsFilter`.
  7. Users can integrate the `CorsFilter` with Spring Security by providing a `CorsConfigurationSource`. Note that Spring Security will automatically configure CORS only if a `UrlBasedCorsConfigurationSource` instance is present.
  8. For example, the following will integrate CORS support within Spring Security:
  9. [tabs]
  10. ======
  11. Java::
  12. +
  13. [source,java,role="primary"]
  14. ----
  15. @Bean
  16. CorsConfigurationSource corsConfigurationSource() {
  17. CorsConfiguration configuration = new CorsConfiguration();
  18. configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
  19. configuration.setAllowedMethods(Arrays.asList("GET","POST"));
  20. UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
  21. source.registerCorsConfiguration("/**", configuration);
  22. return source;
  23. }
  24. ----
  25. Kotlin::
  26. +
  27. [source,kotlin,role="secondary"]
  28. ----
  29. @Bean
  30. fun corsConfigurationSource(): CorsConfigurationSource {
  31. val configuration = CorsConfiguration()
  32. configuration.allowedOrigins = listOf("https://example.com")
  33. configuration.allowedMethods = listOf("GET", "POST")
  34. val source = UrlBasedCorsConfigurationSource()
  35. source.registerCorsConfiguration("/**", configuration)
  36. return source
  37. }
  38. ----
  39. ======
  40. The following listing does the same thing in XML:
  41. [source,xml]
  42. ----
  43. <http>
  44. <cors configuration-source-ref="corsSource"/>
  45. ...
  46. </http>
  47. <b:bean id="corsSource" class="org.springframework.web.cors.UrlBasedCorsConfigurationSource">
  48. ...
  49. </b:bean>
  50. ----
  51. If you use Spring MVC's CORS support, you can omit specifying the `CorsConfigurationSource` and Spring Security uses the CORS configuration provided to Spring MVC:
  52. [tabs]
  53. ======
  54. Java::
  55. +
  56. [source,java,role="primary"]
  57. ----
  58. @Configuration
  59. @EnableWebSecurity
  60. public class WebSecurityConfig {
  61. @Bean
  62. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
  63. http
  64. // if Spring MVC is on classpath and no CorsConfigurationSource is provided,
  65. // Spring Security will use CORS configuration provided to Spring MVC
  66. .cors(withDefaults())
  67. ...
  68. return http.build();
  69. }
  70. }
  71. ----
  72. Kotlin::
  73. +
  74. [source,kotlin,role="secondary"]
  75. ----
  76. @Configuration
  77. @EnableWebSecurity
  78. open class WebSecurityConfig {
  79. @Bean
  80. open fun filterChain(http: HttpSecurity): SecurityFilterChain {
  81. http {
  82. // if Spring MVC is on classpath and no CorsConfigurationSource is provided,
  83. // Spring Security will use CORS configuration provided to Spring MVC
  84. cors { }
  85. // ...
  86. }
  87. return http.build()
  88. }
  89. }
  90. ----
  91. ======
  92. The following listing does the same thing in XML:
  93. [source,xml]
  94. ----
  95. <http>
  96. <!-- Default to Spring MVC's CORS configuration -->
  97. <cors />
  98. ...
  99. </http>
  100. ----
  101. If you have more than one `CorsConfigurationSource` bean, Spring Security won't automatically configure CORS support for you, that is because it cannot decide which one to use.
  102. If you want to specify different `CorsConfigurationSource` for each `SecurityFilterChain`, you can pass it directly into the `.cors()` DSL.
  103. [tabs]
  104. ======
  105. Java::
  106. +
  107. [source,java,role="primary"]
  108. ----
  109. @Configuration
  110. @EnableWebSecurity
  111. public class WebSecurityConfig {
  112. @Bean
  113. @Order(0)
  114. public SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception {
  115. http
  116. .securityMatcher("/api/**")
  117. .cors((cors) -> cors
  118. .configurationSource(apiConfigurationSource())
  119. )
  120. ...
  121. return http.build();
  122. }
  123. @Bean
  124. @Order(1)
  125. public SecurityFilterChain myOtherFilterChain(HttpSecurity http) throws Exception {
  126. http
  127. .cors((cors) -> cors
  128. .configurationSource(myWebsiteConfigurationSource())
  129. )
  130. ...
  131. return http.build();
  132. }
  133. CorsConfigurationSource apiConfigurationSource() {
  134. CorsConfiguration configuration = new CorsConfiguration();
  135. configuration.setAllowedOrigins(Arrays.asList("https://api.example.com"));
  136. configuration.setAllowedMethods(Arrays.asList("GET","POST"));
  137. UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
  138. source.registerCorsConfiguration("/**", configuration);
  139. return source;
  140. }
  141. CorsConfigurationSource myWebsiteConfigurationSource() {
  142. CorsConfiguration configuration = new CorsConfiguration();
  143. configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
  144. configuration.setAllowedMethods(Arrays.asList("GET","POST"));
  145. UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
  146. source.registerCorsConfiguration("/**", configuration);
  147. return source;
  148. }
  149. }
  150. ----
  151. Kotlin::
  152. +
  153. [source,kotlin,role="secondary"]
  154. ----
  155. @Bean
  156. fun corsConfigurationSource(): CorsConfigurationSource {
  157. val configuration = CorsConfiguration()
  158. configuration.allowedOrigins = listOf("https://example.com")
  159. configuration.allowedMethods = listOf("GET", "POST")
  160. val source = UrlBasedCorsConfigurationSource()
  161. source.registerCorsConfiguration("/**", configuration)
  162. return source
  163. }
  164. ----
  165. ======