Erreur Access-Control-Allow-Origin lors de la consommation d'API dans un frontend externe

Bonjour,

J’ai un référentiel créé avec Simplicité qui me fournit des API. Une interface externe contenant des IHM codée en AngularJS souhaite consommer mes APIs Simplicité.
En faisant des tests avec Postman tout fonctionne correctement, cependant, lorsque l’interface appelle les API, l’erreur suivante est retournée : :“No ‘Access-Control-Allow-Origin’ header is present on the requested ressource”.
De ce que j’ai compris, il faut ajouter un header particulier “Access-Control-Allow-Origin” pour que l’interface puisse contrôler les accès aux ressources.
Est-ce bien là la meilleure option? Si oui, comment pouvons-nous ajouter un header dans Simplicité (est-ce dans le fichier services de l’API? Et à travers quelle fonction?)?

Merci,

Le CORS est une configuration particulière à mettre en place conformément à vos besoins, ce n’est pas juste une histoire de header HTTP c’est plus compliqué que ça.

Par exemple, sur nos instances cloud nous faisons gérer ça par le reverse proxy NGINX en autorisant, par défaut, l’accès depuis tout origine.

Je sais qu’on peut aussi mettre ça en place niveau Tomcat si on a pas de reverse proxy capable de gérer ça…

Dans votre cas vous parlez de quelle(s) instance(s) ?

Quoiqu’il en soit il n’y a absolument rien de spécifique à Simplicité ici.

PS: s’il s’agit de vos instances internes et des APIs accessibles via Apigee, visiblement ça peut aussi se mettre en place à ce niveau: https://docs.apigee.com/api-platform/develop/adding-cors-support-api-proxy

Bonjour David,
à nouveau, merci beaucoup pour ton support.
Nous mettons a priori aussi en œuvre NGINX sur nos environnements (intranet ou aws) et il devrait être possible (et plus simple) d’activer la logique d’autorisation “toute origine” (*).
@paulineF, tu peux voir cela avec Sébastien?
Bruno

J’avais déjà échangé sur la configuration NGINX avec Sébastien, pour mémoire voici par exemple la configuration NGINX de l’instance “suppliers.renault.simplicite.io” qui autorise le CORS tout origine:

server {
    listen 80;
    server_name suppliers.renault.simplicite.io;
    location / {
        return 301 https://suppliers.renault.simplicite.io$request_uri;
    }
}
server {
    listen 443 ssl;
    server_name suppliers.renault.simplicite.io;
    ssl_certificate /etc/ssl/renault.simplicite.io.crt;
    ssl_certificate_key /etc/ssl/renault.simplicite.io.key;
    access_log /var/log/nginx/suppliers.renault.simplicite.io.log main;
    location / {
        if ($request_method = 'OPTIONS') {
            add_header Access-Control-Allow-Origin $http_origin;
            add_header Access-Control-Allow-Credentials true;
            add_header Access-Control-Allow-Headers Content-Type,Authorization,X-Requested-With,X-HTTP-Method-Override,X-Simplicite-Authorization;
            add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,HEAD,OPTIONS;
            add_header Access-Control-Max-Age 1728000;
            add_header Content-Type text/plain;
            add_header Content-Length 0;
            return 204;
        }
        if ($request_method = 'GET') {
            add_header Access-Control-Allow-Origin $http_origin always;
            add_header Access-Control-Allow-Credentials true always;
            add_header Access-Control-Expose-Headers X-Simplicite-SessionID;
        }
        if ($request_method = 'POST') {
            add_header Access-Control-Allow-Origin $http_origin always;
            add_header Access-Control-Allow-Credentials true always;
            add_header Access-Control-Expose-Headers X-Simplicite-SessionID;
        }
        proxy_redirect off;
        proxy_buffering off;
        proxy_read_timeout 86400s;
        proxy_send_timeout 86400s;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_pass http://localhost:10303;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

A adapter à votre cas bien sûr mais l’idée générale est là.

PS: cela dit, si on parle d’accès via Apigee je pense que ce serait plutôt à lui de gérer ça… mais bon…

Oui, vu avec Pauline, dans le cas présent, ils attaquent directement le backend (c’est donc un cas d’exception a priori transitoire en attendant d’avoir réglé les pb du côté d’apigee).
NB: lorsqu’on cherche ‘CORS’ sur le forum, aucun post mentionnant le terme n’est listé… le sujet a effectivement été abordé avec Gaylord par le biais d’une problématique de user token; seuls les termes mentionnés dans le sujet semblent pris en compte dans la recherche…

Dans l’échange que tu cite (Authentification par user token pour utilisation d'API) il y a bien des exemples de conf NGINX avec/sans les directives CORS…

J’ai aussi retrouvé un email du 3 mars dans lequel je fournissait le même genre d’exemple conf NGINX avec les directives CORS… je te l’ai forwardé pour mémoire.

Cela dit, la configuration des directives CORS est un sujet classique dans les appels d’API depuis des pages web. Rien de specifique à Simplicité ici, ce qu’on fait avec NGINX n’est qu’une manière parmi plein d’autres de gérer ça.

J’ai aussi retrouvé ça comme exemple de config niveau Tomcat (dans le web.xml mais ça doit pouvoir se mettre ailleurs je pense). C’est @Francois qui s’est servi de ça pour un cas sans reverse proxy ou avec un reverse proxy qui ne gérait pas le CORS, il saura l’expliquer mieux que moi si besoin…

	<!-- Cross domain access on public web services (not needed if behind a CORS-enabled reverse proxy) -->
	<filter>
		<filter-name>CorsFilter</filter-name>
		<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>CorsFilter</filter-name>
		<url-pattern>/health</url-pattern>
		<url-pattern>/api/*</url-pattern>
	</filter-mapping>

Là aussi à adapter dans votre cas.

NB: Si vous faites gérer le CORS niveau NGINX (ou Apigee) ne le faites pas niveau Tomcat et réciproquement.

oui, merci, en fait, j’ai cherché sur le forum rapidement et je n’ai pas retrouvé les posts…
J’ai bien archivé ton mail :) merci!

OK pour info je suis en train de regarder si on pourrait rendre notre image Docker capable d’activer le filter CORS de la webapp Tomcat (cf mon post précédent) en fonction de la présence d’une variable d’environnement ad hoc… A suivre

1 Like

De mémoire, on avait dû le faire il y a quelque temps via la config “web.xml” pour un client lorrain qui avait une architecture spécifique donc compliquée…

A noter : les appels $.ajax depuis la UI utilise bien les CORS afin de pouvoir appeler des services hors domaines sur le front, mais n’oblige en rien de fournisseur à nous répondre.

	ajaxSetup: {
		crossDomain: true,
		xhrFields: { withCredentials: true }
	},