Passer au contenu principal

Jenkins OIDC, Gitea OIDC et Grafana SSO avec Casdoor : une connexion unique pour une stack DevOps auto-hébergée

· Lecture de 10 minutes
Yang Luo
Casdoor Maintainer

Chaque outil d'une stack DevOps auto-hébergée typique peut agir en tant que client OpenID Connect : Gitea et Argo CD prennent en charge nativement OIDC, Jenkins le fait via le plugin oic-auth, Grafana et Portainer via OAuth 2.0 générique, et MinIO, Harbor et GitLab via leurs paramètres OIDC. Pointez-les tous vers une seule instance Casdoor, attribuez à chaque outil sa propre application Casdoor, et placez vos utilisateurs dans des groupes Casdoor. Chaque outil lit alors la revendication groups et décide qui est administrateur. Cet article liste l'URL de callback, les clés de configuration et le mappage des groupes pour chaque outil, puis couvre les parties communes.

Aperçu de la stack​

Tous les chemins ci-dessous sont relatifs à l'URL publique de l'outil lui-même. Enregistrez-les dans Redirect URLs de l'application Casdoor correspondante.

AppProtocoleURL de callbackMappage groupe/rôle adminDoc Casdoor
GiteaOIDC (source d'authentification OAuth2)/user/oauth2/<source-name>/callbackOui : groupe admin, groupe restreint, mappage d'équipesGitea
JenkinsOIDC (plugin oic-auth)/securityRealm/finishLogin, déconnexion /OicLogoutOui : revendication groups plus sécurité basée sur MatrixJenkins (OIDC)
GrafanaOAuth 2.0 générique/login/generic_oauthOui : role_attribute_pathGrafana
Argo CDOIDC/auth/callback, CLI http://localhost:8085/auth/callbackOui : argocd-rbac-cmArgo CD
MinIOOIDCConsole /oauth_callbackPolitiques issues d'une revendication (claim_name)MinIO
PortainerOAuth 2.0 (Custom)L'URL de base de PortainerÉdition Business uniquementPortainer
HarborOIDC/c/oidc/callbackOui : OIDC Admin Groupaucune pour l'instant
GitLabOIDC (OmniAuth)/users/auth/openid_connect/callbackPremium et Ultimate : admin_groupsGitLab

Le document de découverte dont tout client OIDC a besoin est https://<casdoor-host>/.well-known/openid-configuration. Si vous n'avez jamais connecté un client OIDC à Casdoor auparavant, Connecter un client OIDC standard explique les endpoints.

Préparer Casdoor une fois​

Avant de toucher aux outils, configurez trois éléments dans Casdoor.

Groups. Créez des groupes tels que devops-admins et devops-users dans l'arborescence de l'organisation et ajoutez-y des utilisateurs. Voir Groups.

Token group format. Par défaut, la revendication groups nomme chaque groupe sous la forme <organization>/<group>. La plupart des outils comparent la revendication avec une chaîne simple que vous tapez, donc définissez Token group format dans l'onglet OIDC/OAuth de chaque application sur Name (group). La revendication contient alors devops-admins. Les options sont décrites dans Group format.

Token format. Gardez Token format sur JWT, la valeur par défaut. Dans ce format, le jeton ID contient groups, roles et tag. JWT-Empty et JWT-Standard excluent ces trois champs du jeton, et JWT-Custom ne les inclut que si vous les sélectionnez dans Token fields. La réponse /api/userinfo renvoie groups et les noms des rôles lorsque la portée profile est accordée, afin que les outils qui lisent userinfo puissent toujours les voir.

Les rôles fonctionnent aussi. Dans le format JWT, la revendication roles est un tableau d'objets de rôle, donc faites correspondre roles[*].name. Dans /api/userinfo, c'est un tableau simple de noms. Voir User roles.

Gitea​

Dans Site Administration, ajoutez une source d'authentification de type OAuth2 avec le fournisseur OpenID Connect, l'ID client et le secret, ainsi que l'URL de découverte Casdoor. Le nom que vous donnez à la source fait partie de l'URL de callback : une source nommée casdoor utilise https://gitea.example.com/user/oauth2/casdoor/callback.

Pour le mappage des groupes, remplissez Claim name providing group names avec groups, puis Group Claim value for administrator users avec devops-admins. Gitea dispose également de Group Claim value for restricted users et de Map claimed groups to Organization teams. La même source depuis la CLI :

gitea admin auth add-oauth \
--name casdoor \
--provider openidConnect \
--key <client-id> \
--secret <client-secret> \
--auto-discover-url https://door.example.com/.well-known/openid-configuration \
--group-claim-name groups \
--admin-group devops-admins

Jenkins​

Jenkins n'a pas de support OIDC natif. Installez le plugin OpenId Connect Authentication, choisissez-le comme realm de sécurité, et utilisez la configuration well-known. Le callback de connexion est /securityRealm/finishLogin et celui de déconnexion est /OicLogout ; ajoutez les deux dans Casdoor. Dans JCasC :

jenkins:
securityRealm:
oic:
serverConfiguration:
wellKnown:
wellKnownOpenIDConfigurationUrl: https://door.example.com/.well-known/openid-configuration
clientId: <client-id>
clientSecret: <client-secret>
userNameField: name
fullNameFieldName: displayName
emailFieldName: email
groupsFieldName: groups
logoutFromOpenidProvider: true
properties:
- "pkce"

Le plugin transmet uniquement les groupes à Jenkins. Les droits proviennent de la stratégie d'autorisation : avec la sécurité basée sur Matrix, chaque ligne du tableau est un utilisateur ou un groupe, donc ajoutez une ligne pour devops-admins et donnez-lui Overall/Administer. Choisir le plugin comme realm de sécurité désactive les autres méthodes de connexion, donc configurez la propriété escapeHatch du plugin (un nom d'utilisateur et un secret de secours) avant d'enregistrer. Casdoor possède également son propre plugin Jenkins, décrit dans Jenkins plugin, mais le plugin OIDC générique est celui supposé par cet article.

