đSSO Authelia
Authelia est un serveur dâauthentification et dâautorisation open source fournissant une authentification Ă deux facteurs et une authentification unique (SSO) pour vos applications via un portail Web. Authelia se place devant votre reverse proxy (Nginx, Traefik, Caddy) et intercepte les requĂȘtes pour vĂ©rifier lâauthentification.
SSO Authelia
Site web officiel : https://www.authelia.com/
- Open source
- SSO
- Authentification 2F avec Yubikey
- OTP basé sur le temps avec Google Authenticator
- Prend en charge LDAP
- Prend en charge Active Directory
- Fonctionne avec les proxys inverses
- Notifications push avec duo
- Bloquer les attaques de force brute
- VĂ©rification dâidentitĂ©
- Une meilleure gestion des mots de passe
- Flux de travail flexible
- UI intuitif
Autres liens
- Authelia : 2FA et SSO Auto-HĂ©bergĂ©s en 13 Ătapes [2026]
- Authelia : SSO et 2FA pour services self-hosted
- Configurer auth ZeroTrust HTTP (Authelia & Nginx)
Prérequis et liens
Un serveur debian + nginx
Installation binaire
Installation binaire
1
2
3
4
5
6
7
8
9
10
11
# Téléchargement
wget https://github.com/authelia/authelia/releases/download/v4.39.20/authelia-v4.39.20-linux-amd64.tar.gz
tar xzvf authelia-v4.39.20-linux-amd64.tar.gz
# Mise Ă jour binaire
sudo systemctl stop authelia.service
sudo cp authelia /usr/bin/authelia
sudo systemctl start authelia.service
# Effacer
rm authelia*
# version
authelia -v # authelia version v4.39.20
Structure
1
2
3
4
5
6
/etc/authelia/
âââ authelia.log
âââ configuration.yml
# droits
ls -ld /etc/authelia/
drwxr-xr-x 2 authelia authelia 4096 8 août 14:33 /etc/authelia/
Configurer Authelia
Configuration authelia sur serveur cwwk rnmkcy.eu 192.168.0.205
- Serveur: 127.0.0.1:9091
- Authentification: TOTP + Webauthnn
- Notification: SMTP
- Gestion utilisateurs: LLDAP ou fichier
- Stockage: Base mysql ou Sqlite3
Gestion utilisateurs
LLDAP est utilisé pour la gestion utilisateur
Fichier base utilisateurs
1
sudo -u authelia nano /opt/authelia/config/users_database.yml
Format yaml:
1
2
3
4
5
6
7
8
9
users:
mathys:
disabled: false
displayname: "Mathys"
password: "$argon2id$v=19$m=65536,t=3,p=4$..." # voir étape suivante
email: "mathys@verycloud.fr"
groups:
- "admin"
- "users"
Générer le hash du mot de passe
1
sudo authelia crypto hash generate argon2
Entrez votre mot de passe. Copiez le hash résultant et collez-le dans users_database.yml.
Stockage
Stockage géré par une base mariadb (mysl)
Créer une base mariadb
Host : 127.0.0.1
Base : authelia
Utilisateur : authelia
Mot de passe : Mot_de_passe_base_authelia
En ligne de commande
1
sudo mariadb -e "create database authelia; grant all privileges on authelia.* to authelia@'localhost' identified by 'Mot_de_passe_base_authelia'; flush privileges;"
WebAuthn
ParamĂštre user_verification :
- discouraged : Le client sera dĂ©couragĂ© de demander une vĂ©rification Ă lâutilisateur.
- preferred : Le client, sâil est conforme, demandera Ă lâutilisateur une vĂ©rification si lâappareil la prend en charge.
- required : Le client demandera Ă lâutilisateur une vĂ©rification ou Ă©chouera si lâappareil ne prend pas en charge la vĂ©rification.
attestation_conveyance_preference:
- none : Le client recevra lâinstruction de ne pas effectuer de transfert de propriĂ©tĂ©.
- indirect : Le client reçoit lâinstruction dâeffectuer le transfert de propriĂ©tĂ©, mais il peut choisir la maniĂšre de le faire, y compris en utilisant une AC dâanonymisation tierce.
- direct : Le client recevra lâinstruction dâeffectuer le transfert avec une dĂ©claration dâattestation directement signĂ©e par le dispositif.
Authelia (configuration.yml)
Configuration /etc/authelia/configuration.yml (épurée)
Etendre Réduire...
###############################################################################
# Authelia Configuration #
###############################################################################
# Rappel : certains secrets sont fournis via le fichier d'environnement
# /etc/authelia/authelia.env (JWT reset, session, LDAP, MySQL, SMTP, OIDC hmac).
# Ne pas committer ce fichier d'env dans un dépÎt public.
theme: dark
##
## Identity Validation Configuration
##
identity_validation:
reset_password:
jwt_secret: 'CHANGEZ_MOI'
server:
address: 'tcp://127.0.0.1:9091/'
disable_healthcheck: false
tls:
key: ""
certificate: ""
endpoints:
enable_pprof: false
enable_expvars: false
log:
level: warn
file_path: '/etc/authelia/authelia.log'
totp:
issuer: rnmkcy.eu
period: 30
skew: 1
allowed_digits:
- 6
webauthn:
disable: false
enable_passkey_login: false
display_name: 'Authelia'
attestation_conveyance_preference: 'indirect'
timeout: '60 seconds'
filtering:
permitted_aaguids: []
prohibited_aaguids: []
prohibit_backup_eligibility: false
selection_criteria:
attachment: ''
discoverability: 'preferred'
user_verification: 'preferred'
metadata:
enabled: false
validate_trust_anchor: true
validate_entry: true
validate_entry_permit_zero_aaguid: false
validate_status: true
validate_status_permitted: []
validate_status_prohibited:
- 'REVOKED'
- 'USER_KEY_PHYSICAL_COMPROMISE'
- 'USER_KEY_REMOTE_COMPROMISE'
- 'USER_VERIFICATION_BYPASS'
- 'ATTESTATION_KEY_COMPROMISE'
authentication_backend:
password_reset:
disable: false
refresh_interval: 1m
ldap:
implementation: lldap
address: ldap://127.0.0.1:3890
timeout: 5s
start_tls: false
base_dn: dc=rnmkcy,dc=eu
additional_users_dn: ou=people
users_filter: "(&({username_attribute}={input})(objectClass=person))"
additional_groups_dn: ou=groups
groups_filter: "(member={dn})"
user: uid=admin,ou=people,dc=rnmkcy,dc=eu
password: 'CHANGEZ_MOI'
attributes:
mail: 'mail'
username: 'uid'
group_name: 'cn'
display_name: 'displayName'
access_control:
default_policy: deny
networks:
- name: internal
networks:
- '192.168.0.0/24'
- '192.168.10.0/24'
rules:
- domain:
- 'auth.rnmkcy.eu'
policy: bypass
- domain:
- 'site.rnmkcy.eu'
policy: two_factor
session:
secret: 'CHANGEZ_MOI'
name: 'authelia_session'
same_site: 'lax'
inactivity: '45m'
expiration: '12h'
remember_me: '7d'
cookies:
- domain: 'rnmkcy.eu'
authelia_url: 'https://auth.rnmkcy.eu'
default_redirection_url: 'https://rnmkcy.eu'
name: 'authelia_session'
same_site: 'lax'
inactivity: '45m'
expiration: '12h'
remember_me: '7d'
redis:
host: localhost
port: 6379
#password: 'CHANGEZ_MOI'
database_index: 0
maximum_active_connections: 10
minimum_idle_connections: 0
regulation:
max_retries: 3
find_time: 5m
ban_time: 15m
storage:
encryption_key: 'CHANGEZ_MOI'
mysql:
address: '127.0.0.1:3306'
database: authelia
username: authelia
password: 'CHANGEZ_MOI'
notifier:
disable_startup_check: false
smtp:
address: 'smtp://yannig.net:587'
timeout: '5s'
username: 'yann@yannig.net'
password: 'CHANGEZ_MOI'
sender: 'yann@yannig.net'
identifier: 'yannig.net'
subject: '[Authelia] {title}'
startup_check_address: 'yann@yannig.net'
disable_require_tls: false
disable_starttls: false
disable_html_emails: false
identity_providers:
oidc:
hmac_secret: 'CHANGEZ_MOI'
jwks:
- key_id: 'authelia'
algorithm: 'RS256'
use: 'sig'
certificate_chain: |
-----BEGIN CERTIFICATE-----
MIIDFzCCAf+gAwIBAgIQKh+loa2
-----END CERTIFICATE-----
key: |
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQE
-----END PRIVATE KEY-----
enable_client_debug_messages: false
minimum_parameter_entropy: 8
enforce_pkce: 'public_clients_only'
enable_pkce_plain_challenge: false
enable_jwt_access_token_stateless_introspection: false
discovery_signed_response_alg: 'none'
discovery_signed_response_key_id: ''
require_pushed_authorization_requests: false
lifespans:
access_token: '1h'
authorize_code: '1m'
id_token: '1h'
refresh_token: '90m'
cors:
endpoints:
- authorization
- token
- revocation
- introspection
allowed_origins:
- 'https://immich.rnmkcy.eu'
allowed_origins_from_client_redirect_uris: false
clients:
- client_id: immich
client_name: Immich OIDC
# Le client_secret reste dans le YAML (hashed), pas dans l'env.
client_secret: '$pbkdf2-sha512$310000$/4LKM4la/dw013yHgOr1Ug$vUvPxJY6AKKBaV7SaIC1b/BEtKPnqfhz3MKnGSQFOsTNUFspDnBC/qfBfXx0LgUZdcpZ63gbOEQU8Qz0UKB.KQ'
public: false
authorization_policy: 'two_factor'
redirect_uris:
- 'https://immich.rnmkcy.eu/auth/login'
- 'https://immich.rnmkcy.eu/user-settings'
- 'app.immich:///oauth-callback'
scopes:
- 'openid'
- 'profile'
- 'email'
userinfo_signed_response_alg: 'none'
token_endpoint_auth_method: 'client_secret_post'
- client_id: 'forgejo'
client_name: 'Forgejo'
client_secret: '$pbkdf2-sha512$310000$rhOo4zW8lnTSJmPxzizI4w$8CiHPKElYYhOIFSYyDYE34ToBY.c.iwF5sAmgMm.dnnNLKq9uVAECeb2pk6s12cKosnWoLtnhKvjoLLyZLgvPQ'
public: false
authorization_policy: 'two_factor'
require_pkce: true
pkce_challenge_method: 'S256'
redirect_uris:
- 'https://forgejo.rnmkcy.eu/user/oauth2/authelia/callback'
scopes:
- 'openid'
- 'email'
- 'profile'
- 'groups'
response_types:
- 'code'
grant_types:
- 'authorization_code'
access_token_signed_response_alg: 'none'
userinfo_signed_response_alg: 'none'
token_endpoint_auth_method: 'client_secret_post'
- client_id: 'portainer'
client_name: 'Portainer'
client_secret: '$pbkdf2-sha512$310000$2nPrEUGwRI64lVZAMs.bsw$JPMilMlHhYxMwfbU1dcL1JChJ5o.Uk8iEI297DMgXrAV2wVP/njCBgCfjQBvqtLbM9TNVEStJMKNbc3O99vA0Q'
public: false
authorization_policy: 'two_factor'
require_pkce: false
pkce_challenge_method: ''
redirect_uris:
- 'https://portainer.home.arpa'
scopes:
- 'openid'
- 'profile'
- 'groups'
- 'email'
response_types:
- 'code'
grant_types:
- 'authorization_code'
access_token_signed_response_alg: 'none'
userinfo_signed_response_alg: 'none'
token_endpoint_auth_method: 'client_secret_post'
- client_id: 'technitium'
client_name: 'technitium OIDC'
client_secret: '$pbkdf2-sha512$310000$IxPfnOlpxWpaikXDw.qTSg$1d6xUB2YxVzwg.d7rNF.JhESblbfSgM.nuQJWrZgyj21IGKC7LCDHtMnuLvzNmuGy9Hr3INsL02tCbqXCwHOgQ'
public: false
authorization_policy: 'two_factor'
redirect_uris:
- 'https://dns.rnmkcy.eu/sso/callback'
scopes:
- 'openid'
- 'profile'
- 'email'
userinfo_signed_response_alg: 'none'
token_endpoint_auth_method: 'client_secret_post'Vérifier la configuration en mode su
1
sudo authelia validate-config --config /etc/authelia/configuration.yml
Activation service authelia
Lancer, activer et vérifier
1
2
sudo systemctl enable authelia --now
sudo journalctl -u authelia
1
oct. 30 18:56:33 alder systemd[1]: Started authelia.service - Authelia authentication and authorization server.
auth.rnmkcy.eu
Comme Authelia affiche une page de connexion/authentification, il doit ĂȘtre exĂ©cutĂ© sur un canal de transport cryptĂ© pour Ă©viter les attaques de lâhomme du milieu (MITM).
Il ne dĂ©marrera pas tant que ce canal nâaura pas Ă©tĂ© correctement configurĂ©.
Comme dâhabitude avec HTTPS, pour dĂ©marrer une connexion TLS, vous avez besoin dâun certificat. La solution la plus simple est dâutiliser Letâs Encrypt ou ZeroSSL avec son outil certbot pour automatiser la rĂ©cupĂ©ration et le renouvellement des certificats. Il ne sâagit pas dâun tutoriel sur la mise en place du HTTPS, donc je liste les Ă©tapes Ă rĂ©aliser avec un reverse proxy NGINX, nâhĂ©sitez pas Ă personnaliser si vous utilisez un autre reverse proxy pour le HTTPS.
Proxy nginx
Le fichier /etc/nginx/conf.d/auth.rnmkcy.eu.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
server {
listen 80;
server_name auth.rnmkcy.eu;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name auth.rnmkcy.eu;
# Configuration TLS moderne (ciphers, protocoles, etc.)
include /etc/nginx/conf.d/ssl-modern.inc;
# Cache de session TLS
ssl_session_cache shared:SSL:2m;
# Sécurité HTTP strict transport (HSTS)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# Durcissement des en-tĂȘtes sĂ©curitĂ©
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
location / {
# Authelia écoute en HTTP sur localhost
proxy_pass http://127.0.0.1:9091/;
# HTTP/1.1 vers le backend + pas de Connection: close
proxy_http_version 1.1;
proxy_set_header Connection "";
# Contexte client original
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Contexte de la requĂȘte originale
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Uri $request_uri;
proxy_set_header X-Forwarded-Method $request_method;
# URL complĂšte dâorigine (utile pour redirections / logs)
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
# Timeouts raisonnables pour le backend
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
}
PuisâŻ:
1
2
sudo nginx -t
sudo systemctl reload nginx
Ensuite, pointer le navigateur sur https://auth.rnmkcy.eu pour vĂ©rifier que le portail Authelia sâaffiche correctement.
Utilisation SSO - Modifier application
Authelia affiche une page de connexion/authentification, il doit ĂȘtre exĂ©cutĂ© sur un canal de transport https
Lâapplication doit ĂȘtre adaptĂ©e pour traiter avec un serveur dâauthentification externe.
Lorsque Authelia a validĂ© lâutilisateur, il redirige vers votre application.
Cette redirection contient des en-tĂȘtes spĂ©cifiques que votre application doit traiter pour procĂ©der Ă sa crĂ©ation de session habituelle (typiquement, votre application Ă©mettra son Set-Cookie ou une requĂȘte de stockage local ou un jeton JWT ou âŠ).
Il sâagit simplement de contourner la page de connexion.
Nginx snippets
Création dossier snippets
1
sudo mkdir -p /etc/nginx/snippets
Les fichiers de configuration nginx
Le premier extrait est une route interne
/autheliaqui nâest pas accessible depuis lâinternet, qui est utilisĂ©e dans vos applications pour affirmer que la session Authelia est valide.
Snippet authelia.conf
1
sudo nano /etc/nginx/snippets/authelia.conf
Contenu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Internal Authelia verify endpoint
location = /authelia {
# accessible uniquement en interne (subrequests) â requĂȘtes externes â 404
internal;
# n'envoie pas le corps de la requĂȘte au backend (gain d'efficacitĂ©)
proxy_pass_request_body off;
# neutralise Content-Length (évite d'envoyer une taille quand pas de body)
proxy_set_header Content-Length "";
# transmet l'hĂŽte original ($host) au backend
proxy_set_header Host $host;
# URL complÚte d'origine (schéma://host + request_uri)
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
# indique le protocole d'origine (http ou https)
proxy_set_header X-Forwarded-Proto $scheme;
# transmet l'hÎte d'origine (inclut le port si présent)
proxy_set_header X-Forwarded-Host $http_host;
# transmet l'URI d'origine (chemin + query string)
proxy_set_header X-Forwarded-Uri $request_uri;
# ajoute l'IP cliente à X-Forwarded-For (conserve proxys intermédiaires)
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# envoie l'IP source de la connexion nginx (IP client directe)
proxy_set_header X-Real-IP $remote_addr;
# redirige la sous-requĂȘte vers l'API interne Authelia /api/verify sur localhost:9091
proxy_pass http://127.0.0.1:9091/api/verify;
# délai maximum pour lire la réponse du backend = 10 secondes
proxy_read_timeout 10s;
}
Vous aurez aussi besoin dâun snippet pour lâauthentification (interne) elle-mĂȘme, donc sauvegardez ce snippet sous
/etc/nginx/snippets/auth.conf:
Typiquement, ce snippets fait en sorte que NGINX gĂ©nĂšre une requĂȘte vers lâemplacement interne/autheliaĂ chaque fois quâune requĂȘte dâutilisateur est faite vers votre application. Il vĂ©rifie le code de rĂ©sultat HTTP de la requĂȘte interne. Si câest 200, la requĂȘte de lâutilisateur est acceptĂ©e, sinon il est redirigĂ© vers la page de login Authelia.
Snippet auth.conf
1
sudo nano /etc/nginx/snippets/auth.conf
Contenu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Protect with Authelia
# effectue une sous-requĂȘte interne vers /authelia pour vĂ©rifier l'accĂšs
auth_request /authelia;
# stocke l'URL complÚte demandée (schéma://host+URI) dans la variable $target_url
auth_request_set $target_url $scheme://$http_host$request_uri;
# récupÚre le header Remote-User renvoyé par Authelia (nom d'utilisateur authentifié)
auth_request_set $user $upstream_http_remote_user;
# récupÚre le header Remote-Groups renvoyé par Authelia (groupes / rÎles)
auth_request_set $groups $upstream_http_remote_groups;
# transmet l'utilisateur authentifié au backend en tant que header Remote-User
proxy_set_header Remote-User $user;
# transmet les groupes de l'utilisateur au backend en tant que header Remote-Groups
proxy_set_header Remote-Groups $groups;
# en cas de 401 (non autorisé) renvoie une redirection 302 vers le portail d'authentification,
# avec ?rd=<URL d'origine> pour que l'IDP puisse rediriger l'utilisateur vers la ressource demandée aprÚs login
error_page 401 =302 https://auth.rnmkcy.eu/?rd=$target_url;
Exemple de protection
Enfin, dans la description de votre site dâapplication, vous devrez inclure ces extraits. Le fichier
authelia.confva dans le bloc serveur et le fichierauth.confva dans nâimporte quel endroit que vous voulez protĂ©ger.
Vous Ă©viterez typiquement de protĂ©ger les actifs statiques et les redirections, puisquâil nây a pas dâintĂ©rĂȘt Ă vĂ©rifier lâauthentification pour ceux-ci.
Authentification Totp Yubikeys Passkeys
Totp
On va ajouter une authentification TOTP
Se connecter sur authelia et cliquer sur authelia

Mot de passe usage unique

Saisir le code ID

Suivre la procédure

Si vous nâavez pas google authenticator
Prendre une photo avec lâappareil android pour dĂ©coder

Cliquer sur le lien pour copier le code
Copier le contenu de secret dans le totp de cockpit keepassxc

Cliquer sur suivant et décocher qrcode

Vérification fonctionnement avec un code généré par cockpi keepassxc

Si tout est OK

et un message de confirmation

Yubikeys WebAuthn
Configuration authelia prérequise
1
2
3
4
5
6
7
8
9
10
11
12
13
14
## WebAuthn Actif
##
webauthn:
## Désactiver Webauthn avec true.
disable: false
# l'application web utilisant la double authentification
access_control:
default_policy: deny
rules:
- domain:
- "site.rnmkcy.eu"
policy: two_factor
Clé yubikey insérée dans un port USB
Se connecter sur le lien https://auth.rnmkcy.eu avec Firefox
Utilisateur yann (exemple)
Saisir utilisateur âyannâ et son mot de passe
Saisir le code ID

Une nouvelle fenĂȘtre sâouvre


La clé est enregistrée

et un message de confirmation

Se connecter de nouveau Ă cockpit
Page de connexion auhelia

Validation par clé

Page authentification cockpit

Ajouter une autre clé yubikey
La seconde clé est enregistrée

et un message de confirmation

Utilisateur yano (exemple)
Lâapplication KeepassXC et son extension firefox sont actives
Ouvrir le portail authentification https://auth.rnmkcy.eu et saisir yano et son mot de passe
Ajouter la mĂ©thode dâauthentification âWebAuthnâ

Renseigner libellé et suivant

Un popup Keepassxc apparaĂźt

Cliquer sur Enregistrer comme nouveau

Un identifiant webauthn a été ajouté
Sur le navigateur, il faut mémoriser et autoriser Keepassxc

Ce popup nâapparaĂźt quâa la premiĂšre connexion yano sur le portail
Ouvrir le portail authentification https://auth.rnmkcy.eu

Passkeys KeepassXC
Si lâapplication KeepassXC et son extension firefox sont actifs il est possible de crĂ©er une passkey
Authelia fournisseur OIDC
La configuration Authelia est définie dans un fichier de
configuration.yml. Ce fichier permet de dĂ©finir les paramĂštres de configuration OIDC nĂ©cessaires, tels quâun fournisseur et un client.
Création certificat fournisseur
En consultant la documentation publique OIDC dâAuthelia , la configuration contient plusieurs paramĂštres nĂ©cessitant soit une valeur secrĂšte, soit un certificat.
Ces Ă©lĂ©ments doivent ĂȘtre gĂ©nĂ©rĂ©s de maniĂšre sĂ©curisĂ©e avant dâajuster la configuration.
Passer en mode su, puis se rendre dans le répertoire authelia
1
2
sudo -s # ou su -
cd /etc/authelia
Authelia
identity_providers: oidcutilise un certificat (clé privée) pour la directivekeyet une chaßne de certificats (clé publique) pour la directivecertificate_chain.
Vous pouvez générer les deux via la commande suivante :
1
authelia crypto certificate rsa generate --common-name auth.rnmkcy.eu && cat public.crt && cat private.pem
â ïž Veuillez ajuster le nom commun du certificat Ă votre FQDN dâAuthelia
Création fournisseur OIDC
Une fois le certificat RSA et le secret client créés de maniĂšre sĂ©curisĂ©e, nous pouvons commencer Ă ajuster le fichier de configuration dâAuthelia. Nous ajouterons un fournisseur dâidentitĂ© en insĂ©rant nos secrets et informations de certificat auto-gĂ©nĂ©rĂ©s.
Mettez ce qui suit Ă la fin de votre configuration Authelia :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
identity_providers:
oidc:
hmac_secret: 'my-secure-hmac-secret-key-to-change' # Commande: openssl rand -base64 48
jwks:
- key_id: 'authelia'
algorithm: 'RS256'
use: 'sig'
certificate_chain: |
-----BEGIN CERTIFICATE-----
<PASTE-HERE-YOUR-PUBLIC-KEY-DATA> # /etc/authelia/public.crt sur une ligne
-----END CERTIFICATE-----
key: |
-----BEGIN PRIVATE KEY-----
<PASTE-HERE-YOUR-PRIVATE-KEY-DATA> # /etc/authelia/private.pem sur une ligne
-----END PRIVATE KEY-----
enable_client_debug_messages: false
minimum_parameter_entropy: 8
enforce_pkce: 'public_clients_only'
enable_pkce_plain_challenge: false
enable_jwt_access_token_stateless_introspection: false
discovery_signed_response_alg: 'none'
discovery_signed_response_key_id: ''
require_pushed_authorization_requests: false
lifespans:
access_token: '1h'
authorize_code: '1m'
id_token: '1h'
refresh_token: '90m'
cors:
endpoints:
- 'authorization'
- 'token'
- 'revocation'
- 'introspection'
allowed_origins:
- 'https://immich.rnmkcy.eu'
allowed_origins_from_client_redirect_uris: false
Vérifier la configuration en mode su
1
sudo authelia validate-config --config /etc/authelia/configuration.yml
Vous devez obtenir le message suivant, si tout est correct
Configuration parsed and loaded successfully without errors.
Authentification(autres modes)
A 2 facteurs (INACTIVE)
- Se connecter avec son compte forgejo
- Accédez aux ParamÚtres utilisateur en cliquant sur Configuration

Sécurité passkey (INACTIVE)
Une clĂ© dâaccĂšs (en anglais, passkey) est une preuve numĂ©rique utilisĂ©e comme mĂ©thode dâauthentification pour un site web ou une application. La clĂ© dâaccĂšs est un type dâauthentification sans mot de passe, promu par le World Wide Web Consortium et lâAlliance FIDO.(Citation WikipĂ©dia)
Contrairement Ă un mot de passe, les passkeys ne peuvent pas ĂȘtre partagĂ©s, mĂ©morisĂ©s ou Ă©crits. Ils sont donc beaucoup moins vulnĂ©rables aux types dâattaques qui visent gĂ©nĂ©ralement les systĂšmes basĂ©s sur des mots de passe.
Si vous utilisez KeepassXC avec lâextension navigateur KeePassXC-Browser vous pouvez ajouter la sĂ©curitĂ© par clĂ© âpasskeyâ
Ajouter une clé de sécurité
ParamÚtres utilisateur -> Sécurité

- Pseudonyme: forgepass
- Cliquer sur âAjouter une clĂ© de sĂ©curitĂ©â
- Une fenĂȘtre KeepassXC sâouvre
KeepassXC: Cliquer sur Enregistrer ,clĂ© dâaccĂšs est créée

- La clé forgepass est générée sur Forgejo

Connexion depuis Firefox (extension keepassxc-browser)
Ouvrir le lien https://forgejo.rnmkcy.eu
Notre clé de sécurité est une PassKey KeepassXC

Sur la fenĂȘtre popup KeepassXC, cliquer sur Authentifier

A la premiĂšre connexion, il faut cocher âMĂ©moriserâ et âAutoriser les Ă©lĂ©ments choisisâ

Authentification LLDAP (INACTIVE)
Un serveur LLDAP est disponible localement: http://127.0.0.1:3890
Sélectionner LDAP (via BindDN)
- HĂŽte: Le ip/hostname de votre serveur LLDAP,
127.0.0.1 - Port: Port de votre serveur lldap
3890 - Bind DN:
uid=admin,ou=people,dc=rnmkcy,dc=eu - Bind Mot de passe admin lldap
- Base de recherche utilisateur:
ou=people,dc=rnmkcy,dc=eu - Filtre utilisateur: Si vous voulez que tous les utilisateurs puissent se connecter, utilisez
(&(objectClass=person)(|(uid=%[1]s)(mail=%[1]s)))Lâutilisateur âyannâ est dans le groupe âgitâ (&(|(objectclass=inetOrgPerson))(|(memberof=cn=git,ou=groups,dc=rnmkcy,dc=eu)))
Pour se connecter, ils peuvent utiliser leur adresse e-mail ou leur nom dâutilisateur.
Si vous voulez seulement des membres un groupe spĂ©cifique pour ĂȘtre en mesure de se connecter, dans ce cas le groupe git_user, utiliser
(&(memberof=cn=git_user,ou=groups,dc=rnmkcy,dc=eu)(|(uid=%[1]s)(mail=%[1]s)))
Pour plus dâinformations sur le filtre, voir: https://docs.gitea.io/en-us/authentication/#ldap-via-binddn
-
Filtre Admin (facultatif): Utiliser
(memberof=cn=lldap_admin,ou=groups,dc=rnmkcy,dc=eu)si vous voulez que les administrateurs lldap deviennent des administrateurs Gitea. Laissez vide sinon.

- Attribut nom dâutilisateur:
uid - Attribut Prénom:
givenName - Attribut Nom de famille :
sn - Email Attribute:
mail - Avatar Attribute:
jpegPhoto
Authelia analyses
OK â avec ces tables, le moyen le plus fiable pour rĂ©pondre âqui est authentifiĂ© et avec quelle mĂ©thodeâ est de sâappuyer sur :
authentication_logs(pour ce qui sâest rĂ©ellement passĂ© pendant le login et la mĂ©thode/challenge)- et, si besoin,
identity_verification/one_time_code/totp_history/webauthn_credentials(pour recouper â2FA effectuĂ©eâ vs âchallenge Ă©misâ).
Chercher la méthode directement dans authentication_logs
Fais dâabord ces inspections (sans donnĂ©es sensibles) :
1
SHOW COLUMNS FROM authentication_logs;
1
2
3
4
5
6
7
8
9
10
11
12
13
+----------------+--------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| time | timestamp | NO | MUL | current_timestamp() | |
| successful | tinyint(1) | NO | | NULL | |
| banned | tinyint(1) | NO | | 0 | |
| username | varchar(100) | NO | | NULL | |
| auth_type | varchar(8) | NO | | 1FA | |
| remote_ip | varchar(39) | YES | | NULL | |
| request_uri | text | YES | | NULL | |
| request_method | varchar(8) | NO | | | |
+----------------+--------------+------+-----+---------------------+----------------+
Puis lance une requĂȘte âquick winâ :
1
2
3
4
5
SELECT
*
FROM authentication_logs
ORDER BY id DESC
LIMIT 50;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
+-----+---------------------+------------+--------+------------+-----------+---------------------------------------+-------------------------------+----------------+
| id | time | successful | banned | username | auth_type | remote_ip | request_uri | request_method |
+-----+---------------------+------------+--------+------------+-----------+---------------------------------------+-------------------------------+----------------+
| 121 | 2026-07-24 09:04:49 | 1 | 0 | yano | WebAuthn | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 120 | 2026-07-24 09:04:11 | 1 | 0 | yano | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 119 | 2026-07-24 09:03:41 | 1 | 0 | yano | WebAuthn | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 118 | 2026-07-24 09:03:27 | 1 | 0 | yano | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 117 | 2026-07-24 08:56:59 | 1 | 0 | yano | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 116 | 2026-07-24 08:38:08 | 1 | 0 | yano | WebAuthn | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 115 | 2026-07-24 08:32:39 | 1 | 0 | yano | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 114 | 2026-07-24 08:31:58 | 1 | 0 | yano | WebAuthn | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 113 | 2026-07-24 08:06:53 | 1 | 0 | yano | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 112 | 2026-07-24 07:42:55 | 1 | 0 | yann | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 111 | 2026-07-24 07:39:06 | 1 | 0 | yano | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 110 | 2026-07-23 16:41:31 | 1 | 0 | yann | TOTP | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 109 | 2026-07-23 16:41:28 | 1 | 0 | yann | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 108 | 2026-07-22 18:24:59 | 1 | 0 | technitium | TOTP | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 107 | 2026-07-22 18:24:56 | 1 | 0 | technitium | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 106 | 2026-07-22 18:09:14 | 1 | 0 | technitium | TOTP | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 105 | 2026-07-22 18:09:04 | 1 | 0 | technitium | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 104 | 2026-07-22 18:00:58 | 1 | 0 | yann | TOTP | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 103 | 2026-07-22 18:00:43 | 1 | 0 | yann | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 102 | 2026-07-22 17:56:51 | 1 | 0 | technitium | TOTP | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 101 | 2026-07-22 17:55:35 | 1 | 0 | technitium | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 100 | 2026-07-22 17:37:37 | 1 | 0 | technitium | TOTP | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 99 | 2026-07-22 17:14:55 | 1 | 0 | technitium | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 98 | 2026-07-22 17:10:11 | 1 | 0 | technitium | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 97 | 2026-07-22 17:06:23 | 1 | 0 | yann | TOTP | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 96 | 2026-07-22 17:06:12 | 1 | 0 | yann | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 95 | 2026-07-22 08:01:34 | 1 | 0 | portainer | TOTP | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 94 | 2026-07-22 08:01:31 | 1 | 0 | portainer | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 93 | 2026-07-21 17:05:59 | 1 | 0 | portainer | TOTP | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 92 | 2026-07-21 17:05:55 | 1 | 0 | portainer | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 91 | 2026-07-20 06:33:59 | 1 | 0 | yann | TOTP | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | https://site.rnmkcy.eu/notes/ | |
| 90 | 2026-07-20 06:33:57 | 1 | 0 | yann | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | https://site.rnmkcy.eu/notes/ | |
| 89 | 2026-07-19 20:13:48 | 1 | 0 | portainer | TOTP | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 88 | 2026-07-19 20:13:45 | 1 | 0 | portainer | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 87 | 2026-07-18 08:28:17 | 1 | 0 | portainer | TOTP | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 86 | 2026-07-18 08:28:14 | 1 | 0 | portainer | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 85 | 2026-07-18 07:34:19 | 1 | 0 | portainer | TOTP | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 84 | 2026-07-18 07:34:16 | 1 | 0 | portainer | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 83 | 2026-07-16 09:57:54 | 1 | 0 | yann | TOTP | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | https://site.rnmkcy.eu/notes/ | |
| 82 | 2026-07-16 09:57:51 | 1 | 0 | yann | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | https://site.rnmkcy.eu/notes/ | |
| 81 | 2026-07-11 07:16:35 | 1 | 0 | portainer | TOTP | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 80 | 2026-07-11 07:16:32 | 1 | 0 | portainer | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 79 | 2026-07-07 18:38:58 | 1 | 0 | portainer | TOTP | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 78 | 2026-07-07 18:38:56 | 1 | 0 | portainer | 1FA | 2a01:e0a:95a:e2f0:c16f:1f56:c4fd:7dcb | | |
| 77 | 2026-07-06 08:44:57 | 1 | 0 | yann | TOTP | 2a01:e0a:95a:e2f0:d357:db0:cdb0:70ab | https://site.rnmkcy.eu/notes/ | |
| 76 | 2026-07-06 08:44:54 | 1 | 0 | yann | 1FA | 2a01:e0a:95a:e2f0:d357:db0:cdb0:70ab | https://site.rnmkcy.eu/notes/ | |
| 75 | 2026-07-06 07:13:14 | 1 | 0 | portainer | TOTP | 2a01:e0a:95a:e2f0:d357:db0:cdb0:70ab | | |
| 74 | 2026-07-06 07:13:12 | 1 | 0 | portainer | 1FA | 2a01:e0a:95a:e2f0:d357:db0:cdb0:70ab | | |
| 73 | 2026-07-03 20:01:33 | 1 | 0 | yann | TOTP | 2a01:e0a:95a:e2f0:d357:db0:cdb0:70ab | https://site.rnmkcy.eu/ | |
| 72 | 2026-07-03 20:01:30 | 1 | 0 | yann | 1FA | 2a01:e0a:95a:e2f0:d357:db0:cdb0:70ab | https://site.rnmkcy.eu/ | |
+-----+---------------------+------------+--------+------------+-----------+---------------------------------------+-------------------------------+----------------+
En regardant les colonnes retournées, cherche des champs du style (les noms exacts varient) :
- Les champs concernés:
usernameetauth_type
1
2
3
4
5
6
7
8
SELECT
username,
auth_type,
COUNT(*) AS nb
FROM authentication_logs
WHERE auth_type IN ('TOTP','1FA','WebAuthn')
GROUP BY username, auth_type
ORDER BY nb DESC;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
+---------------------------+-----------+----+
| username | auth_type | nb |
+---------------------------+-----------+----+
| yann | 1FA | 23 |
| portainer | 1FA | 22 |
| yann | TOTP | 21 |
| portainer | TOTP | 20 |
| yano | 1FA | 6 |
| technitium | 1FA | 5 |
| admin@yannig.net | 1FA | 4 |
| yano | WebAuthn | 4 |
| forgeadmin | 1FA | 4 |
| technitium | TOTP | 4 |
| | 1FA | 2 |
| forgeadmin | TOTP | 2 |
| immich | 1FA | 1 |
| admin | 1FA | 1 |
| stalwart-admin | 1FA | 1 |
| stalwart-admin@yannig.net | 1FA | 1 |
+---------------------------+-----------+----+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
MariaDB [authelia]> SELECT * FROM identity_verification;
Empty set (0,001 sec)
MariaDB [authelia]> SHOW COLUMNS FROM oauth2_openid_connect_session;
+--------------------+--------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+---------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| challenge_id | char(36) | NO | MUL | NULL | |
| request_id | varchar(40) | NO | MUL | NULL | |
| client_id | varchar(255) | NO | MUL | NULL | |
| signature | varchar(255) | NO | | NULL | |
| subject | char(36) | NO | MUL | NULL | |
| requested_at | timestamp | NO | | current_timestamp() | |
| requested_scopes | text | NO | | NULL | |
| granted_scopes | text | NO | | NULL | |
| requested_audience | text | YES | | NULL | |
| granted_audience | text | YES | | NULL | |
| active | tinyint(1) | NO | | 0 | |
| revoked | tinyint(1) | NO | | 0 | |
| form_data | text | NO | | NULL | |
| session_data | blob | NO | | NULL | |
+--------------------+--------------+------+-----+---------------------+----------------+
15 rows in set (0,002 sec)
MariaDB [authelia]> SHOW COLUMNS FROM totp_configurations;
+--------------+--------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| created_at | timestamp | NO | | current_timestamp() | |
| last_used_at | timestamp | YES | | NULL | |
| username | varchar(100) | NO | UNI | NULL | |
| issuer | varchar(100) | YES | | NULL | |
| algorithm | varchar(6) | NO | | SHA1 | |
| digits | int(11) | NO | | 6 | |
| period | int(11) | NO | | 30 | |
| secret | blob | NO | | NULL | |
+--------------+--------------+------+-----+---------------------+----------------+
9 rows in set (0,002 sec)
MariaDB [authelia]> SHOW COLUMNS FROM webauthn_users;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| rpid | varchar(512) | NO | MUL | NULL | |
| username | varchar(100) | NO | | NULL | |
| userid | char(64) | NO | | NULL | |
+----------+--------------+------+-----+---------+----------------+
4 rows in set (0,001 sec)
MariaDB [authelia]> SHOW COLUMNS FROM webauthn_credentials;
+--------------------+--------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+---------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| created_at | timestamp | NO | | current_timestamp() | |
| last_used_at | timestamp | YES | | NULL | |
| rpid | varchar(512) | NO | MUL | NULL | |
| username | varchar(100) | NO | | NULL | |
| description | varchar(30) | NO | | NULL | |
| kid | varchar(512) | NO | UNI | NULL | |
| aaguid | char(36) | YES | | NULL | |
| attestation_format | varchar(32) | YES | | NULL | |
| attachment | varchar(64) | NO | | NULL | |
| transport | varchar(64) | YES | | | |
| sign_count | int(11) | YES | | 0 | |
| clone_warning | tinyint(1) | NO | | 0 | |
| legacy | tinyint(1) | NO | | 0 | |
| discoverable | tinyint(1) | NO | | NULL | |
| present | tinyint(1) | NO | | 0 | |
| verified | tinyint(1) | NO | | 0 | |
| backup_eligible | tinyint(1) | NO | | 0 | |
| backup_state | tinyint(1) | NO | | 0 | |
| public_key | blob | NO | | NULL | |
| attestation | blob | YES | | NULL | |
| attestation_type | varchar(32) | NO | | | |
+--------------------+--------------+------+-----+---------------------+----------------+
22 rows in set (0,001 sec)
MariaDB [authelia]> SHOW COLUMNS FROM user_opaque_identifier;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| service | varchar(20) | NO | MUL | NULL | |
| sector_id | varchar(255) | NO | | NULL | |
| username | varchar(100) | NO | | NULL | |
| identifier | char(36) | NO | UNI | NULL | |
+------------+--------------+------+-----+---------+----------------+
5 rows in set (0,001 sec)
MariaDB [authelia]> SHOW COLUMNS FROM user_preferences;
+----------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(100) | NO | UNI | NULL | |
| second_factor_method | varchar(11) | NO | | NULL | |
+----------------------+--------------+------+-----+---------+----------------+
Utilisateurs + auth âpar dĂ©fautâ (1FA/TOTP/WEBAUTHN)
Si ton objectif est âtous les utilisateurs rĂ©fĂ©rencĂ©sâ + leur auth âpar dĂ©fautâ, pars de user_preferences et fais un LEFT JOIN vers user_opaque_identifier :
1
2
3
4
5
6
7
8
9
10
11
12
SELECT
up.username,
CASE
WHEN LOWER(up.second_factor_method) = 'totp' THEN 'TOTP'
WHEN LOWER(up.second_factor_method) = 'webauthn' THEN 'WEBAUTHN'
ELSE '1FA'
END AS default_auth_type,
uoi.identifier AS user_identifier_opaque_identifier
FROM user_preferences up
LEFT JOIN user_opaque_identifier uoi
ON uoi.username = up.username
ORDER BY up.username;
1
2
3
4
5
6
7
8
9
10
11
12
13
+---------------------------+-------------------+--------------------------------------+
| username | default_auth_type | user_identifier_opaque_identifier |
+---------------------------+-------------------+--------------------------------------+
| admin@yannig.net | TOTP | NULL |
| forgeadmin | TOTP | cdf46cc8-df28-490c-9846-98a040a2f0bd |
| immich | TOTP | NULL |
| portainer | TOTP | a8f08772-1502-425d-8998-c71d45068713 |
| stalwart-admin | TOTP | NULL |
| stalwart-admin@yannig.net | TOTP | NULL |
| technitium | TOTP | c45a31c9-255d-4e36-b639-edb6ba75b0aa |
| yann | TOTP | 846ee529-5388-425c-853a-10bcc0db22c5 |
| yano | WEBAUTHN | NULL |
+---------------------------+-------------------+--------------------------------------+
Exemple pour yano
1
2
3
4
5
6
7
8
9
10
11
12
SELECT
up.username,
CASE
WHEN LOWER(up.second_factor_method) = 'totp' THEN 'TOTP'
WHEN LOWER(up.second_factor_method) = 'webauthn' THEN 'WEBAUTHN'
ELSE '1FA'
END AS default_auth_type,
uoi.identifier AS user_identifier_opaque_identifier
FROM user_preferences up
LEFT JOIN user_opaque_identifier uoi
ON uoi.username = up.username
WHERE up.username = 'yano';
1
2
3
4
5
+----------+-------------------+-----------------------------------+
| username | default_auth_type | user_identifier_opaque_identifier |
+----------+-------------------+-----------------------------------+
| yano | WEBAUTHN | NULL |
+----------+-------------------+-----------------------------------+
Le champ user_identifier_opaque_identifier est utilisé uniquement pour les connexions OIDC openid
1
SELECT * FROM user_opaque_identifier;
1
2
3
4
5
6
7
8
+----+---------+-----------+------------+--------------------------------------+
| id | service | sector_id | username | identifier |
+----+---------+-----------+------------+--------------------------------------+
| 1 | openid | | portainer | a8f08772-1502-425d-8998-c71d45068713 |
| 2 | openid | | forgeadmin | cdf46cc8-df28-490c-9846-98a040a2f0bd |
| 3 | openid | | technitium | c45a31c9-255d-4e36-b639-edb6ba75b0aa |
| 4 | openid | | yann | 846ee529-5388-425c-853a-10bcc0db22c5 |
+----+---------+-----------+------------+--------------------------------------+
La consĂ©quence pour ta question (âutilisateurs rĂ©fĂ©rencĂ©s + 1FA/TOTP/WEBAUTHNâ) :
user_preferenceste donne bien la méthode par défaut (2FA) pouryano.- mais
user_opaque_identifierne te sert pas pour lister âtous les utilisateurs LDAPâ, uniquement ceux qui ont un contexte OIDC openid pour lequel Authelia a gĂ©nĂ©rĂ© unidentifier.
Lister tous les utilisateurs ârĂ©fĂ©rencĂ©sâ cĂŽtĂ© prefs (par dĂ©faut)
1
2
3
4
5
6
7
8
9
SELECT
up.username,
CASE
WHEN LOWER(up.second_factor_method) = 'totp' THEN 'TOTP'
WHEN LOWER(up.second_factor_method) = 'webauthn' THEN 'WEBAUTHN'
ELSE '1FA'
END AS default_auth_type
FROM user_preferences up
ORDER BY up.username;
1
2
3
4
5
6
7
8
9
10
11
12
13
+---------------------------+-------------------+
| username | default_auth_type |
+---------------------------+-------------------+
| admin@yannig.net | TOTP |
| forgeadmin | TOTP |
| immich | TOTP |
| portainer | TOTP |
| stalwart-admin | TOTP |
| stalwart-admin@yannig.net | TOTP |
| technitium | TOTP |
| yann | TOTP |
| yano | WEBAUTHN |
+---------------------------+-------------------+
Oui. Pour avoir un âschĂ©ma avec les liens entre tablesâ (FK / dĂ©pendances), il faut essentiellement :
1) exporter la structure (tables + colonnes + indexes)
2) extraire les relations (FOREIGN KEY) et, si Authelia nâen met pas beaucoup, dĂ©duire des âliensâ via colonnes communes (ex: username, id, *_id, challenge_id, etc.)
Commencer par voir sâil y a des clĂ©s Ă©trangĂšres (FOREIGN KEY)
1
2
3
4
5
6
7
8
9
10
SELECT
TABLE_NAME,
CONSTRAINT_NAME,
COLUMN_NAME,
REFERENCED_TABLE_NAME,
REFERENCED_COLUMN_NAME
FROM information_schema.KEY_COLUMN_USAGE
WHERE TABLE_SCHEMA='authelia'
AND REFERENCED_TABLE_NAME IS NOT NULL
ORDER BY TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
+-----------------------------------+-----------------------------------------------------+------------------+---------------------------------+------------------------+
| TABLE_NAME | CONSTRAINT_NAME | COLUMN_NAME | REFERENCED_TABLE_NAME | REFERENCED_COLUMN_NAME |
+-----------------------------------+-----------------------------------------------------+------------------+---------------------------------+------------------------+
| oauth2_access_token_session | oauth2_access_token_session_challenge_id_fkey | challenge_id | oauth2_consent_session | challenge_id |
| oauth2_access_token_session | oauth2_access_token_session_subject_fkey | subject | user_opaque_identifier | identifier |
| oauth2_authorization_code_session | oauth2_authorization_code_session_challenge_id_fkey | challenge_id | oauth2_consent_session | challenge_id |
| oauth2_authorization_code_session | oauth2_authorization_code_session_subject_fkey | subject | user_opaque_identifier | identifier |
| oauth2_consent_preconfiguration | oauth2_consent_preconfiguration_subject_fkey | subject | user_opaque_identifier | identifier |
| oauth2_consent_session | oauth2_consent_session_preconfiguration_fkey | preconfiguration | oauth2_consent_preconfiguration | id |
| oauth2_consent_session | oauth2_consent_session_subject_fkey | subject | user_opaque_identifier | identifier |
| oauth2_device_code_session | oauth2_device_code_session_challenge_id_fkey | challenge_id | oauth2_consent_session | challenge_id |
| oauth2_device_code_session | oauth2_device_code_session_subject_fkey | subject | user_opaque_identifier | identifier |
| oauth2_openid_connect_session | oauth2_openid_connect_session_challenge_id_fkey | challenge_id | oauth2_consent_session | challenge_id |
| oauth2_openid_connect_session | oauth2_openid_connect_session_subject_fkey | subject | user_opaque_identifier | identifier |
| oauth2_pkce_request_session | oauth2_pkce_request_session_challenge_id_fkey | challenge_id | oauth2_consent_session | challenge_id |
| oauth2_pkce_request_session | oauth2_pkce_request_session_subject_fkey | subject | user_opaque_identifier | identifier |
| oauth2_refresh_token_session | oauth2_refresh_token_session_challenge_id_fkey | challenge_id | oauth2_consent_session | challenge_id |
| oauth2_refresh_token_session | oauth2_refresh_token_session_subject_fkey | subject | user_opaque_identifier | identifier |
+-----------------------------------+-----------------------------------------------------+------------------+---------------------------------+------------------------+
erDiagram
user_opaque_identifier {
int id PK
char identifier UK
}
oauth2_consent_preconfiguration {
int id PK
char subject FK
}
oauth2_consent_session {
int id PK
char challenge_id UK
char subject FK
int preconfiguration FK
}
oauth2_access_token_session {
int id PK
char challenge_id FK
char subject FK
}
oauth2_authorization_code_session {
int id PK
char challenge_id FK
char subject FK
}
oauth2_device_code_session {
int id PK
char challenge_id FK
char subject FK
}
oauth2_openid_connect_session {
int id PK
char challenge_id FK
char subject FK
}
oauth2_pkce_request_session {
int id PK
char challenge_id FK
char subject FK
}
oauth2_refresh_token_session {
int id PK
char challenge_id FK
char subject FK
}
user_opaque_identifier ||--o{ oauth2_access_token_session : "identifier = subject"
user_opaque_identifier ||--o{ oauth2_authorization_code_session : "identifier = subject"
user_opaque_identifier ||--o{ oauth2_consent_preconfiguration : "identifier = subject"
user_opaque_identifier ||--o{ oauth2_consent_session : "identifier = subject"
user_opaque_identifier ||--o{ oauth2_device_code_session : "identifier = subject"
user_opaque_identifier ||--o{ oauth2_openid_connect_session : "identifier = subject"
user_opaque_identifier ||--o{ oauth2_pkce_request_session : "identifier = subject"
user_opaque_identifier ||--o{ oauth2_refresh_token_session : "identifier = subject"
oauth2_consent_session ||--o{ oauth2_access_token_session : "challenge_id"
oauth2_consent_session ||--o{ oauth2_authorization_code_session : "challenge_id"
oauth2_consent_session ||--o{ oauth2_device_code_session : "challenge_id"
oauth2_consent_session ||--o{ oauth2_openid_connect_session : "challenge_id"
oauth2_consent_session ||--o{ oauth2_pkce_request_session : "challenge_id"
oauth2_consent_session ||--o{ oauth2_refresh_token_session : "challenge_id"
oauth2_consent_preconfiguration ||--o{ oauth2_consent_session : "id = preconfiguration"
Plus compacte
%%{init: { "theme": "base", "themeVariables": { "fontFamily": "monospace" }}}%%
flowchart LR
%% Columns: TABLE_NAME | CONSTRAINT_NAME | COLUMN_NAME | REFERENCED_TABLE_NAME | REFERENCED_COLUMN_NAME
oauth2_access_token_session:::t --> oauth2_consent_session:::t
oauth2_access_token_session:::t --> oauth2_consent_session:::t
oauth2_access_token_session:::t --> user_opaque_identifier:::t
oauth2_access_token_session:::t --> user_opaque_identifier:::t
oauth2_authorization_code_session:::t --> oauth2_consent_session:::t
oauth2_authorization_code_session:::t --> oauth2_consent_session:::t
oauth2_authorization_code_session:::t --> user_opaque_identifier:::t
oauth2_authorization_code_session:::t --> user_opaque_identifier:::t
oauth2_consent_preconfiguration:::t --> user_opaque_identifier:::t
oauth2_consent_session:::t --> oauth2_consent_preconfiguration:::t
oauth2_consent_session:::t --> user_opaque_identifier:::t
oauth2_device_code_session:::t --> oauth2_consent_session:::t
oauth2_device_code_session:::t --> oauth2_consent_session:::t
oauth2_device_code_session:::t --> user_opaque_identifier:::t
oauth2_device_code_session:::t --> user_opaque_identifier:::t
oauth2_openid_connect_session:::t --> oauth2_consent_session:::t
oauth2_openid_connect_session:::t --> oauth2_consent_session:::t
oauth2_openid_connect_session:::t --> user_opaque_identifier:::t
oauth2_openid_connect_session:::t --> user_opaque_identifier:::t
oauth2_pkce_request_session:::t --> oauth2_consent_session:::t
oauth2_pkce_request_session:::t --> oauth2_consent_session:::t
oauth2_pkce_request_session:::t --> user_opaque_identifier:::t
oauth2_pkce_request_session:::t --> user_opaque_identifier:::t
oauth2_refresh_token_session:::t --> oauth2_consent_session:::t
oauth2_refresh_token_session:::t --> oauth2_consent_session:::t
oauth2_refresh_token_session:::t --> user_opaque_identifier:::t
oauth2_refresh_token_session:::t --> user_opaque_identifier:::t
classDef t fill:#f7f7ff,stroke:#666,stroke-width:1px,rx:8,ry:8;
Annexe
ID client
Les utilisateurs peuvent facilement gĂ©nĂ©rer un identifiant/identifiant client en suivant le guide GĂ©nĂ©ration dâune chaĂźne alphanumĂ©rique alĂ©atoire
Par exemple, les utilisateurs peuvent exécuter la commande
1
authelia crypto rand --length 72 --charset rfc3986
pour générer un identifiant/identifiant client de 72 caractÚres qui est imprimé.
Cette commande aléatoire évite également les problÚmes avec une application client/partie de confiance codant correctement les caractÚres car elle utilise les caractÚres non réservés RFC3986 .
Si un jeu de caractĂšres diffĂ©rent est utilisĂ© et que la valeur est diffĂ©rente lors du codage de lâURL, il imprimera Ă©galement cette valeur sĂ©parĂ©ment.
Secret client
Les utilisateurs peuvent facilement gĂ©nĂ©rer un secret client en suivant le guide GĂ©nĂ©ration dâun hachage de mot de passe alĂ©atoire
Par exemple, les utilisateurs peuvent exécuter la commande
1
authelia crypto hash generate pbkdf2 --variant sha512 --random --random.length 72 --random.charset rfc3986
â ïž Veuillez noter le mot de passe en clair ainsi que le hachage $pbkdf2 du mot de passe pour une utilisation ultĂ©rieure.
pour Ă la fois gĂ©nĂ©rer un secret client de 72 caractĂšres qui est imprimĂ© et doit ĂȘtre utilisĂ© avec la partie utilisatrice et le hacher Ă lâaide de PBKDF2 qui peut ĂȘtre stockĂ© dans la configuration Authelia. Cette commande alĂ©atoire Ă©vite Ă©galement les problĂšmes avec une application client/partie de confiance codant correctement les caractĂšres car elle utilise les caractĂšres non rĂ©servĂ©s RFC3986 .
Si un jeu de caractĂšres diffĂ©rent est utilisĂ© et que la valeur est diffĂ©rente lors du codage de lâURL, il imprimera Ă©galement cette valeur sĂ©parĂ©ment.
Réglage des facteurs de travail
Lors du hachage des secrets du client, Authelia effectue lâopĂ©ration de hachage pour authentifier le client lors de la rĂ©ception des demandes. Cette opĂ©ration de hachage prend du temps, de par sa conception (la partie travail du facteur travail) pour empĂȘcher un attaquant de tenter dâobtenir le secret client. Le temps nĂ©cessaire dĂ©pend de votre matĂ©riel et du facteur de travail.
Si les opĂ©rations de votre client expirent, vous devrez peut-ĂȘtre rĂ©duire le facteur de travail Ă un niveau appropriĂ© pour votre client et les capacitĂ©s de votre matĂ©riel.
Pour tester la durée de différents facteurs de travail, vous pouvez la mesurer ainsi :
1
time authelia crypto hash generate pbkdf2 --variant sha512 --iterations 310000 --password insecure_password
Générer chaßne aléatoire
Generating a Random Alphanumeric String
Authelia. Le conteneur de docker Authelia ou binaire CLI peut ĂȘtre utilisĂ© pour gĂ©nĂ©rer une chaĂźne alphanumĂ©rique alĂ©atoire.
Utilisez le authelia crypto rand --helpcommander ou voir le guide de rĂ©fĂ©rence authelia crypto rand pour plus dâinformations sur toutes les options disponibles.
1
authelia crypto rand --length 64 --charset alphanumeric
OpenSSL. La commande openssl sur Linux peut ĂȘtre utilisĂ©e pour gĂ©nĂ©rer une chaĂźne alphanumĂ©rique alĂ©atoire:
1
openssl rand -hex 64
Linux de base. Les commandes Linux de base peuvent ĂȘtre utilisĂ©es pour gĂ©nĂ©rer une chaĂźne alphanumĂ©rique alĂ©atoire:
1
2
LENGTH=64
tr -cd '[:alnum:]' < /dev/urandom | fold -w "${LENGTH}" | head -n 1 | tr -d '\n' ; echo

















