help: remove section about API accesses (now written online) (#75607)

This commit is contained in:
Frédéric Péters 2023-03-20 15:38:43 +01:00 committed by Gitea
parent 00222aae84
commit 42c904394f
2 changed files with 1 additions and 319 deletions

View File

@ -1,317 +0,0 @@
<page xmlns="http://projectmallard.org/1.0/"
type="topic" id="api-auth" xml:lang="fr">
<info>
<link type="guide" xref="index#api" />
<revision docversion="0.1" date="2013-01-04" status="draft"/>
<revision docversion="0.2" date="2015-12-18" status="draft"/>
<credit type="author">
<name>Frédéric Péters</name>
<email>fpeters@entrouvert.com</email>
</credit>
<desc>Accès aux API, identifiants et clé dutilisation, utilisateurs, signature, etc.</desc>
</info>
<title>Authentification</title>
<section>
<title>Gestion des accès aux API</title>
<p>
La création daccès aux API se fait dans lespace de paramétrage, dans la
section « Sécurité », en suivant le lien « Accès aux API ». Le bouton « Nouvel
accès aux API » permet dajouter un accès, et il faut indiquer :
</p>
<list>
<item><p>Nom : le nom choisi pour laccès, qui sera affiché dans la page des
accès ;</p></item>
<item><p>Description : pour se rappeler de lusage prévu pour cet
accès ;</p></item>
<item><p>Identifiant daccès : le nom de lutilisateur à utiliser pour
lauthentification HTTP Basic, ou le paramètre <code>orig</code> pour
lauthentification par signature ;</p></item>
<item><p>Clé daccès : le mot de passe pour lauthentification HTTP Basic de
cet utilisateur, ou la clé partagée à utiliser pour lauthentification par
signature ;</p></item>
<item><p>Rôles : liste des rôles automatiquement obtenus lorsque cet accès est
utilisé. Par exemple, sil sagit de permettre de lister des demandes dune
certaine démarche, il faut indiquer un rôle qui permet de voir les demandes.
Ce rôle est à déterminer selon le paramétrage du formulaire de la démarche
et/ou de son workflow.</p></item>
</list>
<note><p>Il est conseillé de créer des «rôles techniques» dédiés aux API. Ces
rôles ne sont jamais donnés à des utilisateurs de la plateforme, ils sont
utilisés uniquement dans le paramétrage des accès. Typiquement une démarche est
paramétrée pour quun certain rôle technique ait accès à ses demandes, et ce
même rôle est indiqué dans laccès aux API dédié.</p></note>
<section>
<title>Définitions de lusager concerné</title>
<p>
Si lauthentification utilisée passe par un accès aux API qui ne donne pas de
rôle spécifique, alors il faut indiquer dans la query-string un usager qui aura
les rôles nécessaires.
</p>
<p>
C'est aussi nécessaire pour les appels concernant un usager particulier, tel
que la récupération de la liste de ses formulaires en cours.
</p>
<p>Lusager est précisé en ajoutant dans la query string :</p>
<list>
<item><p>soit un paramètre <code>email</code> pour trouver lusager selon son
adresse électronique</p></item>
<item><p>soit un paramètre <code>NameID</code> pour trouver lusager selon son
NameID SAML.</p></item>
</list>
</section>
</section>
<section>
<title>Authentification simple HTTP Basic</title>
<p>
Pour accéder aux API avec lauthentification HTTP Basic classique, il faut
utiliser le nom dutilisateur (identifiant daccès) et le mot de passe (clé
daccès) de laccès configuré ci-dessus.
</p>
</section>
<section>
<title>Authentification par signature de lURL</title>
<p>
Un système dauthentification basé sur une signature ajoutée à la fin de lURL
est également disponible. Il peut être jugé plus sécurisé que
lauthentification HTTP Basic, par ailleurs il assure une protection plus
explicite contre le rejeu. Ce système est spécifique à Publik/w.c.s.
</p>
<section id="req-security-shared-secret">
<title>Signature des requêtes</title>
<p>
La signature dun appel aux API passe par une clé partagée à
configurer des deux cotés de la liaison, la signature est du type HMAC;
lalgorithme de hash à employer est passé en paramètre.
</p>
<note><p>En ce qui concerne lalgorithme de hash, il est préconisé dutiliser
SHA-256 par respect du <link
href="http://references.modernisation.gouv.fr/securite">Référentiel Général
de Sécurité (RGS)</link>.</p></note>
<p>
La signature est à calculer sur la query string encodée complète, en
enlevant les paramètres terminaux <code>algo</code>, <code>timestamp</code>,
<code>nonce</code>, <code>orig</code> et <code>signature</code> sils sont
présents.</p>
<p>La formule de calcul de la signature est la suivante :</p>
<code>
BASE64(HMAC-HASH(query_string+'algo=HASH&amp;timestamp=' + timestamp + '&amp;nonce=' + nonce '&amp;orig=" + orig, clé))
</code>
<list>
<item><p><code>timestamp</code> est la date dans la zone GMT au format ISO8601
en se limitant à la précision des secondes (ex : 2012-04-04T12:34:00Z),
</p></item>
<item><p><code>nonce</code> est un aléa, typiquement la réprésentation hexa
dun nombre pseudo-aléatoire de 128 bits,</p></item>
<item><p><code>orig</code> est une chaîne précisant lémetteur de la
requête,</p></item>
<item><p>algo est une chaîne représentant lalgorithme de hachage utilisé, sont
définis : sha1, sha256, sha512 pour les trois algorithmes correspondant.
Lutilisation dune valeur différente nest pas définie. Lalgorithme sha256
est préconisé.</p></item>
</list>
<p>
La query string définitive est ainsi :
</p>
<code>
<var>qs_initial</var>&amp;algo=<var>algo</var>&amp;timestamp=<var>timestamp</var>&amp;nonce=<var>nonce</var>&amp;orig=<var>orig</var>&amp;signature=<var>signature</var>
</code>
</section>
<section>
<title>Configuration des clés partagées</title>
<p>
La définition des clés se fait lors de la création des accès aux API (voir
plus haut). Lors de la création d'un nouvel accès, lidentifiant d'accès
correspond au «orig» et la clé d'accès est la clé de signature. Les rôles sont
ceux qui seront obtenus lors de lusage de laccès.
</p>
<p>
Les clés partagées peuvent aussi être définies dans le fichier
<code>site-options.cfg</code>, dans une section <code>[api-secrets]</code>, par
exemple :
</p>
<code>
[api-secrets]
intranet = 12345
</code>
</section>
<section>
<title>Exemples d'implémentation de lalgorithme de signature</title>
<p>
Voici des exemples de code pour créer des URLs signées selon lalgorithme
expliqué ci-dessus.
</p>
<listing>
<title>Python</title>
<code mime="text/x-python">
#! /usr/bin/env python3
import base64
import datetime
import hashlib
import hmac
import random
import urllib.parse
def sign_url(url, key, algo='sha256', orig=None, timestamp=None, nonce=None):
parsed = urllib.parse.urlparse(url)
new_query = sign_query(parsed.query, key, algo, orig, timestamp, nonce)
return urllib.parse.urlunparse(parsed[:4] + (new_query,) + parsed[5:])
def sign_query(query, key, algo='sha256', orig=None, timestamp=None, nonce=None):
if timestamp is None:
timestamp = datetime.datetime.utcnow()
timestamp = timestamp.strftime('%Y-%m-%dT%H:%M:%SZ')
if nonce is None:
nonce = hex(random.getrandbits(128))[2:].rstrip('L')
new_query = query
if new_query:
new_query += '&amp;'
new_query += urllib.parse.urlencode((('algo', algo), ('timestamp', timestamp), ('nonce', nonce)))
if orig is not None:
new_query += '&amp;' + urllib.parse.urlencode({'orig': orig})
signature = base64.b64encode(sign_string(new_query, key, algo=algo))
new_query += '&amp;' + urllib.parse.urlencode({'signature': signature})
return new_query
def sign_string(s, key, algo='sha256', timedelta=30):
if not isinstance(key, bytes):
key = key.encode('utf-8')
if not isinstance(s, bytes):
s = s.encode('utf-8')
digestmod = getattr(hashlib, algo)
hash = hmac.HMAC(key, digestmod=digestmod, msg=s)
return hash.digest()
# usage:
url = sign_url('https://www.example.net/uri/?arg=val&amp;arg2=val2', 'user-key', orig='user')
</code>
</listing>
<listing>
<title>PHP</title>
<code mime="application/x-php">
&lt;?php
function sign_url(string $url, string $orig, string $key) {
$parsed_url = parse_url($url);
$timestamp = gmstrftime("%Y-%m-%dT%H:%M:%SZ");
$nonce = bin2hex(random_bytes(16));
$new_query = '';
if (isset($parsed_url['query'])) {
$new_query .= $parsed_url['query'] . '&amp;';
}
$new_query .= http_build_query(array(
'algo' => 'sha256',
'timestamp' => $timestamp,
'nonce' => $nonce,
'orig' => $orig));
$signature = base64_encode(hash_hmac('sha256', $new_query, $key, $raw_output = true));
$new_query .= '&amp;' . http_build_query(array('signature' => $signature));
$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
$host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
$port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
$user = isset($parsed_url['user']) ? $parsed_url['user'] : '';
$pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
$pass = ($user || $pass) ? "$pass@" : '';
$path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
$fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
return "$scheme$user$pass$host$port$path?$new_query$fragment";
}
# usage:
url = sign_url("http://www.example.net/uri/?arg=val&amp;arg2=val2", "user", "user-key");
?&gt;
</code>
</listing>
<listing>
<title>Shell (bash)</title>
<code mime="application/x-shellscript">
#!/bin/bash
url="http://www.example.net/uri/?arg=val&amp;arg2=val2"
orig="user"
key="user-key"
function rawurlencode() {
local string="${1}"
local strlen=${#string}
local encoded=""
local pos c o
for ((pos=0; pos&lt;strlen; pos++)); do
c=${string:$pos:1}
case "$c" in
[-_.~a-zA-Z0-9] ) o="${c}" ;;
* ) printf -v o '%%%02x' "'$c"
esac
encoded+="${o}"
done
echo "${encoded}"
}
now=$(date -u +%FT%TZ);
nonce=$(od -N16 -txL /dev/urandom | cut -c8- | tr -d " ")
qs="algo=sha256&amp;timestamp=$now&amp;nonce=$nonce&amp;orig=$orig"
sig=$(rawurlencode $(echo -n "$qs" | openssl dgst -binary -sha256 -hmac "$key" | base64))
signed="${url}?$qs&amp;signature=$sig"
echo "$signed"
</code>
</listing>
</section>
</section>
</page>

View File

@ -181,8 +181,7 @@ comme un commentaire ou une erreur lors de lappel dun <em>web service</em>
<note>
<p>
Il est bien sûr nécessaire de disposer des autorisations nécessaires pour
accéder ainsi aux données dun formulaire. (cf <link
xref="api-auth"/> pour les explications sur le sujet)
accéder ainsi aux données dun formulaire.
</p>
</note>