CORS dengan Spring

1. Gambaran keseluruhan

Di mana-mana penyemak imbas moden, Cross-Origin Resource Sharing (CORS) adalah spesifikasi yang relevan dengan munculnya klien HTML5 dan JS yang menggunakan data melalui REST API.

Dalam banyak kes, host yang melayani JS (misalnya, example.com ) berbeza dengan host yang menyajikan data (misalnya, api.example.com ). Dalam kes sedemikian, CORS memungkinkan komunikasi antara domain.

Spring memberikan sokongan kelas pertama untuk CORS, yang menawarkan cara yang mudah dan kuat untuk mengkonfigurasinya di mana-mana aplikasi web Spring atau Spring Boot.

2. Kaedah Pengawal Konfigurasi CORS

Mendayakan CORS sangat mudah - tambah sahaja anotasi @CrossOrigin .

Kami mungkin melaksanakannya dengan beberapa cara yang berbeza.

2.1. @CrossOrigin on Kaedah @ RequestMapping- Annotated Handler

@RestController @RequestMapping("/account") public class AccountController { @CrossOrigin @RequestMapping(method = RequestMethod.GET, path = "/{id}") public Account retrieve(@PathVariable Long id) { // ... } @RequestMapping(method = RequestMethod.DELETE, path = "/{id}") public void remove(@PathVariable Long id) { // ... } }

Dalam contoh di atas, kami hanya mengaktifkan CORS untuk kaedah pengambilan () . Kami dapat melihat bahawa kami tidak menetapkan konfigurasi apa pun untuk anotasi @CrossOrigin , jadi ia menggunakan default

  • Semua asal dibenarkan
  • Kaedah HTTP yang dibenarkan adalah kaedah yang dinyatakan dalam anotasi @RequestMapping (untuk contoh ini adalah GET)
  • Masa tindak balas awalan di- cache ( maxAge) adalah 30 minit

2.2. @CrossOrigin pada Pengawal

@CrossOrigin(origins = "//example.com", maxAge = 3600) @RestController @RequestMapping("/account") public class AccountController { @RequestMapping(method = RequestMethod.GET, path = "/{id}") public Account retrieve(@PathVariable Long id) { // ... } @RequestMapping(method = RequestMethod.DELETE, path = "/{id}") public void remove(@PathVariable Long id) { // ... } }

Kali ini, kami menambah @CrossOrigin di peringkat kelas. Akibatnya, kedua-dua kaedah pengambilan () dan penghapusan () diaktifkan. Kita dapat menyesuaikan konfigurasi dengan menentukan nilai salah satu atribut anotasi: asal , kaedah , pembolehkan dibolehkan , Pemimpin terdedah , allowCredentials, atau maxAge.

2.3. @CrossOrigin on Kaedah Pengawal dan Pengendali

@CrossOrigin(maxAge = 3600) @RestController @RequestMapping("/account") public class AccountController { @CrossOrigin("//example.com") @RequestMapping(method = RequestMethod.GET, "/{id}") public Account retrieve(@PathVariable Long id) { // ... } @RequestMapping(method = RequestMethod.DELETE, path = "/{id}") public void remove(@PathVariable Long id) { // ... } }

Spring akan menggabungkan atribut dari kedua anotasi untuk membuat konfigurasi CORS gabungan.

Dalam contoh ini, kedua-dua kaedah akan mempunyai maxAge 3600 saat, kaedah membuang () akan membenarkan semua asal, tetapi kaedah mengambil () hanya akan membenarkan asal dari //example.com.

3. Konfigurasi CORS Global

Sebagai alternatif kepada konfigurasi berasaskan anotasi yang halus, Spring membolehkan kami menentukan beberapa konfigurasi CORS global daripada pengawal anda. Ini serupa dengan menggunakan penyelesaian berdasarkan Penapis tetapi dapat dinyatakan dalam Spring MVC dan digabungkan dengan konfigurasi @CrossOrigin yang halus .

Secara lalai, semua kaedah asal dan kaedah GET, HEAD, dan POST dibenarkan.

3.1. JavaConfig

@Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**"); } }

Contoh di atas membolehkan permintaan CORS dari mana-mana asal ke mana-mana titik akhir dalam aplikasi.

Sekiranya kita ingin mengunci ini sedikit lagi, kaedah registry.addMapping mengembalikan objek CorsRegistration , yang dapat kita gunakan untuk konfigurasi tambahan. Terdapat juga kaedah allowOrigins yang membolehkan kami menentukan susunan asal yang dibenarkan. Ini boleh berguna jika kita perlu memuatkan array ini dari sumber luaran pada waktu runtime.

Selain itu, terdapat juga Metode yang diperbolehkan , Pembaca yang diizinkan , Pemimpin yang terdedah , kepemilikan maksimum , dan kelayakan yang dapat kita gunakan untuk menetapkan tajuk respons dan pilihan penyesuaian.

3.2. Ruang Nama XML

Konfigurasi XML minimum ini membolehkan CORS pada corak jalur / ** dengan sifat lalai yang sama dengan JavaConfig:

Anda juga boleh menyatakan beberapa pemetaan CORS dengan sifat yang disesuaikan:

4. CORS dengan Keselamatan Musim Semi

Sekiranya kita menggunakan Spring Security dalam projek kita, kita mesti mengambil langkah tambahan untuk memastikannya berfungsi dengan baik dengan CORS. Ini kerana CORS mesti diproses terlebih dahulu. Jika tidak, Spring Security akan menolak permintaan tersebut sebelum sampai ke Spring MVC.

Nasib baik, Spring Security menyediakan penyelesaian luar kotak:

@EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.cors().and()... } }

Artikel ini menerangkannya dengan lebih terperinci.

5. Bagaimana Ia Berfungsi

Permintaan CORS secara automatik dikirim ke berbagai HandlerMappings yang didaftarkan . Mereka menangani permintaan CORS preflight dan memintas CORS permintaan sederhana dan sebenarnya menggunakan pelaksanaan CorsProcessor ( DefaultCorsProcessor secara lalai) untuk menambahkan tajuk respons CORS yang relevan (seperti Access-Control-Allow-Origin ).

CorsConfiguration membolehkan kita menentukan bagaimana permintaan CORS harus diproses: asal, tajuk, dan kaedah yang dibenarkan, antara lain. Kami boleh menyediakannya dengan pelbagai cara:

  • AbstractHandlerMapping # setCorsConfiguration () membolehkan seseorang menentukan Peta dengan beberapa CorsConfiguration yang dipetakan ke corak jalan seperti / api / **
  • Subclasses may provide their own CorsConfiguration by overriding the AbstractHandlerMapping#getCorsConfiguration(Object, HttpServletRequest) method
  • Handlers may implement the CorsConfigurationSource interface (like ResourceHttpRequestHandler now does) to provide a CorsConfiguration for each request

6. Conclusion

In this article, we showed how Spring provides support for enabling CORS in our application.

We started with the configuration of the controller. We saw that we only need to add the annotation @CrossOrigin to enable CORS either to one particular method or the entire controller.

Akhirnya, kami juga melihat bahawa jika kami ingin mengawal konfigurasi CORS di luar pengawal, kami dapat melakukan ini dengan lancar dalam fail konfigurasi - baik menggunakan JavaConfig atau XML.

Kod sumber lengkap untuk contoh boleh didapati di GitHub.