Outils pour utilisateurs

Outils du site


fr:rapports:2022:07-02

2022/07/02 (Neutriton) : Keycloak

Présences :

  • HgO (hagécho)
  • Célo (cécho - lait chaud)
  • Tharyrok
  • wget

Météo

Moment informel durant lequel on exprime en peu de mots comment on se sent et si on a une attente forte pour la réunion. Ce n'est pas un moment de discussion mais d'expression individuelle et ce n'est pas obligatoire 🙂

Attente(s) forte(s)

Si l'une ou l'autre personne exprime une attente forte, merci de vous en occuper en priorité ou de la noter dans le hub ou dans un point approprié.

Atelier Keycloak

Labo

On a créé quatre VMs dans le cluster « Chez Mémé ».

On vérifie bien que tout le monde peut se connecter à sa petite VM.

  • ssh.cust-q3iom4kp-3e9.chezme.me (tharyrok)
  • ssh.cust-clph1mud-3ea.chezme.me (hgo)
  • ssh.cust-3ojf1oo9-3eb.chezme.me (celo)
  • ssh.cust-whedrm0h-3ec.chezme.me (wget)

Sur cette VM est provisionné plusieurs choses. Pour y accéder, il suffit de remplacer le ssh du nom de domaine de sa machine par le nom du service:

  • maildev pour avoir les mails
  • grav installé
  • nextcloud
  • keycloak
  • echo (retourne tous les headers que le serveur reçoit)

Certains services offrent directement le SSO. Parfois, il faudra un proxy SSO.

Pour grav, l'utilisateur c'est admin et le mot de passe se trouve dans le home de l'utilisateur grav: /var/www/grav/password

Pour le nextcloud, l'utilisateur c'est admin et le mot de passe c'est neutrinet #sécurité

Et pour keycloak, c'est pareil que nextcloud.

Tour d'horizon

Mais… C'est quoi Keycloak ? C'est un gestionnaire d'utilisateurs qui permet d'avoir le même mot de passe pour tous les services, pour un utilisateur donné.

Il permet de s'authentifier dans chaque service en se connectant une seule fois (ce qui ne signifie pas qu'on est d'office connecté à tout, il faut quand même aller sur le service en question).

Quels protocoles Keycloak supporte-t-il ? Et que font-ils ?

  • oauth2 : à la base c'était pour déléguer l'authentification à un service tiers. Ça parle en json, et tout se repose sur des tokens qui se transmettent via l'url, pour faire très très simple.
  • saml2 : protocole en xml, le chiffrement ne se fait pas uniquement sur l'https mais utilise aussi des certificats (échange de certificat), plus vieux qu'openid-connect et faisait à sa création aussi de l'identification.
  • openid-connect : de oauth2 + une notion de profil qui permet d'avoir un échange d'informations.

Différence identificatation et authentification :

  • Identification : permet d'identifier une personne formellement (ex: eid), prouver qui on est, en plus de prouver qu'on connait le secret, on prouve qu'on a accès à l'information
  • Authentification : prouve que l'identité est bien celle qu'elle prétend elle, on prouve qu'on est soi parce qu'on s'authentifie. Cela se fait en montrant qu'on connaît un secret (token, vérification par mail, etc).

Dans le cas de Keycloak, il peut fonctionner uniquement en mode authentification.

Quel est le workflow quand on va sur un service « géré » par Keycloak ?