Grafana​

Grafana utilise OAuth générique. Son callback est /login/generic_oauth. La valeur par défaut de scopes dans Grafana est user:email, donc définissez explicitement les portées OIDC :

[auth.generic_oauth]
enabled = true
name = Casdoor
client_id = <client-id>
client_secret = <client-secret>
scopes = openid profile email
auth_url = https://door.example.com/login/oauth/authorize
token_url = https://door.example.com/api/login/oauth/access_token
api_url = https://door.example.com/api/userinfo
use_pkce = true
groups_attribute_path = groups
role_attribute_path = contains(groups[*], 'devops-admins') && 'Admin' || contains(groups[*], 'devops-users') && 'Editor' || 'Viewer'
role_attribute_strict = true

Grafana evaluates role_attribute_path against the ID token first, then the userinfo response, then the access token. Valid results are None, Viewer, Editor, Admin and GrafanaAdmin; the last one needs allow_assign_grafana_admin = true. allowed_groups limits login to listed groups and requires groups_attribute_path. Team sync is a Grafana Enterprise and Grafana Cloud feature.

Argo CD​

Argo CD communique directement avec Casdoor, sans utiliser son Dex intégré. Le callback navigateur est /auth/callback. argocd login --sso démarre un serveur local sur le port 8085 par défaut et utilise http://localhost:8085/auth/callback, il faut donc enregistrer cette URL également.

Définissez url et oidc.config (avec name, issuer, clientID, clientSecret, requestedScopes) dans argocd-cm. Les requestedScopes par défaut d'Argo CD ajoutent une portée groups. Casdoor n'en a pas besoin, car le jeton ID JWT contient toujours groups, c'est pourquoi notre guide demande ["openid", "profile", "email"]. Les groupes sont mappés dans argocd-rbac-cm, où scopes vaut [groups] par défaut :

data:
policy.default: role:readonly
policy.csv: |
g, devops-admins, role:admin

La procédure complète, y compris le secret client dans argocd-secret, se trouve dans le guide Argo CD.

MinIO​

MinIO lit les politiques depuis une seule revendication, définie via claim_name (par défaut policy). Il ne mappe pas les groupes. Le quickstart Casdoor de MinIO et notre guide utilisent la revendication tag de Casdoor : placez un nom de politique MinIO tel que readwrite dans le Tag de l'utilisateur, puis :

