7.4. Domaines de sécurité — Identifier les utilisateurs Jenkins

Jenkins vous permet d'identifier et de gérer les utilisateurs de plusieurs façons, depuis une simple base de données intégrée pour les petites équipes jusqu'à l'intégration avec des annuaires d'entreprise, avec de nombreuses autres options entre les deux.

7.4.1. Utiliser la base de données intégrée à Jenkins

Le moyen le plus simple pour gérer des comptes utilisateurs dans Jenkins est d'utiliser la base de données interne de Jenkins. C'est une bonne option si vous voulez garder les choses simples, car peu de configuration est nécessaire. Les utilisateurs qui ont besoin de se connecter au serveur Jenkins peuvent s'enregistrer et créer un compte par eux-mêmes, et, en fonction du modèle de sécurité choisi, un administrateur peut ensuite décider ce que ces utilisateurs sont autorisés à faire.

Jenkins ajoute automatiquement tout utilisateur de gestionnaire de sources à cette base de données dès qu'un changement est effectué dans le code source surveillé par Jenkins. Ces noms d'utilisateurs sont utilisés principalement pour enregistrer le responsable de chaque tâche de build. Vous pouvez voir la liste des utilisateurs actuellement connus en cliquant sur l'entrée de menu Personnes (voir Figure 7.3, “La liste des utilisateurs connus de Jenkins”). Ici, vous pouvez visualiser les utilisateurs que Jenkins connaît actuellement, et aussi voir le dernier projet dans lequel ils ont committé. Notez que cette liste contient la liste de tous les utilisateurs à avoir jamais committé dans les projets que Jenkins surveille — ils pourraient ne pas être (et en général ne sont pas) tous des utilisateurs actifs de Jenkins capables de se connecter sur le serveur Jenkins.

La liste des utilisateurs connus de Jenkins

Figure 7.3. La liste des utilisateurs connus de Jenkins


Si vous cliquez sur un utilisateur de cette liste, Jenkins vous emmène sur une page affichant différentes informations à propos de cet utilisateur, incluant son nom complet et les tâches de build auxquelles il a contribué (voir Figure 7.4, “Afficher les builds auxquels un utilisateur participe”). De là, vous pouvez aussi modifier ou compléter les détails à propos de cet utilisateur, comme son mot de passe ou son adresse email.

Afficher les builds auxquels un utilisateur participe

Figure 7.4. Afficher les builds auxquels un utilisateur participe


Un utilisateur apparaissant sur cette liste ne peut pas nécessairement se connecter à Jenkins. Pour pouvoir se connecter, l'utilisateur doit avoir un mot de passe configuré. Il y a essentiellement deux façons de faire cela. Si vous avez configuré l'option "Autoriser les utilisateurs à s'enregistrer", les utilisateurs peuvent simplement se connecter avec leur nom d'utilisateur SCM et fournir leur adresse email et leur mot de passe (voir Section 7.3, “Sécurité simple dans Jenkins”). Autrement, vous pouvez activer un utilisateur en cliquant sur l'option de menu Configurer dans l'écran de détails utilisateur, et fournir une adresse email et un mot de passe vous-même (voir Figure 7.5, “Créer un nouveau compte utilisateur en s'enregistrant”).

Créer un nouveau compte utilisateur en s'enregistrant

Figure 7.5. Créer un nouveau compte utilisateur en s'enregistrant


Il est utile de noter que, si vos adresses email sont synchronisées avec vos noms d'utilisateurs de contrôle de version (par exemple, si vous travaillez chez acme.com, et que l'utilisateur “joe” dans votre système de contrôle de version a une adresse email joe@acme.com), vous pouvez faire que Jenkins dérive l'adresse email de l'utilisateur en ajoutant un suffixe que vous configurez dans la section Notification Email (voir Figure 7.6, “Synchroniser les adresses email”). Si vous avez effectué ce type de configuration, vous n'avez pas besoin de spécifier l'adresse email pour les nouveaux utilisateurs à moins qu'elle ne respecte pas cette convention.

Synchroniser les adresses email

Figure 7.6. Synchroniser les adresses email