Soit on accède à la page du service qui va vérifier si on est authentifié ou pas et qui dirige d'emblée vers le services d'authentification (ou alors on a un bouton vers lequel on doit cliquer pour être redirigé vers le service d'authentification).

On a une redirection web qui se fait avec un token dans l'URL, keycloak authentifie, puis redirige vers le service, qui une fois qu'il a reçu le nouveau token, va recontacter keycloak pour lui demander si le service est valide.

En résumé :

  1. L'humain souhaite accéder à l'application.
  2. L'application demande à keycloak le token.
  3. Keycloak répond “bonjour voici ton token”
  4. Le service envoie une 302 à l'humain (enfin dans son navigateur)
  5. Le navigateur envoit une requête à Keycloak pour savoir si le token est valide.
  6. Keycloak répond une 302 au navigateur de l'humain.
  7. Le service recontacte encore Keycloack pour savoir si le token est valide.

Si l'on est déjà identifié, le token est rafraichi. C'est à la dernière étape que Keycloak que le service interroge Keycloak pour savoir si c'est une nouvelle connexion ou si c'est une personne déjà authentifiée.

On a une boucle.

Si vous voulez creuser le sujet, lisez les RFC.

Utilisation de Keycloak

Keycloak possède des royaumes.

Un royaume est un ensemble d'utilisateurs, un ensemble d'applications et des permissions. On peut avoir un royaume qui ne contient que des applications ou que des utilisateurs.

Le royaume par défaut est le royaume master. Celui ci doit UNIQUEMENT être utilisé pour l'administation de Keycload. C'est le big boss des royaumes, et seuls les admins doivent pouvoir y accéder. On force la double authentification. Si un petit malin tombe dedans, il peut impersonifier n'import qui, bref faire ce qu'il veut.

On peut le désactiver, mais c'est assez chiant.

Comme on ne peut pas utiliser le royaume par défaut, on va créer un royaume \o/ 👑 🏰

On clique sur la flèche « Master » en haut à gauche, puis sur « Add a realm ».

⚠ Quand on crée un realm, son nom sera sensible à la casse dans les urls. Donc on va mettre tout en minuscule pour ne pas avoir de surprises par la suite :

On peut réimporter une configuration qu'on aurait exporté (mais pas les mots de passes utilisateurs).

On ne touche pas à l'onglet « Général ».

Dans l'onglet « Login » on va activer toute une série d'options :

Ne pas oublier de cliquer sur « Save ».

En navigation privée, on se rend ensuite sur le lien :

https://keycloak.cust-q3iom4kp-3e9.chezme.me/realms/{realm_name}/account/#/

Il s'agit de la console pour les utilisateurs.

La navigation privée permet d'éviter les conflits avec la console d'administration.

C'est un des deux endroits cruciaux (l'autre étant la page d'accueil)

Ces deux consoles sont modifiables et cela va être géré dans les paramềtres de configuration de keycloak. Il y a un template qu'on peut modifier. On peut aussi configurer le serveur web pour être d'office redirigé sur la console utilisateur.

On se connecte… mais… on n'a pas de compte 😞 Donc on se crée un compte !

Par défaut, l'email, le nom et prénom sont obligatoires… on souhaiterait changer cela. Ca se fait dans la console d'administration dans Authentification → Flow → sélectionner Registration dans la liste.

Les champs apparaissent encore.. mais ils ne sont plus obligatoires ! Donc on met juste notre pseudo et notre mot de passe très sécurisé.

On peut customiser les différents champs et en mettre d'autres qui seraient obligatoires.

Par contre, si on veut modifier des infos dans son profil une fois connecté, on va de nouveau avoir des champs obligatoires 😨 D'où l'importance de modifier le thème par défaut, parce que c'est prévu pour un monde d'entreprise de surveillance capitaliste !!!

Dans le tableau de bord, on peut avoir des infos sur les devices actuellement connectés, les méthodes de connexion, les applications autorisées.

Quand on va dans la partie « Users », en cliquant sur « View all users » on peut avoir la liste des utilisateurs :

On peut même impersonifier quelqu'un ! C'est hyper dangereux parce que l'application ne sera jamais au courant qu'on est en train d'impersonifier quelqu'un…

En cliquant sur l'utilisateur, on peut avoir plusieurs « required actions » pour celui-ci :

Mais ça ne marche pas encore, parce que le flow d'authentification ne demande pas de vérifier l'email.

On va essayer avec « Update password », ce qui va demander à l'utilisateur de changer son mot de passe la prochaine fois qu'il tente de se connecter

Attributs : il est possible de stocker des informations qui seront utiles aux applications pour qu'elles puissent y accéder. Par exemple, l'adresse postale. Les champs et les valeurs qui peuvent être indiquées sont libres.

Credentials : on a différentes manières d'authentifier les humains (fédération par exemple, c'est alors un autre outil qui revoie l'information).

Role mapping :

Dans cette section, on peut, pour un utilisateur donné, donner des rôles qui seront accessibles dans la partie client.

À partir de maintenant, on va parler d'utilisateur pour faire références aux humains, et de clients pour faire référence aux applications.

Concrètement, on va pouvoir gérer les droits d'accès aux applications.

Par défaut, on a un rôle assigné, default role realm. C'est le rôle qui permet d'accéder à la console utilisateur. Les rôles sur la gauche sont des rôles qui pourraient être ajoutés.

On pourrait se donner des roles dans le client realm-management, qui a différents sous-rôles, par exemple voir les utilisateurs du royaume. Donc, le realm-management est vu comme un client comme les autres pour keycloak.

Les groupes permettent de mapper des groupes aux utilisateurs. Ces groupes peuvent avoir des attribus et des rôles mappings (voir plus loin). On peut avoir par exemple le groupe « Tata » et un sous-groupe « Ryrok ».

Le consentement, c'est pour certains flow où l'on va demander à l'utilisateur de valider que l'application peut utiliser keycloak pour les informations d'authentification, et par conséquent demander éventuellement ces infos.

Par exemple, pour les commandes de briques, on a besoin de l'adresse des gens. On pourrait avoir un écran qui averti qu'on va transmettre l'info à l'application. Si l'info est connue de Keycloak, elle sera transférée à l'application. Si elle ne l'est pas, l'utilisateur sera invité à renseigner l'info.

C'est dans cet écran qu'on verra la liste des trucs pour lesquels l'utilisateur aura donné son consentement.

Et les sessions, ce sont les différentes connexions de l'utilisateur.

Là où on va beaucoup jouer, ce sont les rôle mappings, les groupes, les credentials (pour donner un mot de passe par défaut par ex), et enfin les sessions.

On va parler de la configuration des clients.

Dans “Client” dans la colonne latérale.

Tharyrok aime bien créer les royaumes par usage, quitte à avoir beaucoup de royaume. Typiquement, quand on fait de la délégation, on peut avoir trois royaumes séparés (royaume développement pour les développeurs, permet de leur donner accès et qu'ils soient libres d'ajouter leur application, mais qui n'auront pas les mots de passes des utilisateurs).

Par exemple, dans Neutrinet on pourrait faire des royaumes par sensibilité d'information.

Le Mattermost n'a besoin que d'un pseudonyme. Cela pourrait être dans un royaume basique.

Mais pour la commande des brique, il faut l'adresse postale, donc on aurait un autre royaume « restrictive ».

Ce royaume contiendra donc les adresses, mais ne sera pas à même d'accéder aux autres royaumes.

Utile pour ne pas que toutes les apps aient accès aux key values de tous les utilisateurs. Ici c'est pour avoir une granularité plus forte.

Aussi pour avoir des niveaux d'authentification sépaarés en fonction de la sensibilité: restrctif pourrait nécessiter du TOTP par exemple alors que Basic pas.

Et on pourrait même avoir un royaume pour les informations sensibles.

Par défaut, Keycloak s'utilise lui-même pour s'authentifier. On retrouve le client “Account”. Real manager est l'interface de gestion mais seulement pour un royaume.

Si on supprime account, les utilisateurs ne peuvent plus se connecter pour accéder à l'interface et mettre à jour leur profil.

On créé un nouveau royaume, qu'on appelle « application ». On va lier ce royaume a un client utilisé pour l'authentification.

Puis on va dans Identity Provider. Keycloak est capable, pour un royaume, de déléguer l'authentification via un autre royaume. Dans Identity Provider, on peut faire l'authentification par github, google, etc… On choisit « keycloak openid-connect ».

Si on ajoute un identity provider, on laisse par défaut l'alias, puis on a un display name, on peut dire qu'on attend que des emails, et on peut cocher Account Linking Only pour indiquer qu'on aura dans le royaume que des utilisateurs fédérés. Tout le reste, on laisse par défaut.

Si on ouvre un autre onglet avec notre royaume neutricorp ou patatacorp, on créé un nouveau client (donc partie Client de Neutricorp).

Aux yeux du royaume Neutricorp, le royaume application est client.

Dans client → Application, on a les informations du client.

Endpoints : ce sont les informations, identifiants, token actifs…

Si on clique sur l'endpoint « openid », on tombe sur json qui va lister tout plein d'infos sur ce type d'endpoint.

On copie l'url de la ligne « issuer » pour la mettre dans le champ root url du client « application.

En fait, on va taper ces urls dans le client « application » du realm « patacorp », ce qui va permettre de relier ce client avec le royaume « application ».

Pour openid-connect, il faut mettre l'exacte URL de redirection, parce que si le client ne donne pas la même URL, Keycloak va refuser. (Celle de Royaume Application → Identity Provider)

Dans Royaume Neutricorp, on regarde les endpoint. Dans Identity Provider, on a pas mal de chose à renseigner. On prend l'URL qui est dans Authorisation Endpoint et on la met dans Authorisation URL.

On fait la même chose pour le token (on la trouve dans token endpoint).

Il reste alors Client Authentification, qui permet de dire à Keycloak comment s'échanger les infos dans le protocole openid. Keycloak va utiliser post dans l'URL de redirection des clients.

Client ID → l'ID du client, ici application.

Dans Access type, on met confidentiel, ce qui permet de se rendre dans Credential et d'avoir le secret, qui se met dans le Client secret.

On pourrait ajouter d'autres trucs encore, mais on va s'arrêter là. On sauvergarde.

Maintenant, dans le royaume Neutricorp, on a bien un client qui s'appelle Application.

Si on ouvre un nouvel onglet et qu'on va comme tout à l'heure sur la partie account (donc publique), et qu'on va dans Sing in, on voit qu'on s'authentifie avec le royaume Application… mais ce n'est pas ce qu'on veut.

On a oublié un truc : cocher hide login page dans Identity Provider → Notre application keycloak-oidc.

Ce qui se passe aussi, c'est que le disable login a juste caché le bouton. Or on veut être redirigé.

Dans Identity Provider, on va copier le nom de notre Provider, et dans Authentification → Browser → Identity Provider Redirector → config → on met notre identity provider.

On désactive complétement le form qui ne doit plus être actif.

Là on a un problème. Comme on a désactivé profil, Keycloak ne veut pas un client où profil est activé. Pour que ça marche, on doit donc remettre tel que c'est pas défaut :

Décocher hide login page Décocher Account Link Only Désactiver la redirection dans Browser.

Là, quand on s'authentifie dans le royaume Neutricorp, il nous connecte. Mais on doit renseigner des informations dans le royaume Application.

Faire plusieurs royaumes avec un pour les applications permet de sécuriser.

Différents cas d'usage :

  • limiter les attributs
  • limiter qui a le droit de faire quoi (impersonification seulement pour les utilisateurs et applications du royaume)
  • des flows plus sécurisés pour une partie des applications

Faire de la fédération est plus compliqué à configurer, mais permet de gérer plus finement les accès.

Nextcloud : en openid, ne gère pas les groupes. On devrait le faire en saml2 pour que ça prenne en compte les groupes.

Nextcloud

Dans Nextcloud, on va rajouter une application.

On se connecte en tant qu'admin.

On va rechercher saml2 dans Applications → Intégration. On cherche l'app : SSO & SAML authentication

Dans les paramètres de Nextcloud, un nouveau paramètre est apparu 😃

On choisit use built-in-SAML authentification.

On va dans Keycloak, et dans le royaume Application, on va dans Client, et Create. On met un ID qui représente le Nextcloud.

On va utiliser le hostname du service, en replaçant les . par des tirets. On pourrait l'appeler Nextcloud ou autrement.

On choisit SAML comme protocole dans Client Protocol.

Dans Always Display in Console, on fait que ça apparaît dans le panel comme dans Yunohost.

Comparé à openid, on a plus d'options.

Bon, en fait on va pas faire ça, on supprime le client. Elle chiante Mémé 😛

Dans Application → Endpoint SAMLv2 → On fait une copie du certificat.

On retourne dans Nextcloud.

Quand on rajoute le client SAML, on peut toujours utiliser l'authentification locale. Ca peut-être bien de la désactiver, ce qui fait que tout le monde doit se re-authentifier auprès de keycloak.

On risque de devoir réauthentifier aussi ses caldav, etc.

On clique sur Add (le lien est discret) Identity Provider.

et on indique qu'on va matcher sur username → c'est propre à Nextcloud pour lui dire qu'on va récupérer les infos de keycloak.

Dans Service Provider Data, on récupère le certificat dans Keycloak → Application → Key. On copie la clé.

On met le certificat dans X509 subject name.

src.

On suit ce tutoriel :

https://janikvonrotz.ch/2020/04/21/configure-saml-authentication-for-nextcloud-with-keycloack/

En fait il faut préalablement générer un certificat :

openssl req  -nodes -new -x509  -keyout private.key -out public.cert

On entre le certificat ainsi que la clé privée.

Dans Configure your IdP on met les liens vers le royaume et vers le protocole.

On doit maintenant mapper les champs de Nextcloud avec ceux qui Keycloak doit fournir :

Champs :

  • email
  • groupe
  • quota
  • role

etc… ce sont des attributs qu'on aurait dû créer avant, ou alors on met des comptes par défaut.

Ensuite on coche des trucs, tel que montré sur la capture d'écran finale :

Mais on tombe sur une Internal Server Error T_T :

snippet.json
{"reqId":"3kSLELyfZxtEpspLCo4k","level":3,"time":"2022-07-02T16:31:54+00:00","remoteAddr":"127.0.0.1","user":"admin","app":"index","method":"GET","url":"/apps/user_saml/saml/metadata?idp=1","message":"Invalid array settings: idp_cert_or_fingerprint_not_found_and_required","userAgent":"Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0","version":"24.0.2.1","exception":{"Exception":"OneLogin\\Saml2\\Error","Message":"Invalid array settings: idp_cert_or_fingerprint_not_found_and_required","Code":2,"Trace":[{"file":"/var/www/nextcloud/24.0.0/apps/user_saml/lib/Controller/SAMLController.php","line":246,"function":"__construct","class":"OneLogin\\Saml2\\Settings","type":"->"},{"file":"/var/www/nextcloud/24.0.0/lib/private/AppFramework/Http/Dispatcher.php","line":225,"function":"getMetadata","class":"OCA\\User_SAML\\Controller\\SAMLController","type":"->"},{"file":"/var/www/nextcloud/24.0.0/lib/private/AppFramework/Http/Dispatcher.php","line":133,"function":"executeController","class":"OC\\AppFramework\\Http\\Dispatcher","type":"->"},{"file":"/var/www/nextcloud/24.0.0/lib/private/AppFramework/App.php","line":172,"function":"dispatch","class":"OC\\AppFramework\\Http\\Dispatcher","type":"->"},{"file":"/var/www/nextcloud/24.0.0/lib/private/Route/Router.php","line":298,"function":"main","class":"OC\\AppFramework\\App","type":"::"},{"file":"/var/www/nextcloud/24.0.0/lib/base.php","line":1023,"function":"match","class":"OC\\Route\\Router","type":"->"},{"file":"/var/www/nextcloud/24.0.0/index.php","line":36,"function":"handleRequest","class":"OC","type":"::"}],"File":"/var/www/nextcloud/24.0.0/apps/user_saml/3rdparty/vendor/onelogin/php-saml/src/Saml2/Settings.php","Line":141,"CustomMessage":"--"}}

En fait, dans la partie privée, on met son propre certificat généré… mais dans la partie publique, on doit mettre le certificat de keycloak.

Donc premier champ certificat keycloak. Second champ certificat privé.

Avant attribut, on a un autre lien discret, Share optional identity setting… en fait, dans les champs qui précède, on met ce qu'on a généré, et là on met les infos relatives à Keycloak.

Merci à Janik le Suisse pour son aide : https://janikvonrotz.ch/2020/04/21/configure-saml-authentication-for-nextcloud-with-keycloack/

Et là on peut télécharger le metadata xml.

Dans Client → Create → Import → on importe les metadata qu'on a téléchargé, et on touche à rien tout est configuré.

En client ID, on a le lien vers l'application (celle qui apparaît dans les métadata de l'Endpoint). Ne surtout pas le modifier !!!

Tout à l'heure, la fédération était un client openid-connect. Ici on voit la partie SAML.

On va maintenant ajouter les rôles dans keycloak (sachant qu'on a fait un mapping entre les rôles de keycloak et les groupes de Nextcloud).

On ajoute un rôle patata.

Sur notre user, on va dans les roles mapping et on cherche notre client Nextcloud (le lien ID), le rôle patata apparaît.

Mais là, on a toujours pas expliqué à Keycloak qu'il devait mapper les rôles clients à l'attribut rôle. On peut s'assigner le rôle mais c'est tout.

On va dans Client, dans notre attribu et dans Mappers → Create.

On crée un Protocol Mapper auquel on donne le nom username → User Proprety.

Par défaut, Keycloak a quelques user prorpierties qu'il connaît déjà (celles du formulaire du début par exemple). On choisit user name et basic comme saml attribute name format.

On peut créer un autre champ email :

Pour les groupes :

Single role attribute : il va faire autant d'attributs que de rôles.

Maintenant, quand on se déconnecte de Nextcloud, il propose de s'authentifier avec keycloak.

Mais quand on essaie de se connecter, on a une erreur unsupported name format 😢

Là, on s'est pas encore rajouté le rôle patata.

Il y a un wiki avec l'erreur, mais pas de réponse : https://rmm.li/wiki/doku.php?id=linux_server_manuals:nextcloud_saml_authentication_against_keycloak

On force le Name ID dans les settings du client nextcloud. Mais on tombe sur une autre erreur.

Il y a un autre ticket qui en parle https://github.com/nextcloud/user_saml/issues/222 et qui pointe vers un guide https://stackoverflow.com/questions/48400812/sso-with-saml-keycloak-and-nextcloud

Moralité : c'est pénible le SSO.

En vrai, il faut comprendre pourquoi ça marche pas mais après ça marche 😃

On avait une duplication de l'attribut username.

Dans Nextcloud, l'utlisateur a été créé, mais il a tous les rôles. Au lieu du rôle mapper, il fallait faire un role list (dans Create a role mapper).

Dans l'onglet Scope, on décoche la case full scope ce qui permet de réduire les mapper.

Dans Nextcloud, il fallait aussi remplir le champ SLO Single Login

Ce qui est pénible aussi, c'est qu'on peut avoir des clients qui ne supportent pas l'attribut groupe. Par exemple, gitlab, il faut utiliser un ldap pour avoir accès aux groupes.

Souvent, Tharyrok provisionne directement dans gitlab les groupes des utilisateurs, comme ça ils les ont quand ils sont connectés, mais ce n'est pas keycloak qui sait les créer.

Conseil : pour comprendre les protocoles comme saml, openid, toujours conseillé de lire la RFC.

OAuth2 Proxy peut agir comme middleware afin de rendre compatible une application avec Keycloak : https://github.com/oauth2-proxy/oauth2-proxy

Smallstep permet de connecter sur SSH sur du SSO. https://smallstep.com/sso-ssh/

Pour éviter de sccier la branche sur laquelle on est assis, la solution est d'avoir un compte SSH commun, mais dont la clé est dérivée en sous-clés et nécessite plusieurs personnes de l'équipe afin de rassembler suffisamment de segments de clés pour pouvoir se connecter. Si cette méthode d'authentification se produit, supprimer la clé de façon à conscientiser les membres qu'il ne s'agit pas d'une situation normale. https://fr.wikipedia.org/wiki/Partage_de_cl%C3%A9_secr%C3%A8te_de_Shamir

Une autre possibilité pour un service qui ne supporte pas le SSO, utiliser un LDAP. Dans User Federation, on peut d'ailleurs sélectionner LDAP dans keycloak.

Dans ce cas, notre royaume application pourrait gérer du SSO et du LDAP.

Un avantage du LDAP est de provisionner les utilisateurs.

Prochaine réunion

Prochaine réunion hub-infra : 23/07 à 14:00

Lieu : Jitsi & Caldarium

On choisira la date pour la suite de l'atelier keycloak à ce moment-là.

Il restera aussi le Neutriton sur la sécurité à décider.

Météo de fin

Moment informel durant lequel on exprime en peu de mots comment, à titre personnel, la réunion a été vécue que ce soit positif ou négatif. Si une ou plusieurs tension est née durant la réunion, il est peut-être nécessaire d'envisager l'une ou l'autre réunion pour y remédier.

fr/rapports/2022/07-02.txt · Dernière modification : 2022/11/29 10:34 de tharyrok