Le diagramme ci-contre donne une idée simplifiée de la suite des échanges entre les 3 pôles d’un flux de type Serveur à serveur.
Cliquez sur l’image pour l’agrandir
<clear1>
Ce flux n’identifie pas l’utilisateur final, qui n’entre pas en ligne de compte. Il est donc utile pour effectuer des tâches requérant un accès de l’application à des ressources protégées hors du contrôle de l’utilisateur final.
Du côté du client
Voici un exemple en PHP pour SPIP 3.1 :
SPIP
/**
* Interface avec OAuthSD, Flux d'autorisation de serveur à serveur
* (Client Credentials Grant).
* Cette fonction interroge une API protégée et retourne le résultat au format JSON.
* Si l'API refuse l'accès, une nouvelle demande de jeton est lancée automatiquement.
*
* @param mixed $request : URI de l'appel à l'API REST
* @return mixed string, bool : Résultat de la requête au format JSON ou false en
* cas de refus d'accès.
*
* Auteur: B.Degoy DnC https://degoy.com/#dnc_conteneur_contact
* licence GNU/GPL v3
*
*/
function ProtectedApi_GET_auto( $request ) {
$session_name = session_name();
if ( empty($session_name) ) {
session_name('PHPSESSID');
}
session_start();
include_spip('inc/headers');
include_spip('inc/distant');
if ( isset($_GET['token']) ) $token = $_GET['token'];
if ( !$token ) $token = $_SESSION['oauth_access_token'];
if ( !empty($token) ) {
// Interroger la ressource protégée
$request_response = recuperer_url($request . "&token=$token");
if ( (int)$request_response['status'] == 200 ) {
// Ok
return $request_response['page'];
} elseif ( (int)$request_response['status'] == 401
OR (int)$request_response['status'] == 403 ) {
// Pas le droit d'accéder à cette ressource.
// Commencer par vérifier le jeton
$url = "http://oa.dnc.global/oauth/resource.php?access_token=" . $token;
$resource_response = recuperer_url($url);
$status = (int)$resource_response['status'];
$page = json_decode($resource_response['page'], true);
$error = $page['error'];
$error_description = $page['error_description'];
switch( $status ) {
case 200 :
// Si le jeton était valide, ne pas boucler!
return false;
break;
default :
// Demander un nouveau jeton et recommencer
unset($_SESSION['oauth_access_token']);
return _replay( $request );
break;
}
return false;
}
} else {
// Demander un nouveau jeton et recommencer
return _replay( $request );
}
}
function _replay( $request ) {
if ( $token = GetToken() ) {
$_SESSION['oauth_access_token'] = $token;
$_GET['token'] = $token;
ProtectedApi_GET_auto( $request );
} else return false;
}
/**
* Demander un nouveau jeton d'accès au serveur OAuth
* Flux Client Credentials Grant
*
* Auteur: B.Degoy DnC https://degoy.com/#dnc_conteneur_contact
* licence GNU/GPL v3
*
*/
function GetToken() {
// Interroger Token
$jeton = '';
$url = 'http://oa.dnc.global/token.php';
$options = array(
'method' => 'POST',
'datas' => array(
'grant_type' => 'client_credentials',
'client_id' => 'radar',
'client_secret' => '01fc4587ab1c23ff456e448dab18327a',
)
);
$res = recuperer_url( $url, $options );
$page = json_decode($res['page'], true);
$token = $page['access_token'];
return ( (!empty($token))? $token : false );
}
L’utilisation de la fonction est très simple.
La fonction retourne un objet JSON représentant la réponse, que l’on peut facilement transformer en Array PHP :
PHP
// Le nom de l'application cliente
define ( 'APPNAME', 'radar' );
// La requete
$req = "http://chemindeleau.com/?page=gis.json&pt=1";
echo '<h3>Résultat de : ' . $req . '</h3><br/>';
$api_result = ProtectedApi_GET_auto( $req );
if ( $api_result == false ) {
$api_result = "Erreur !";
} else {
echo '<pre>';
print_r( json_decode( $api_result, true ));
echo '</pre>';
}Du côté du serveur de ressource
Voici un exemple de serveur de ressource simple :
SPIP
#CACHE{2}
[(#REM)
Liste de Tagazd en JSON.
Nécessite les plugins geobase et gis.
Exemple d'appel:
http://xxx.com/?page=gis.json&pt=nn
où nn est l'id du point dans la table gis.
Copyright (c) 2001-2016
Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James
Copyright(c) 2013-2016 DnC
Auteur: B.Degoy DnC https://degoy.com/#dnc_conteneur_contact
Licence GNU/GPL v3
]
<?php
function oauth_authorize($accesstoken) {
if ( !empty( $accesstoken ) ) {
// Interroger OAuth Server by DnC
include_spip('inc/distant');
// Vérifier le jeton d'accès (access token)
$url = "https://oa.dnc.global/oauth/resource.php?access_token=" . $accesstoken;
$res = recuperer_url($url);
if ( (int)$res['status'] === 200 ) {
return true ;
}
}
return false;
}
if ( !(bool)@oauth_authorize(_request('token')) ) {
header("HTTP/1.0 401 Unauthorized");
die();
}
// Si le jeton est valide, demander à SPIP d'émettre le contenu au format JSON :
?>
#HTTP_HEADER{Content-Type: application/json; charset=#CHARSET}
[<BOUCLE_docp(DOCUMENTS){gis}{', '}{distancefrom #ENV{pt}, <=, 100}{extension IN png,jpg,gif,html}{par distance}{0,#ENV{limit,100}}>
[(#ARRAY{
id,#ID_GIS,
titre,#TITRE,
distance,[(#DISTANCE|format_kmm)],
quadrant,[(#ENV{pt,1}|quadrant{#ID_GIS})],
lat,#LAT,
lon,#LON,
url,#URL_SITE_SPIP/?page=photo&id_document=#ID_DOCUMENT,
}|json_encode)]
</BOUCLE_docp>]La première partie du code en PHP valide le jeton d’accès auprès du serveur OAuthSD. En cas d’échec, l’exécution est interrompue et le serveur retourne le code HTTP 401 (Non autorisé) et un contenu vide.
Dans la deuxième partie "écrite en SPIP", vous remarquerez comme SPIP permet de générer facilement toute sortes de contenus à partir de données diverses. Nous avons ici une jointure entre des documents et des points géographiques retournée au format application/json.
OpenID Connect OAuth Server dédié
Plus de sécurité et de confidentialité avec un serveur d’authentification indépendant