Une autre façon de gérer les utilisateurs courants actifs (ceux qui peuvent vraiment se connecter à Jenkins) s'effectue via le lien Gérer les utilisateurs sur la page de configuration principale de Jenkins (voir Figure 7.7, “Vous pouvez aussi gérer les utilisateurs Jenkins depuis la page de configuration Jenkins”).

Vous pouvez aussi gérer les utilisateurs Jenkins depuis la page de configuration Jenkins

Figure 7.7. Vous pouvez aussi gérer les utilisateurs Jenkins depuis la page de configuration Jenkins


D'ici, vous pouvez voir et éditer les utilisateurs qui peuvent se connecter à Jenkins (voir Figure 7.8, “La base de données des utilisateurs de Jenkins”). Cela inclut à la fois les utilisateurs qui se sont enregistrés manuellement (si cette option a été activée) et les utilisateurs SCM que vous avez activés en leur configurant un mot de passe. Vous pouvez aussi éditer des informations utilisateur (par exemple, modifier leur adresse email ou réinitialiser leur mot de passe), ou même les supprimer de la liste des utilisateurs actifs. Procéder ainsi ne les enlèvera pas de la liste globale des utilisateurs (leurs noms apparaîtront toujours dans l'historique de build, par exemple), mais ils ne seront plus capables de se connecter au serveur Jenkins.

La base de données des utilisateurs de Jenkins

Figure 7.8. La base de données des utilisateurs de Jenkins


La base de données interne de Jenkins est suffisante pour de nombreuses équipes et organisations. Toutefois, pour des organisations plus importantes, cela peut devenir fastidieux et répétitif de gérer un grand nombre d'utilisateurs à la main. Et plus particulièrement encore si cette information existe déjà quelque part. Dans les sections suivantes, nous regarderons comment brancher Jenkins avec d'autres systèmes de gestion utilisateurs, comme des annuaires LDAP ou des utilisateurs et groupes Unix.

7.4.2. Utiliser un annuaire LDAP

Plusieurs organisations utilisent des annuaires LDAP pour stocker des comptes et mots de passe à travers différentes applications. Jenkins s'intègre bien avec LDAP, sans nécessiter de plugin spécial. Il peut authentifier les utilisateurs en utilisant l'annuaire LDAP, vérifier l'appartenance à un groupe, et récupérer les adresses email des utilisateurs authentifiés.