mc admin config set myminio identity_openid \
config_url="https://door.example.com/.well-known/openid-configuration" \
client_id=<client-id> client_secret=<client-secret> claim_name="tag"

role_policy est l'alternative : chaque utilisateur qui se connecte via ce fournisseur obtient les politiques répertoriées, et elle ne peut pas être combinée avec claim_name. Le callback de la Console est <console-url>/oauth_callback. Derrière un proxy, définissez MINIO_BROWSER_REDIRECT_URL ; l'ancienne clé redirect_uri est obsolète. Notez que le dépôt GitHub minio/minio a été archivé et que son README indique qu'il n'est plus maintenu, vérifiez donc quelle version de MinIO vous utilisez avant de compter sur ces paramètres.

Portainer​

Portainer utilise un fournisseur OAuth personnalisé. Remplissez Authorization URL (/login/oauth/authorize), Access token URL (/api/login/oauth/access_token) et Resource URL (/api/userinfo) sur votre hôte Casdoor, et définissez Redirect URL sur l'URL de base de Portainer. Il existe également un champ Logout URL. Dans Portainer CE, Automatic team membership est marqué comme une fonctionnalité Business Edition, et le paramètre attribuant des droits administrateur aux groupes n'existe que dans Business Edition. Sur CE, les utilisateurs créés par provisionnement automatique reçoivent le rôle utilisateur standard et vous promouvez les administrateurs manuellement.

Harbor et GitLab​

Harbor affiche son URI de redirection en bas de la page des paramètres OIDC : <harbor-url>/c/oidc/callback. Définissez OIDC Provider Endpoint sur l'URL de Casdoor, Group Claim Name sur groups, et OIDC Admin Group sur devops-admins. Harbor lit la revendication de groupe depuis le jeton ID, que le format JWT fournit. Vous ne pouvez passer Harbor de l'authentification par base de données à l'authentification OIDC qu'avant la création d'utilisateurs locaux.

La documentation OIDC de GitLab comprend une section Casdoor et exige que Casdoor soit servi via HTTPS. Le callback est /users/auth/openid_connect/callback. Les rôles basés sur les groupes (groups_attribute, admin_groups, required_groups, external_groups) nécessitent GitLab Premium ou Ultimate.

Outils sans OIDC​

Pour les tableaux de bord internes n'ayant pas leur propre connexion, placez-les derrière le plugin openid-connect d'Apache APISIX (discovery, client_id, client_secret, redirect_uri, bearer_only), comme indiqué dans le guide APISIX, ou derrière nginx comme décrit dans Nginx SSO authentication.

Une application par outil ou une application partagée​

Une seule application Casdoor contenant les callbacks de tous les outils dans ses Redirect URLs fonctionne, mais une application par outil est plus simple à gérer :

  • Chaque outil possède son propre secret client, de sorte qu'un secret Jenkins divulgué n'expose pas Grafana.
  • Token group format, Token format et l'expiration du jeton sont définis par application, vous pouvez donc donner à Argo CD Name (group) sans modifier les revendications d'un autre outil.
  • Casdoor vérifie post_logout_redirect_uri par rapport aux Redirect URLs de l'application, chaque liste reste ainsi courte et spécifique.

Les utilisateurs ne se connectent qu'une seule fois : après la première connexion, le cookie de session de Casdoor permet à la redirection vers l'outil suivant de s'effectuer sans demander de mot de passe.

Déconnexion​

Le point de terminaison end-session de Casdoor est /api/logout, listé sous end_session_endpoint dans le document de découverte. Il accepte id_token_hint, post_logout_redirect_uri, client_id et state, et ne redirige que vers une URL figurant dans les Redirect URLs de l'application. La déconnexion de Casdoor termine la session Casdoor et les jetons de cette session, mais chaque outil conserve également son propre cookie de session. Configurez la déconnexion dans chaque outil :

  • Jenkins : logoutFromOpenidProvider, avec /OicLogout enregistré.
  • Grafana : signout_redirect_url.
  • Argo CD : logoutURL dans oidc.config, par exemple https://door.example.com/api/logout?id_token_hint={{token}}&post_logout_redirect_uri={{logoutRedirectURL}}.
  • Harbor : OIDC Session Logout.
  • Portainer : Logout URL.

Les détails du point de terminaison se trouvent dans RP-initiated logout.

Références​