Architecture

CORS : appeler TOSIAM depuis une autre origine

Sur cette page

Un navigateur ne laisse une page appeler une autre adresse en JavaScript que si cette adresse l’autorise : c’est le CORS (Cross-Origin Resource Sharing). Une application Angular ou React servie sur https://app.example.com qui appelle le point des jetons ou userinfo de https://sso.example.com a donc besoin d’une configuration CORS dans TOSIAM.

Pas besoin de CORS quand :

  • la page est servie par TOSIAM lui-même, ou par un CDN placé sur la même adresse (voir CDN sur le même domaine) ;
  • seul un serveur appelle TOSIAM, comme une application Spring Boot qui échange le code contre des jetons.

Ce que TOSIAM vérifie#

Le filtre CORS couvre toutes les adresses de TOSIAM. Il ne s’occupe que des requêtes qui portent un en-tête Origin différent de l’adresse de TOSIAM.

  • Aucune configuration active (commutateur global désactivé, ou aucune configuration activée) : TOSIAM n’ajoute aucun en-tête CORS, et le navigateur bloque les appels venus d’une autre origine.
  • Au moins une configuration active : une requête venue d’une origine qu’aucune configuration n’accepte est refusée (403).

Avant une requête qui n’est pas « simple » (un POST en JSON, un en-tête authorization…), le navigateur envoie une pré-vérification : une requête OPTIONS qui annonce la méthode (Access-Control-Request-Method) et les en-têtes (Access-Control-Request-Headers) de la vraie requête. TOSIAM y répond 200 avec les en-têtes Access-Control-Allow-* si une configuration accepte l’origine, la méthode annoncée et tous les en-têtes annoncés ; sinon 403.

Les réglages#

Dans la console, Services globaux › CORS configuration :

Faites défiler le tableau
RéglageAttributRôle
Activer CORSforgerock-am-cors-config-enable-all-corsCommutateur global. Sans lui, aucune configuration n’est appliquée.

Puis une configuration par application, sous Sous-configurations › Nouvelle configuration :

Faites défiler le tableau
RéglageAttributRôle
Activer cette configuration CORSforgerock-am-cors-config-enable-corsLa configuration n’est appliquée que si elle est activée.
Origines acceptéesforgerock-am-cors-config-accepted-originsSchéma, nom et port, exactement comme le navigateur les envoie, sans / final : http://localhost:3000, https://app.example.com. * accepte toutes les origines, mais pas avec les identifiants.
Méthodes acceptéesforgerock-am-cors-config-accepted-methodsLes méthodes des vraies requêtes : GET, POST…
En-têtes acceptésforgerock-am-cors-config-accepted-headersLes en-têtes que la page envoie : authorization, content-type. Depuis la version 3.38.0, la casse ne compte pas (Authorization convient aussi) ; avant, saisissez-les en minuscules.
En-têtes exposésforgerock-am-cors-config-exposed-headersLes en-têtes de la réponse que la page peut lire.
Autoriser les identifiants (cookies)forgerock-am-cors-config-allow-credentialÀ activer quand la page envoie le cookie de session (credentials: 'include').
Durée de mise en cache (max-age)forgerock-am-cors-config-max-ageDurée, en secondes, pendant laquelle le navigateur garde la réponse de la pré-vérification.

Les en-têtes à accepter dépendent de ce que la page appelle :

Faites défiler le tableau
Appels depuis la pageEn-têtes acceptés
Point des jetons (/oauth2/.../access_token), en application/x-www-form-urlencodedaucun
userinfo, introspection, API protégées par un jetonauthorization
Requêtes en JSONcontent-type
API /json/... (par exemple /json/authenticate)content-type, accept-api-version, x-requested-with ; et les en-têtes de connexion que la page utilise, comme x-openam-username et x-openam-password

Configurer avec ssoadm#

Un fichier de données pour l’application, app_cors.properties :

properties· app_cors.properties
forgerock-am-cors-config-enable-cors=true
forgerock-am-cors-config-accepted-origins=https://app.example.com
forgerock-am-cors-config-accepted-methods=GET
forgerock-am-cors-config-accepted-methods=POST
forgerock-am-cors-config-accepted-headers=authorization
forgerock-am-cors-config-accepted-headers=content-type

Puis le commutateur global et la configuration :

bash
ssoadm set-attr-defs -s iPlanetCORSConfig -t global \
  -a forgerock-am-cors-config-enable-all-cors=true \
  -u amadmin -f /chemin/vers/pwd.txt

ssoadm create-sub-cfg -s iPlanetCORSConfig --subconfigid CorsList --subconfigname app \
  --datafile app_cors.properties -u amadmin -f /chemin/vers/pwd.txt

Pour la retirer : ssoadm delete-sub-cfg -s iPlanetCORSConfig --subconfigname app.

Les changements s’appliquent sans redémarrage, depuis la console comme avec ssoadm. Depuis la version 3.38.0, c’est vrai aussi du commutateur global posé par set-attr-defs ; avant, il n’était pris en compte qu’au redémarrage ou à la modification suivante d’une configuration.

Vérifier avec curl#

Une pré-vérification comme celle du navigateur, pour un POST avec un en-tête authorization :

bash
curl -s -o /dev/null -D - -X OPTIONS \
  -H "Origin: https://app.example.com" \
  -H "Access-Control-Request-Method: POST" \
  -H "Access-Control-Request-Headers: authorization" \
  https://sso.example.com/tosiam/oauth2/realms/root/userinfo

Réponse attendue (l’ordre des valeurs peut varier) :

texte
HTTP/1.1 200
Access-Control-Allow-Methods: POST,GET
Access-Control-Allow-Headers: authorization,content-type
Access-Control-Allow-Origin: https://app.example.com

Avec une origine, une méthode ou un en-tête absent de la configuration, la réponse est 403, sans en-tête Access-Control-Allow-*.

En cas de problème#

Faites défiler le tableau
Ce que l’on voitCause probable
Erreur CORS dans la console du navigateur, réponse sans Access-Control-Allow-OriginCommutateur global désactivé, ou configuration non activée
set-attr-defs … enable-all-cors=true ne change rienLa page CORS configuration a déjà été enregistrée : sa valeur l’emporte sur la valeur par défaut. Activez le commutateur dans la console
Pré-vérification en 403Origine, méthode annoncée ou un des en-têtes annoncés absent de la configuration. Avant la version 3.38.0 : un en-tête saisi avec des majuscules (Authorization) ; saisissez-le en minuscules
Requêtes d’une autre application refusées en 403 depuis qu’une configuration CORS existeSon origine n’est dans aucune configuration : ajoutez-la, ou créez une configuration pour elle
Le navigateur refuse la réponse, avec un message sur les identifiantsLa page envoie le cookie (credentials: 'include') et Autoriser les identifiants est désactivé

Mis à jour le