Pour intégrer Jenkins à votre annuaire LDAP, sélectionnez simplement “LDAP” dans la section Domaine de sécurité, et remplissez les détails concernant votre serveur LDAP (voir Figure 7.9, “Configurer LDAP dans Jenkins”). Le champ le plus important est le serveur de l'annuaire. Si vous utilisez un port non standard, vous devrez aussi l'indiquer (par exemple, ldap.acme.org:1389). Si vous utilisez LDAPS, vous devrez aussi le spécifier (par exemple, ldaps://ldap.acme.org)

Si votre serveur autorise la connexion anonyme, cela vous suffira probablement pour démarrer. Sinon, vous pouvez utiliser les options avancées pour paramétrer plus finement votre configuration.

La plupart des champs Avancés peuvent sans problème être laissés vides à moins que vous n'ayez une bonne raison de les changer. Si votre annuaire est extrêmement volumineux, vous devriez spécifiez une valeur de DN racine (e.g., dc=acme, dc=com) et/ou une base de recherche utilisateur et groupe (e.g., ou=people) pour réduire la portée des requêtes utilisateur. Ceci n'est habituellement pas nécessaire à moins que vous ne remarquiez des problèmes de performance. Ou, si votre serveur n'autorise pas les connexions anonymes, vous devrez fournir un DN et un mot de passe de gestionnaire, afin que Jenkins puisse se connecter au serveur pour exécuter ses requêtes.

Configurer LDAP dans Jenkins

Figure 7.9. Configurer LDAP dans Jenkins


Une fois que vous avez configuré votre serveur LDAP comme domaine de sécurité, vous pouvez configurer votre modèle de sécurité comme décrit précédemment. Quand les utilisateurs se connecteront à Jenkins, ils seront authentifiés sur l'annuaire LDAP.

Vous pouvez aussi utiliser des groupes LDAP, bien que la configuration ne soit pas immédiatement évidente. Supposons que vous ayez défini un group appelé JenkinsAdmin dans votre annuaire LDAP, avec un DN cn=JenkinsAdmin, ou-Groups, dc=acme, dc=com. Pour référencer ce groupe dans Jenkins, vous devez prendre le nom commun (cn) en majuscules, et le préfixer avec ROLE_. Ainsi cn=JenkinsAdmin devient ROLE_JENKINSADMIN. Vous pouvez voir un exemple de groupes LDAP utilisés de cette façon dans Figure 7.10, “Utiliser des groupes LDAP dans Jenkins”.

Utiliser des groupes LDAP dans Jenkins

Figure 7.10. Utiliser des groupes LDAP dans Jenkins


7.4.3. Utiliser Microsoft Active Directory

Microsoft Active Directory est un logiciel d'annuaire largement utilisé dans les architectures Microsoft. Bien qu'Active Directory fournisse un service LDAP, il peut être compliqué à configurer, et il est plus simple de demander à Jenkins de parler directement au serveur Active Directory. Heureusement, il y a un plugin pour ça.

Le plugin Active Directory de Jenkins vous permet de configurer Jenkins pour authentifier les utilisateurs via un serveur Microsoft Active Directory. Vous pouvez à la fois authentifier les utilisateurs, et récupérer leurs groupes pour la matrice d'autorisations générale ou par projet. Notez que, à l'inverse d'une intégration LDAP conventionnelle (voir Section 7.4.2, “Utiliser un annuaire LDAP”), il n'est pas nécessaire de préfixer les groupes avec ROLE_ — vous pouvez utiliser l'annuaire des groupes Active Directory (comme “Administrateur de Domaine”).

Pour configurer le plugin, vous devez fournir le nom de domaine complet de votre serveur Active Directory. Si vous avez plus d'un domaine, vous pouvez fournir une liste séparée par des virgules. Si vous fournissez le nom de la forêt (par exemple “acme.com” au lieu de “europe.acme.com”), alors la recherche sera faite à partir du catalogue global. Notez que si vous faites cela sans spécifier le bind DN (voir ci-dessous), l'utilisateur devra se connecter en tant que “europe\joe” ou “joe@europe”.

Les options avancées vous permettent de spécifier un nom de site (pour améliorer les performances en restreignant les contrôleurs de domaine que Jenkins requête), et un DN de liaison et un mot de passe, ce qui peut être pratique si vous vous connectez à une forêt multidomaines. Vous devez fournir des valeurs de DN de liaison et de mot de passe valides, que Jenkins puisse utiliser pour se connecter à votre serveur afin qu'il établisse l'identité complète de l'utilisateur en cours d'authentification. De cette façon, l'utilisateur peut taper simplement “jack” ou “jill”, et faire que le système retrouve automatiquement qu'ils sont jack@europe.acme.com ou jack@asia.acme.com. Vous devez fournir le nom principal complet avec le nom de domaine, tel que admin@europe.acme.com, ou un nom distinctif de style LDAP, tel que CN=Administrator,OU=europe,DC=acme,DC=com.

Une autre bonne chose à propos de ce plugin est qu'il fonctionne à la fois dans un environnement Windows et un environnement Unix. Donc si Jenkins fonctionne sur un serveur Unix, il pourra quand même effectuer les authentifications via un service Microsoft Active Directory d'une autre machine.

Plus précisément, si Jenkins s'exécute sur une machine Windows et que vous ne spécifiez pas de domaine, cette machine doit être un membre du domaine auprès duquel vous souhaitez vous authentifier. Jenkins utilisera ADSI pour retrouver tous les détails, aucune configuration additionnelle n'est donc nécessaire.

Sur une machine non Windows (ou si vous spécifiez un ou plusieurs domaines), vous devez dire à Jenkins le nom du domaine Active Directory auprès duquel s'authentifier. Jenkins utilise alors les enregistrements DNS SRV et le service LDAP d'Active Directory pour authentifier les utilisateurs.

Jenkins peut déterminer les groupes Active Directory auxquels l'utilisateur appartient. Vous pouvez donc les utiliser dans votre stratégie d'autorisations. Par exemple, vous pouvez utiliser ces groupes dans la sécurité basée sur une matrice, ou autoriser les "Administrateurs de domaine" à administrer Jenkins.

7.4.4. Utiliser les utilisateurs et les groupes Unix

Si vous exécutez Jenkins sur une machine Unix, vous pouvez aussi demander à Jenkins d'utiliser les comptes utilisateur et groupes définis sur cette machine. Dans ce cas, les utilisateurs se connecteront à Jenkins en utilisant leurs comptes et mots de passe Unix. On utilise alors le système Pluggable Authentication Modules (PAM), et cela fonctionne aussi bien avec NIS.

Dans sa forme la plus basique, c'est un peu rébarbatif, parce que cela nécessite de créer et de configurer des comptes utilisateurs pour chaque nouvel utilisateur Jenkins. Ce n'est véritablement utile que si ces comptes nécessitent d'être mis en place pour d'autres besoins.

7.4.5. Déléguer au conteneur de Servlet

Une autre façon d'identifier les utilisateurs Jenkins est de laisser le conteneur de Servlet le faire pour vous. Cette approche est utile si vous exécutez Jenkins dans un conteneur de Servlet comme Tomcat ou GlassFish, et que vous avez déjà un moyen établi pour intégrer le conteneur de Servlet avec votre annuaire utilisateur. Tomcat, par exemple, vous permet d'authentifier les utilisateurs par rapport à une base de données relationnelle (en utilisant du JDBC direct ou une DataSource), JNDI, JAAS, ou fichier de configuration XML. Vous pouvez aussi utiliser les rôles définis dans l'annuaire utilisateur du conteneur de Servlet afin de les utiliser pour les stratégies d'autorisation par matrice ou basée sur le projet.

Dans Jenkins, c'est facile à configurer — sélectionnez simplement cette option dans la section Domaine de sécurité (voir Figure 7.11, “Sélectionner le domaine de sécurité”). Une fois que vous avez fait cela, Jenkins laissera le serveur s'occuper de tout.

Sélectionner le domaine de sécurité

Figure 7.11. Sélectionner le domaine de sécurité


7.4.6. Utiliser Atlassian Crowd

Si votre organisation utilise les produits Atlassian comme JIRA et Confluence, vous pouvez aussi utiliser Crowd. Crowd est une application commerciale de gestion d'identité et de Single-Sign On (SSO) d'Atlassian qui vous permet de gérer des comptes utilisateur unique à travers différents produits. Vous gérez une base de données interne d'utilisateurs, de groupes et de rôles, et vous vous intégrez avec des annuaires externes comme des annuaires LDAP ou des magasins utilisateur spécifiques.

En utilisant le plugin Jenkins Crowd, vous pouvez utiliser Atlassian Crowd comme source de vos utilisateurs et groupes Jenkins. Avant de commencer, vous devez configurer une nouvelle application dans Crowd (voir Figure 7.12, “Utiliser Atlassian Crowd comme domaine de sécurité Jenkins”). Configurez simplement une nouvelle Application Générique appelée “jenkins” (ou quelque chose du même genre), et avancez d'onglet en onglet. Dans l'onglet Connexions, vous devez fournir l'adresse IP de votre serveur Jenkins. Ensuite, vous devez indiquer l'annuaire Crowd que vous utiliserez pour récupérer les comptes utilisateurs Jenkins et informations de groupes. Enfin, vous devrez dire à Crowd quels utilisateurs de ces annuaires peuvent se connecter à Jenkins. Une option est d'autoriser tous les utilisateurs à s'authentifier, et laisser Jenkins gérer les détails. Sinon, vous pouvez lister les groupes utilisateur Crowd autorisés à se connecter à Jenkins.

Utiliser Atlassian Crowd comme domaine de sécurité Jenkins

Figure 7.12. Utiliser Atlassian Crowd comme domaine de sécurité Jenkins


Une fois que vous avez configuré cela, vous devez installer le plugin Jenkins Crowd, comme vous le faites habituellement via le gestionnaire de plugin de Jenkins. Une fois installé le plugin et Jenkins redemarré, vous pouvez définir Crowd comme domaine de sécurité dans l'écran de configuration principal de Jenkins (voir Figure 7.13, “Utiliser Atlassian Crowd comme domaine de sécurité Jenkins”).

Utiliser Atlassian Crowd comme domaine de sécurité Jenkins

Figure 7.13. Utiliser Atlassian Crowd comme domaine de sécurité Jenkins


Avec ce plugin installé et configuré, vous pouvez utiliser les utilisateurs et les groupes de Crowd pour toutes les stratégies d'autorisation que nous avons présentées précédemment dans ce chapitre. Par exemple, dans Figure 7.14, “Utiliser les groupes Atlassian Crowd dans Jenkins”, nous utilisons des groupes utilisateurs définis dans Crowd pour configurer une sécurité basée sur la matrice dans l'écran principal de configuration.

Utiliser les groupes Atlassian Crowd dans Jenkins

Figure 7.14. Utiliser les groupes Atlassian Crowd dans Jenkins


7.4.7. S'intégrer avec d'autres systèmes

En plus des stratégies d'authentification discutées ici, il y a un certain nombre d'autres plugins permettant à Jenkins d'effectuer l'authentification via d'autres systèmes. Au moment de l'écriture de ces lignes, ceci inclut Central Authentication Service (CAS) — un outil open source de single sign-on — et le serveur Collabnet Source Forge Enterprise Edition (SFEE).

Si aucun plugin n'est disponible, vous pouvez aussi écrire votre propre script d'authentification. Pour faire cela, vous devez installer le plugin Script Security Realm. Une fois que vous avez installé le script et redémarré Jenkins, vous pouvez écrire deux scripts dans votre langage de scripting favori. Un script authentifie l'utilisateur, tandis que l'autre détermine les groupes d'un utilisateur donné (voir Figure 7.15, “Utiliser des scripts personnalisés pour gérer l'authentification”).

