# 3.13.8. Configuration de apache shiro

TODO: présentation de apache shiro, configuration, …

# 3.13.9. Présentation authentification via certificats

Afin de pouvoir authentifier des clients via des certificats valides il suffit de bien configurer shiro. Pour ce faire vitam utilise le fichier shiro.ini qui a la forme suivante.

    [main]
    x509 = fr.gouv.vitam.common.auth.web.filter.X509AuthenticationFilter
    x509.useHeader = false
    x509credentialsMatcher = fr.gouv.vitam.common.auth.core.authc.X509CredentialsSha256Matcher
    x509Realm = fr.gouv.vitam.common.auth.core.realm.X509KeystoreFileRealm
    x509Realm.grantedKeyStoreName = path/granted_certs.jks
    x509Realm.grantedKeyStorePassphrase = password
    x509Realm.trustedKeyStoreName = path/truststore.jks
    x509Realm.trustedKeyStorePassphrase = password
    x509Realm.credentialsMatcher = $x509credentialsMatcher
    securityManager.realm = $x509Realm
    securityManager.subjectDAO.sessionStorageEvaluator.sessionStorageEnabled = false
    [urls]
    /ingest-ext/v1/**= x509

# 3.13.10. Décryptage de shiro.ini

[main] Contient les déclaration de filters et classes comme par exemple X509AuthenticationFilter, X509CredentialsSha256Matcher, X509KeystoreFileReal, … La clé (x509, x509Realm) sont custom et on peut donner le nom qu’on veut, par contre securityManager est un mot clé shiro. La ligne securityManager.realm = $x509Realm passe à shiro le Realm qu’on veut utiliser, ceci dit, les clé custom peut être passé à shiro de la même façon.

[urls] Pour une url donnée on dit quel filter utiliser, exemple: /ingest-ext/v1/= x509 signifie que l’on veut utiliser le filter x509 pour toutes les urls de type /ingest-ext/v1/

# 3.13.11. Utilisation des certificats

Vitam a une implémentation de filter pour utiliser des certificats x509 afin d’authentifier des clients.

X509AuthenticationFilter (filter par defaut)

> - Activation du filter dans le fichier shiro.ini: x509 = fr.gouv.vitam.common.auth.web.filter.X509AuthenticationFilter

> - Ce filter récupère les certificats fournis dans la requête :

>   >     X509Certificate[] clientCertChain = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");

> - Si des certificats sont trouvé alors un token est crée qui sera passé à la méthode qui s’occupe d’authentifier un client.

>   >     new X509AuthenticationToken(clientCertChain, getHost(request));

> - X509AuthenticationFilter peut aussi authentifier via un certificat passé dans le header. La variable « useHeader » est égale à false par défaut. Donc cette option est désactivé par défaut. Si useHeader= true (qu’on peut spécifier dans shiro.ini: x509.useHeader = false dans l’exemple ci-dessus) et qu’aucun cetificat n’est fourni dans l’attribute de la requête javax.servlet.request.X509Certificate alors il bascule vers une authentification via le header. Le nom du header est X-SSL-CLIENT-CERT, et il doit avoir comme valeur un certificat valide au format pem. Le certificat pem est ensuite converti vers un X509Certificate qui sera utilisé pour créer le token d’authentification. Ci-dessous une snipet de code qui permets de récupérer la valeur du certificat depuis le header et le convertir au bon format.

> - Attention, jetty n’accepte pas les retour à la ligne dans le header, d’où la nécessité d’encoder le `pem` en base 64. X509AuthenticationFilter s’occupe de déterminer si le certificat passé dans le header est encodé ou non en base 64 et fera en sorte d’accepter même les certificats non encodés.

>   >     final HttpServletRequest httpRequest = (HttpServletRequest) request;
>   >     String pem = httpRequest.getHeader(X_SSL_CLIENT_CERT);
>   >     byte[] pemByte = null;
>   >     if (null != pem) {
>   >         try {
>   >             try {
>   >                 pemByte = Base64.getDecoder().decode(pem);
>   >             } catch (IllegalArgumentException ex) {
>   >                 // the pem is not base64 encoded
>   >                 pemByte = pem.getBytes();
>   >             }
>   >             final InputStream pemStream = new ByteArrayInputStream(pemByte);
>   >             final CertificateFactory cf = CertificateFactory.getInstance("X.509");
>   >             final X509Certificate cert = (X509Certificate) cf.generateCertificate(pemStream);
>   >             clientCertChain = new X509Certificate[] {cert};
>   >         } catch (Exception ce) {
>   >             throw new ShiroException(ce);
>   >         }
>   >     }

> - Il faut noter que l’authentification via un certificat passé dans le header n’est pas sécurisée (moins sécurisée que la solution via l’attribute de la requête). En effet, il peut y avoir une injection lors de l’acheminement de la requête depuis un client vers un serveur jetty. Nous recommendons donc l’utilisation de certificats dans l’attribute de la requête.