Connexion sans login/mdp depuis une application externe

Si vous souhaitez utiliser ce type de connexion (via Iframe) sous navigateur Chromium (Chrome et dérivés), votre installation Open-Capture doit être sécurisée (HTTPS)

Dans certains cas, vous pouvez avoir besoin d'accéder à Open-Capture sans passer par une authentification (de la même manière qu'un SSO). Cela sera possible via la génération d'un token JWT par votre application dans laquelle vous souhaitez intégrer Open-Capture.

Pour commencer, il vous faudra récupérer la clé secrète de votre instance d'Open-Capture, générée de manière aléatoire lors de l'installation. Cette dernière est située dans le dossier custom de votre instance, dans le sous dossier config.

/var/www/html/opencapture/custom/edissyum/config/secret_key

Il vous suffira ensuite de générer le token à l'aide de cette clé secrète ainsi que du username de l'utilisateur (pour cela, veillez bien à ce que les username Open-Capture et de l'application externe soient similaires). Soit via l'utilisation du LDAP, soit à la main en étant très vigilant). Vous retrouverez ci-dessous un exemple d'une fonction générant le token en Python, JavaScript ainsi qu'en PHP.

Par défaut les tokens ont une durée de validité d'une journée (1440 minutes)

import jwt
from datetime import datetime, timedelta

def encode_token(user_id, secret_key):
    try:
        payload = {
            'exp': datetime.utcnow() + timedelta(minutes=1440, seconds=0),
            'iat': datetime.utcnow(),
            'sub': user_id
        }
        return jwt.encode(
            payload,
            secret_key,
            algorithm='HS512'
        )
    except Exception as _e:
        return str(_e)

Il ne vous restera plus qu'à envoyer token dans la source de votre iframe, qui sera lu par Open-Capture pour procéder à la connexion automatique. Vous retrouverez ci-dessous un exemple simple d'une page HTML, gérant l'authentification par token dans une iframe. Les seules choses à modifier de votre côté sont les variables url, secretKey, userId ainsi que route.

Dans l'exemple ci-dessous, nous allons nous connecter avec l'utilisateur admin et allons accéder aux lots du module Verifier.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
    <body>
        <iframe id="iframe" src='' style="width: 100%; height: 100vh"></iframe>
    </body>
    <footer>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js" type="text/javascript"></script>
        <script>
            function base64url(source) {
                let encodedSource = CryptoJS.enc.Base64.stringify(source);
                encodedSource = encodedSource.replace(/=+$/, '');
                encodedSource = encodedSource.replace(/\+/g, '-');
                encodedSource = encodedSource.replace(/\//g, '_');
                return encodedSource;
            }

            function generate_token(user_id, secret_key) {
                const header = {
                    "alg": "HS512",
                    "typ": "JWT"
                };
                const stringifiedHeader = CryptoJS.enc.Utf8.parse(JSON.stringify(header));
                const encodedHeader = base64url(stringifiedHeader);
                const expDate = moment().add(1440, 'minutes').unix();
                const data = {
                    'exp': expDate,
                    'iat': moment().unix(),
                    "sub": user_id
                };

                const stringifiedData = CryptoJS.enc.Utf8.parse(JSON.stringify(data));
                const encodedData = base64url(stringifiedData);
                const token = encodedHeader + "." + encodedData;
                let signature = CryptoJS.HmacSHA512(token, secret_key);
                signature = base64url(signature);
                return token + "." + signature;
            }
            const openCaptureUrl = 'http://localhost/opencapture/edissyum/';
            const userId = 'admin';
            const route = '/verifier/list';
            const secretKey = '';
            const token = generate_token(userId, secretKey);
            document.getElementById('iframe').setAttribute("src", openCaptureUrl + "/dist/#/" + route + "/?id=token&token=" + token);
        </script>
    </footer>
</html>

Pour plus de sécurité il est recommandé de générer le token coté serveur afin d'éviter d'exposer la clé secrète.

Last updated