Utiliser des scripts personnalisés pour gérer l'authentification

Figure 7.15. Utiliser des scripts personnalisés pour gérer l'authentification


Avant d'invoquer le script d'authentification, Jenkins positionne deux variables d'environnement : U, contenant le nom d'utilisateur, et P, contenant le mot de passe. Ce script utilise ces variables d'environnement pour authentifier le nom d'utilisateur et le mot de passe spécifié, en retournant 0 en cas de réussite, et une autre valeur sinon. Si l'authentification échoue, la sortie du processus sera renvoyée dans le message d'erreur affiché à l'utilisateur. Voici un simple script script d'authentification Groovy :

def env = System.getenv()
def username = env['U']
def password = env['P']

println "Authenticating user $username"

if (authenticate(username, password)) {
    System.exit 0
} else {
    System.exit 1
}

def authenticate(def username, def password) {
    def userIsAuthenticated = true
    // Authentication logic goes here
    return userIsAuthenticated
}

Ce script est suffisant si tout ce que vous avez à faire est de gérer une authentification basique sans groupes. Si vous voulez utiliser des groupes de votre source d'authentification personnalisée dans vos autorisations matricielles ou projet (voir Section 7.5, “Autorisation — Qui peut faire quoi”), vous pouvez écrire un second script, qui détermine les groupes pour un utilisateur donné. Ce script utilise la variable d'environnement U pour déterminer quel utilisateur essaie de se connecter, et affiche une liste de groupe séparée par des virgules pour cet utilisateur sur la sortie standard. Si vous n'aimez pas les virgules, vous pouvez redéfinir le caractère de séparation dans la configuration. Voici un simple script Groovy pour faire cela :

def env = System.getenv()
def username = env['U'] 

println findGroupsFor(username)

System.exit 0

def findGroupsFor(def username) {
    return "admin,game-of-life-developer"
}

Ces deux scripts doivent renvoyer 0 lorsqu'ils sont appelés pour qu'un utilisateur soit authentifié.