CODiLOG, 205 Avenue Georges Clemenceau, 92024 Nanterre
06 99 32 17 37
marketing@codilog.fr

CORS SAP – Qu’est-ce que c’est et comment le gérer?

DEVENEZ SAP COMME JAMAIS !

SAP CORS

Introduction au CORS SAP

Le CORS est une problématique qui devient courante sur SAP. En effet, Les applications web sont de plus en plus diverses et nombreuses et il convient de renforcer leur sécurité pour éviter toute attaque et préserver nos données. La technologie évoluant, il est de plus en plus aisé pour les hackers de commettre leurs méfaits. Puissance de calcul, failles réseaux ou systèmes, ils exploitent tout ce qui est à leur disposition.

Afin de contrer les hackers, les normes de sécurité évoluent et apportent de plus en plus de mécanismes, d’algorithmes ou de protocoles de sécurité. L’exemple le plus flagrant est celui des mots de passes toujours plus complexes et plus long.

C’est dans ce contexte que le CORS, pour Cross Origin Resource Sharing, voit le jour. Le CORS est un protocole de sécurité qui s’applique aux navigateurs. Son but ? Bloquer l’accès à vos ressources depuis une origine qui n’est pas la vôtre si vous ne l’avez pas autorisée spécifiquement.

Côté SAP, de plus en plus de solutions sont basées sur le WEB. Outre les outils cloud tels que Success Factors, il y a SAP FIORI et SAPUI5 qui permettent de créer des applications d’entreprise web.

Nous allons voir au travers de ce post, dans quels cas il est nécessaire de mettre en place ce protocole avec la description de scenarii type mais également un exemple de mise en œuvre sur vos systèmes SAP.

Qu’est-ce que le CORS – Cross Origin Resources Sharing ?

CORS est un mécanisme de sécurité permettant d’autoriser une origine à accéder à une ressource située à une autre origine. Il s’agit en effet d’une façon de contourner la règle appelée same-origin policy que la plupart des navigateurs implémentent de nos jours. Il faut rappeler qu’une origine est constituée d’un protocole tel que https, d’un domaine et d’un port (les ports par défaut peuvent être omis).

On a donc <protocol>://<domain or hostname> :<port>

Exemple :

https://codilog.fr ou http://localhost:8080

Vous remarquez qu’il n’y a pas de port dans l’un des exemples ci-dessus, c’est parce qu’il s’agit du port par défaut (80 pour http et 443 pour https). Dans ce cas, il peut être omis.

Le CORS, contrairement aux idées reçues, est donc une protection implémentée côté client et non serveur. Plus précisément, cette protection concerne les appels AJAX émis au travers d’un navigateur web. Cette erreur d’appréciation est souvent liée au fait que la politique de CORS s’implémente côté serveur mais ce n’est que pour « montrer patte blanche » au client qui attend certaines entêtes HTTP de la part du serveur. Un outil comme Postman ou SOAPUI pourrait donc réussir à faire passer la requête contrairement à votre application web. En effet ces outils n’étant pas des navigateurs, ils n’ont que faire du CORS.

Comment ça marche?

 

Grâce au CORS, un développeur peut décider de qui peut consommer les ressources d’un serveur (Access-Control-Allow-Origin), depuis un navigateur, en renvoyant des entêtes HTTP particulières. Outre l’origine du demandeur, il est possible de contrôler les méthodes HTTP autorisées (Access-Control-Allow-Methods) telles que POST, GET, DELETE, etc. Ou encore de spécifier quelles entêtes HTTP peuvent être associées à la requête entrante (Access-Control-Allow-Headers).

Prenons un exemple concret :

Mon application est accessible depuis https://codilog.fr et tente d’accéder à une ressource située sur https://www.neurones.net. Dans ce cas, une erreur sera propagée au navigateur de ce type :

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://codilog.fr' is therefore not allowed access.

