Web-services CASifiés

Pascal.Rigaux @ univ-paris1.fr

Single Page Application

web-service dédié sur le même vhost

Une solution simple est de faire comme les applications non-SPA : exiger une session valide pour toutes pages html.

Le web-service peut alors utiliser la session.

Exemple :

NB : dans l'exemple app/index.html est accessible, mais il faut utiliser app/index.php NB2 : if your first page is static and CAS protected, you must ensure it is not browser cached

Limites

La solution proposée est très simple et fonctionne très bien.

Pourquoi faire plus compliqué ?

  • Web Services séparés de la SPA
  • Mieux gérer la fin de session
  • Web Components (ie Web Widgets)

Web Services séparés de la SPA

Plusieurs solutions sont possibles, sans CASifier ces Web Services :
  • le Web Service dédié fait les requêtes vers le Web Service séparé, en trusted (IP ou Basic auth, OAuth Client Credentials)
  • le Web Service fournit un JWT utilisé pour accéder au Web Service séparé. Exemple :
  • proxy ticket CAS

Authentification

Pour authentifier un web service depuis le navigateur :

possibilitécontraintes
classique maitriser l'url de la page
window.open + postMessage clic utilisateur
JSONPauth préalable, third party cookies, pas shibboleth
iframe cachéeauth préalable, third party cookies

Mieux gérer la fin de session

window.open +
postMessage

Permet de gérer finement le relog en fin de session.

  • prompt the user to relog
  • window.open la mire CAS
  • postMessage
  • l'appli ferme la fenêtre

Utilisé notamment par google

Exemple d'implémentation : AngularJS, Angular (TODO).

XHR, CORS, JSONP

GET POST DELETE,
PUT
Cross domain Cookies Error handling HTTP header
XHR X X X X X X
CORS X X X controlé limité X X
JSONP X X X partiel
<form> + hidden iframe oui,
aveugle
oui,
aveugle
X X ?

XHR, CORS, JSONP

Précisions

CORS
  • bien répandu (IE >= 8)
  • limité : impossible d'avoir cookies + redirect

JSONP

  • possibilité de contrôler partiellement le cross-domain en vérifiant le referer

<form> + hidden iframe

  • impossible de lire le résultat des requêtes GET/POST

JSONP vs Ajax

REST/JSON

Requête Ajax http://foo.fr/bar qui renvoie

{ "Name": "Foo", "Id": 1234 }

JSONP

Balise script src=http://foo.fr/bar?callback=f qui renvoie

f({ "Name": "Foo", "Id": 1234 })

Pour faire du JSONP en PHP, on remplace

echo $data
par

echo $_GET['callback'] . '(' . $data . ');';

JSONP

Avec un web-service compatible JSONP, on peut l'utiliser de la même manière que XHR tout en étant cross-domain.

⚠ Autoriser JSONP ouvre le web-service à des vols de données par XSS.

⚠ Pour éviter les attaques CSRF, le web-service doit respecter la norme HTTP : GET ne doit pas faire d'effet de bord.

Safari refuse les cookies des sites non visités. Cela concerne uniquement les sites externes. Si besoin, le web-service peut contourner le problème en utilisant sessionStorage.

JSONP & CAS

Si cookie CAS dans le navigateur,
possibilité d'autolog requête JSONP :
NB : CAS gateway est recommandée pour la gestion d'erreur

JSONP & Shibboleth

La fédération Éducation-Recherche utilise le binding « HTTP Post ». Cela rend difficile l'authentification :

  • JSONP : impossible
  • iframe cachée : possible mais impossible de savoir si l'authentification a échoué ou est en cours

Solution pour un Web Component :

  • tester un login automatique dans une iframe cachée
  • tout en proposant un login explicite avec window.open

NB : l'utilisation du binding « HTTP Artifact » rendrait le mécanisme similaire à CAS. Cela éviterait aussi les syndromes « page blanche » et « action "page précédente" impossible »

SPA et WS sur domaine différent

Safari refuse les cookies des sites non visités. Cela concerne uniquement les sites externes.

Dans ce cas on peut utiliser un token

  • conservé dans sessionStorage ou en mémoire,
  • passé à chaque requête XHR, par exemple dans le header "Authorization"

SPA et WS sur domaine différent

Authentification du web-service qui renvoie d'un token :
  • Java CAS Client : facile ➡ fait dans SMS-U (redirectAfterValidation + jsessionid dans l'URL)
  • phpCAS : facile
  • Shibboleth SP : impossible, cookies obligatoires
  • SimpleSAMLphp, OpenSAML... : à tester

login_then

L'api fournit une page login.php qui redirige vers la page html une fois la session obtenue.

Beaucoup d'applications utilisent cette technique (spring-security, shibboleth-SP...)

Cette technique est utilisable avec ou sans cookies pour le web-service.

Exemple d'implémentation : avec puis sans cookie

implicit grant

Mimicks OAuth2 implicit grant which passes the token as a fragment identifier.

Note that it breaks CAS back channel Single Logout.

Exemple d'implémentation

Web Service cross-domain

sécurité

Toutes les techniques nécessitent une validation pour éviter les attaques CSRF.

Chaque diagramme montre les points à vérifier.