Ces scripts ne sont pas conçu pour une application en production. Cependant, ils fournissent un flux complet que vous pourrez adapter au besoin de votre application cliente. En particulier, il serait opportun d’utiliser les fonctions d’affichage et de gestion des erreurs du système de l’application cliente.
Notez que ces scripts jouent le rôle de Point d’extrémité de redirection, ou URI de retour à l’application cliente (Redirection Endpoint). Voyez : OAuth 2.0 : Points d’extrémité.
Première version : Validation locale du JWT
La vérification du jeton JWT est effectuée localement par la fonction decode_jwt(), qui est décrite dans cet article : JSON Web Token (JWT).
PHP
- <?php
- /*
- testopenid3.php
- Verbose Test of OpenID Connect Authorization Code Flow
- This code is meant for testing, not for production !
- At the authentification step, if you don't want to create an account
- on OAuthSD, use this credentials :
- login = bebert
- password = 012345678
- Author :
- Bertrand Degoy https://degoy.com
- Credits :
- bschaffer https://github.com/bshaffer/oauth2-server-php
- Licence : MIT licence
- Copyright (c) 2016 - DnC
- */
- //***** Configuration *****
- /* Client's Public Key
- Warning : no double-quote, no indent!
- */
- '-----BEGIN PUBLIC KEY-----
- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2dCHybdu/1pDk5BHSxMA
- nMGygm8lm6s2hnru3GPH2JyMxrd92dC7TljI21P+egsnmjsUzaS1IWZPvIFvEOwO
- 5wP8gFyNm8fFkXSmrAEHXLFJ6WufF+f5Fg3pU5GDPjT5Z7ccWab5NM9w7ec433J1
- XtePh2QjUbibu4rpwYh8ADODAJkyIRMhhYXqK0n8GgojkcgEZ172sB/NdbcNALPy
- Qg0lMd3/AKxavTSSm9LslEyP+ZwBvTENzhoeQV2V7ZQ5xIZs6VBgrnsnYbgfbdQ+
- Dbk2FRbtB2+g4rKbN04JheaZyFORseoigVJ6asQ5lUS/3cMIUj2C+VBj4xAyXp00
- TMH8GtiGIQkVYjBd/Lsza11YwBOA8YYvDnTs/kzy9CqHjETdIHUlNqeaFbHSYTST
- rUl9QxBN+JAVGs9YY9MWoiVsGex4MsTwf3PanKIlavKXeFSwppwMMvmdt+yrGraH
- UKv5QP5NMbOu6/BghbuQZP4MoUnRxQxt8PN2e5M2b358C3tctgRQhRGBWaYw8B5J
- /drz5VA8s14NkG162lBW7PLYhLqm8u2hpqIlOCVndwW2W+bCkXrfjj3jBHe4yauQ
- vyQWcv3KaBV2HsUoY2sCAaC5nB46SV0UkAycX8xyqOsGJA64m2S+ntOQkB9R2x2y
- 4DjfJHTRTe2uXsaiYFahoLECAwEAAQ==
- -----END PUBLIC KEY-----
- ');
- $client_id = 'testopenid';
- $client_secret = 'thesecret';
- $authorization_endpoint = 'https://oa.dnc.global/authorize';
- $token_endpoint = 'https://oa.dnc.global/token';
- $userinfo_endpoint = 'https://oa.dnc.global/userinfo';
- //*** End of configuration ***
- // Set session
- // Check state
- if ( $_GET['state'] == $_SESSION['state'] ) {
- // Step 2. Token request
- $code = $_GET['code'];
- 'grant_type' => 'authorization_code',
- 'code' => $code,
- );
- //curl_setopt($h, CURLOPT_SSL_VERIFYPEER, false);
- if ($res) {
- // Validate signed JWT token using client's public key
- if ( $payload = decode_jwt($res['id_token'],
- PUBLIC_KEY, 'RS256') ) {
- // If Token Response is valid goto step 3
- // Step 3. Get UserInfo
- $access_token = $res['access_token'];
- /* Auth Header Methode
- $headr = array();
- $headr[] = 'Authorization: Bearer ' . $access_token;
- $h = curl_init();
- curl_setopt($h, CURLOPT_URL, $userinfo_endpoint);
- curl_setopt($h, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($h, CURLOPT_TIMEOUT, 10);
- curl_setopt($h, CURLOPT_HTTPHEADER, $headr);
- //curl_setopt($h, CURLOPT_SSL_VERIFYPEER, false);
- //*/
- //* Post Methode
- 'access_token' => $access_token,
- 'state' => $state,
- );
- application/x-www-form-urlencoded'));
- //*/
- if ( $res ) {
- // Check User ID
- if ( $payload['sub'] == $res['sub'] ) {
- // Everithing Ok !
- echo "UserInfo Response:\n";
- } else
- // User of ID Token doesn't match UserInfo's one
- } else
- // Token request error
- . $res['error_description']);
- } else {
- // Curl error during UserInfo request
- }
- } else
- // Invalid id_token
- } else {
- // Token request error
- . $res['error_description']);
- }
- } else {
- // Curl error during Token request
- }
- } else
- // Wrong State
- } else
- // Missing State
- } else {
- // Step 1. Authorization Code request
- $_SESSION['state'] = $state;
- 'response_type' => 'code',
- 'client_id' => $client_id,
- 'scope' => 'openid profile',
- 'state' => $state,
- );
- }
- } else {
- // Authorization error
- }
Notons que, dans cet exemple, nous avons intégré la clé publique dans le code. Une alternative consiste à se la procurer auprès d’AuthSD, voyez : API OpenId Connect : Point d’extrémité d’informations sur les clefs (Keys Endpoint). Mais la meilleure pratique est de valider le jeton par introspection.
Lancer le script : https://oa.dnc.global/oidc/tests/te...
Lors de la demande de vos login et mot de passe, si vous ne voulez pas vous inscrire sur ce serveur en tant qu’utilisateur, vous pourrez utiliser les identifiants suivants :
E-mail or pseudo : bebert
Password : 012345678
Voici la page de login générée par le serveur OAuthSD :
A propos du scope sli : vous noterez que le contrôleur Authorize est appelé avec le scope sli, alors que ce n’est pas le cas dans l’exemple suivant. Cela permet d’illustrer le fonctionnement de la Connexion unique (Single Login In, SLI).
Deuxième version : Validation du JWT par Introspection
La vérification du jeton JWT est effectuée par la méthode décrite dans cet article : API Open ID Connect : Introspection (Introspection Endpoint).
PHP
- <?php
- /*
- testopenid4.php
- Verbose Test of OpenID Connect JWT Introspection
- This code is meant for testing, not for production !
- For the authentification step, if you don't want to create an account
- on OAuthSD, use this credentials :
- login = bebert
- password = 012345678
- Author :
- Bertrand Degoy https://degoy.com
- Credits :
- bschaffer https://github.com/bshaffer/oauth2-server-php
- Licence : MIT licence
- Copyright (c) 2016 - DnC
- */
- $client_id = 'testopenid4';
- $client_secret = 'thesecret';
- $authorization_endpoint = 'https://oa.dnc.global/authorize';
- $token_endpoint = 'https://oa.dnc.global/token';
- $introspection_endpoint = 'https://oa.dnc.global/introspect';
- $userinfo_endpoint = 'https://oa.dnc.global/userinfo';
- //*** End of configuration ***
- // Set session
- // Check state
- if ( $_GET['state'] == $_SESSION['state'] ) {
- // Step 2. Token request
- $code = $_GET['code'];
- 'grant_type' => 'authorization_code',
- 'code' => $code,
- );
- application/x-www-form-urlencoded'));
- //curl_setopt($h, CURLOPT_SSL_VERIFYPEER, false);
- $access_token = $res['access_token'];
- // Validate signed JWT token using introspection
- //* Post Methode
- 'token' => $res['id_token'],
- );
- application/x-www-form-urlencoded'));
- //*/
- if ( $jwt['active'] == 'true' ) {
- // If Token Response is valid goto step 3
- // Step 3. Get UserInfo
- /* Auth Header Methode
- $headr = array();
- $headr[] = 'Authorization: Bearer ' . $access_token;
- $h = curl_init();
- curl_setopt($h, CURLOPT_URL, $userinfo_endpoint);
- curl_setopt($h, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($h, CURLOPT_TIMEOUT, 10);
- curl_setopt($h, CURLOPT_HTTPHEADER, $headr);
- //curl_setopt($h, CURLOPT_SSL_VERIFYPEER, false);
- //*/
- //* Post Methode
- 'access_token' => $access_token,
- );
- application/x-www-form-urlencoded'));
- //*/
- // Check User ID
- if ( $jwt['sub'] == $res['sub'] ) {
- // Everithing Ok !
- echo "UserInfo Response:\n";
- } else
- // User of ID Token doesn't match UserInfo's one
- } else
- // Token request error
- . $res['error_description']);
- } else {
- // script error ?
- } else {
- // Curl error during UserInfo request
- }
- }
- } else
- // JWT is inactive
- } else
- // Invalid id_token
- } else {
- // script error ?
- } else {
- // Curl error during Introspection request
- }
- }
- } else {
- // Token request error
- . $res['error_description']);
- }
- } else {
- // script error ?
- } else {
- // Curl error during Token request
- }
- }
- } else
- // Wrong State
- } else
- // Missing State
- } else {
- // Step 1. Authorization Code request
- $_SESSION['state'] = $state;
- 'response_type' => 'code',
- 'client_id' => $client_id,
- 'scope' => 'openid profile sli',
- 'state' => $state,
- );
- }
- } else {
- // Authorization error
- }
- ?>
Lancer le script : https://oa.dnc.global/oidc/tests/te...