CORS avec Spring

CORS avec Printemps

1. Vue d'ensemble

Dans tous les navigateurs modernes, le partage de ressources d'origine croisée (CORS) est une spécification pertinente avec l'émergence de clients HTML5 et JS qui consomment des données via des API REST.

Dans de nombreux cas, l’hôte qui dessert le JS (par exemple, example.com) est différent de l'hôte qui sert les données (par ex. api.example.com). Dans un tel cas, CORS permet la communication interdomaine.

Spring fournit dessupport de première classe pour CORS, offrant un moyen simple et puissant de le configurer dans n'importe quelle application Web Spring ou Spring Boot.

Lectures complémentaires:

Fixation des 401 avec les contrôles en amont de la CORS et Spring Security

Découvrez comment corriger le statut d'erreur HTTP 401 pour les demandes de contrôle en amont CORS

Read more

Spring Webflux et CORS

Un guide rapide et pratique pour travailler avec CORS et Spring Webflux.

Read more

2. Méthode de contrôleur Configuration CORS

L'activation de CORS est simple - ajoutez simplement l'annotation@CrossOrigin.

Nous pouvons mettre cela en œuvre de différentes manières.

2.1. @CrossOrigin sur une méthode de gestion@RequestMapping-Annotated

@RestController
@RequestMapping("/account")
public class AccountController {

    @CrossOrigin
    @RequestMapping("/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

Dans l'exemple ci-dessus, CORS n'est activé que pour la méthoderetrieve(). Nous pouvons voir que nous n'avons défini aucune configuration pour l'annotation@CrossOrigin, donc la configuration par défaut a lieu:

  • Toutes les origines sont autorisées

  • Les méthodes HTTP autorisées sont celles spécifiées dans l'annotation@RequestMapping (pour cet exemple, c'est GET)

  • L'heure de mise en cache de la réponse de contrôle en amont (maxAge) est de 30 minutes

2.2. @CrossOrigin sur le contrôleur

@CrossOrigin(origins = "http://example.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

    @RequestMapping("/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

Puisque@CrossOrigin est ajouté au contrôleur, les méthodesretrieve() etremove() l'ont activé. Nous pouvons personnaliser la configuration en spécifiant la valeur de l'un des attributs d'annotation:origins,methods,allowedHeaders,exposedHeaders,allowCredentials oumaxAge.

2.3. @CrossOrigin activé Méthode du contrôleur et du gestionnaire

@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

    @CrossOrigin("http://example.com")
    @RequestMapping("/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

Spring combinera les attributs des deux annotations pour créer une configuration CORS fusionnée.

Dans cet exemple, les deux méthodes auront unmaxAge de 3600 secondes, la méthoderemove() autorisera toutes les origines mais la méthoderetrieve() n'autorisera que les origines dehttp://example.com.

3. Configuration globale de CORS

En guise d'alternative à la configuration basée sur les annotations, Spring nous permet de définir une configuration globale CORS à partir de vos contrôleurs. Ceci est similaire à l'utilisation d'une solution basée surFilter, mais peut être déclaré dans Spring MVC et combiné avec une configuration@CrossOrigin à granularité fine.

Par défaut, toutes les origines et les méthodes GET, HEAD et POST sont autorisées.

3.1. JavaConfig

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}

L'exemple ci-dessus active les demandes CORS de n'importe quelle origine vers n'importe quel point d'extrémité de l'application.

Si nous voulons verrouiller cela un peu plus, la méthoderegistry.addMapping renvoie un objetCorsRegistration qui peut être utilisé pour une configuration supplémentaire. Il existe également une méthodeallowedOrigins que vous pouvez utiliser pour spécifier un tableau d’origines autorisées. Cela peut être utile si vous devez charger ce tableau à partir d'une source externe au moment de l'exécution.

En outre, il existe égalementallowedMethods,allowedHeaders,exposedHeaders,maxAge etallowCredentials qui peuvent être utilisés pour définir les en-têtes de réponse et nous fournir plus d'options de personnalisation .

3.2. Espace de noms XML

Cette configuration XML minimale active CORS sur un modèle de chemin/**avec les mêmes propriétés par défaut que JavaConfig:


    

Il est également possible de déclarer plusieurs mappages CORS avec des propriétés personnalisées:



    

    

4. Comment ça fonctionne

Les requêtes CORS sont automatiquement envoyées aux différentsHandlerMappings qui sont enregistrés. Ils gèrent les demandes de contrôle en amont CORS et interceptent les demandes simples et réelles CORS au moyen d'une implémentation deCorsProcessor (DefaultCorsProcessor par défaut) afin d'ajouter les en-têtes de réponse CORS appropriés (tels queAccess-Control-Allow-Origin).

CorsConfiguration permet de spécifier comment les requêtes CORS doivent être traitées: origines autorisées, en-têtes et méthodes entre autres. Cela peut être fourni de différentes manières:

  • AbstractHandlerMapping#setCorsConfiguration() permet de spécifier unMap avec plusieursCorsConfigurations mappés sur des modèles de chemin tels que/api/**

  • Les sous-classes peuvent fournir leurs propresCorsConfiguration en remplaçant la méthodeAbstractHandlerMapping#getCorsConfiguration(Object, HttpServletRequest)

  • Les gestionnaires peuvent implémenter l'interfaceCorsConfigurationSource (comme le fait maintenantResourceHttpRequestHandler) afin de fournir unCorsConfiguration pour chaque requête

5. Conclusion

Dans cet article, nous avons montré comment Spring prenait en charge l’activation de CORS dans notre application.

Nous avons commencé par la configuration du contrôleur. Nous avons vu qu'il suffit d'ajouter l'annotation@CrossOrigin pour activer CORS soit pour une méthode particulière, soit pour l'ensemble du contrôleur.

Enfin, nous avons également constaté que si nous souhaitons contrôler la configuration CORS en dehors des contrôleurs, nous pouvons le faire facilement dans les fichiers de configuration, en utilisant JavaConfig ou XML.

Le code source complet des exemples est disponibleover on GitHub.