Cela signifie que le serveur sur lequel je tente de récupérer une ressource (https://www.neurones.net) n’a pas implémenté de règle CORS autorisant https://codilog.fr en tant qu’origine pouvant accéder à cette ressource.

Voici un diagramme illustrant le cheminement d’une requête dans le protocole CORS.

 

Comment gérer le CORS SAP?

Le CORS et une problématique peu connu dans les contextes SAP UI5 ou encore FIORI lorsqu’on utilise les outils SAP. En effet, qu’il s’agisse d’une application FIORI ou SAP UI5 qui est développées, testée et/ou exécutées depuis SAP Web IDE (ou SAP Business Application Studio), SAP Gateway ou encore SAP Cloud Platform, le CORS n’est pas un problème puisque la consommation des ressources se fait depuis la même origine ou via un proxy qui est géré par le système de destinations de SCP/SAP Web IDE.

C’est en général lorsqu’on s’attaque aux applications mobiles hybrides que cette problématique se rencontre, les applications natives n’étant pas exécutées dans un navigateur. Il suffit de créer un projet SAPUI5 avec Cordova consommant un service OData de votre système SAP pour rencontrer les blocages dès lors que rien n’est fait pour gérer le CORS. En effet, les projets FIORI/SAP UI5 consommés au travers de Cordova ont pour origine localhost qui est donc différente de celle de votre système SAP.

C’est dans le cadre de ce dernier cas que je vais vous décrire les options qui s’offrent à vous. Il faut tout de même garder à l’esprit que le CORS pourrait se rencontrer dans bien d’autres cas comme par exemple lors de la consommation de ressources liées à des applications SAPUI5 ou FIORI depuis un autre serveur Frontend.

Implémentation du CORS sur SAP

La meilleure solution est de gérer proprement au niveau de votre serveur votre propre politique de CORS. Que ce soit sur le serveur SAP, un apache ou encore Web Dispatcher, il s’agit de permettre au serveur recevant les requêtes de l’application de renvoyer les entêtes HTTP adéquates. Attention, certains prérequis sont à respecter en matière de Kernel (min 7.49) par exemple pour permettre à votre serveur de « connaître » les instructions permettant de renvoyer les entêtes HTTP (setResponseHeader).

Par ailleurs, à partir de certaines versions de SAP Netweaver, le module UCON offre un moyen d’implémenter le CORS via la transaction UCONCOCKPIT. Voici la liste de ces versions minimales :

  • SAP NetWeaver AS ABAP 7.52 SP02
  • SAP NetWeaver AS ABAP 7.51 SP06
  • SAP NetWeaver AS ABAP 7.50 SP12
  • SAP NetWeaver AS ABAP 7.40 SP20

Pour en savoir plus, vous pouvez consulter la note 2547381

A partir de ces versions, vous pouvez gérer le CORS via le module UCON. Cette documentation est disponible sur la page d’aide SAP suivante : https://help.sap.com/viewer/1ca554ffe75a4d44a7bb882b5454236f/1709.000/en-US/149f40fa2c9b40599b2a61ee9127e20c.html

Dans un prochain article, je vous présenterai plus en détail cette configuration.

Si vous n’avez pas atteint ces versions, vous pouvez tout de même implémenter le CORS en suivant cette méthode :

Premièrement, vous devez ajouter une entrée au niveau de votre profil d’instance pour spécifier l’adresse de votre fichier de réécriture d’URL.

icm/HTTP/mod_0 = PREFIX=/,FILE=$(DIR_PROFILE)/cors.txt

Nous devons donc créer un fichier que j’ai appelé cors.txt et y écrire nos règles CORS.

Il s’agit de renvoyer les entêtes HTTP souhaitées telles que :

SetResponseHeader Access-Control-Allow-Origin *

SetResponseHeader Access-Control-Allow-Credentials false

SetResponseHeader Access-Control-Allow-Methods "GET, POST, PUT, OPTIONS"

SetResponseHeader Access-Control-Allow-Headers "x-csrf-token, Content-Type, Authorization, mysapsso2"

SetResponseHeader Access-Control-Expose-Headers "x-csrf-token"

SetResponseHeader Access-Control-Max-Age 600

Vous pouvez spécifier plus finement vos besoins ou encore créer des structures conditionnelles afin de gérer différents contextes applicatifs.

Une fois le script en place, vous devez redémarrer votre instance pour qu’il soit pris en compte.

Les autres options

Si vous n’avez pas la possibilité d’agir sur le système, il n’est pas impossible de contourner le CORS. En effet, comme je l’ai expliqué au début, il s’agit d’une sécurité implémentée au niveau du navigateur, aussi selon votre contexte, vous pourrez passer outre en passant par un serveur tiers qui lui pourrait être configuré au niveau du CORS. Ce serait donc ce serveur intermédiaire qui effectuerait les requêtes vers votre système SAP. Cela s’apparente à du proxy. SAP Cloud Platform (SCP) utilise cette pratique via le système de destination vers le système backend. Ce mécanisme s’apparente à du reverse proxy.

De même, la plupart des services d’API management feront office de proxy et vous éviteront ces désagréments.

On retrouve également ce type de problématique au sein des applications mobile hybrides telles que les application Apache Cordova, Ionic etc… En effet il s’agit d’applications web packagées dans un conteneur mobile, aussi il est fréquent de se retrouver face à des erreurs de type CORS dans ce domaine.

Si on ne peut pas avoir la main sur le serveur, il faut passer par du code natif du téléphone pour effectuer les appels web services.

Il est possible de le faire pour Cordova via le plugin cordova-plugin-advanced-http par exemple.

Cas du preflight (requête de pré-validation)

Pour certaines requêtes complexes (d’un point de vue CORS), le navigateur émet une requête préliminaire appelée preflight. Le navigateur envoie cette requête préliminaire sous la forme d’une requête HTTP OPTIONS.

Une requête complexe possède les caractéristiques suivantes :

  • Ne concerne pas les méthodes GET, POST, ou HEAD
  • A d’autres entêtes HTTP que Accept, Accept-Language ou Content-Type
  • Possède une entête HTTP Content-Type autre que application/x-www-form-urlencoded, multipart/form-data, ou text/plain

Par exemple :

OPTIONS /data HTTP/1.1
Origin: https://codilog.fr
Access-Control-Request-Method: POST

Le serveur prend en charge cette requête et renvoie par entête http, les méthodes ou origines autorisées.

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://codilog.fr
Access-Control-Allow-Methods: GET, DELETE, HEAD, OPTIONS

Le script décrit dans la section implémentation du CORS ne gèrera pas le preflight. En effet, puisqu’il n’y a pas de possibilité d’envoyer la requête du preflight autrement que de manière anonyme, c’est-à-dire sans porter d’informations qui permettrait l’authentification de l’émetteur, cette requête n’arrivera même pas au script CORS. Il faudrait donc pouvoir adresser une application anonyme pour que cela puisse couvrir le preflight.

Pour ce faire, une solution consiste à créer 1 nœud ICF permettant l’accès anonyme. Ce nœud ne devra rien faire d’important ou de lourd pour ne pas nuire à la sécurité ou aux performances. On associe souvent ce nœud au handler CL_HTTP_EXT_PING qui répond à ces critères. Il est aussi possible de créer votre propre handler.

Il ne reste qu’à rediriger les requêtes de preflight vers ce nœud et de renvoyer les bons entêtes http.

Voici un exemple de code à mettre dans le script de réécriture d’URL :

Tout d’abord, gestion de la redirection vers le nœud anonyme appelé cors dans cet exemple :

if %{REQUEST_METHOD} stricmp OPTIONS
  begin
    RegRewriteUrl ^/.* /cors?%{QUERY_STRING} [noescape]
  end

Puis après redirection, le serveur peut renvoyer au client les entêtes souhaités :

if %{PATH} regmatch /cors
  begin
        SetResponseHeader Access-Control-Max-Age 600
        SetResponseHeader Access-Control-Allow-Origin
        SetResponseHeader Access-Control-Allow-Credentials true
        SetResponseHeader Access-Control-Allow-Methods "GET, POST, …"
        SetResponseHeader Access-Control-Allow-Headers "x-csrf-token,…"
        SetResponseHeader vary "Origin"
  end

Ne pas oublier de redémarrer l’application server !

Si vous avez des questions sur cet exemple ou sur toute autre problématique CORS (qu’elle soit liée à SAP FIORI, SAP UI5 ou à tout autre produit SAP), n’hésitez pas à nous contacter, notre équipe d’experts se tient à votre disposition.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *