Go to Hackademy website

Administration des accès Doorkeeper

Numa Claudel

Posté par Numa Claudel dans les catégories outils

Cet article est publié sous licence CC BY-NC-SA

Doorkeeper est un provider OAuth 2 pour votre application Rails. Ce provider sert à définir un SSO (Single Sign On) permettant à un utilisateur de se connecter une fois pour toutes sur les applications auxquelles il a accès.

La mise en place d’un SSO nécessite un dialogue entre vos applications clientes et votre provider pour savoir si l’utilisateur doit se connecter ou s’il l’est déjà. Bien entendu ces échanges doivent se faire en toute transparence pour celui-ci. Si vous souhaitez en savoir plus, je vous laisse consulter la présentation de Martin à ce sujet.

Doorkeeper se chargeant de la machinerie coté provider, la mise en place d’un SSO en est grandement simplifié, d’autant plus que Doorkeeper ne se contente pas de gérer les authentifications utilisateurs, mais gère aussi les applications à partir desquelles les utilisateurs pourront se connecter. Une interface est d’ailleurs dédiée à la création / modification / suppression d’applications.

Les autorisations d’accès entre utilisateurs et applications sont aussi de la partie, mais par défaut c’est l’utilisateur lui même qui s’autorise à accéder à une application. Le but de cet article est donc d’aborder une solution pour ne permettre cette gestion des applications et des accès qu’à un administrateur.

Installer Doorkeeper dans l’application

Comme indiqué sur leur Github, ajoutez au Gemfile :

gem 'doorkeeper'

Un bundle, puis exécutez :

rails generate doorkeeper:install

Cette commande aura pour effet de générer un fichier config/initializers/doorkeeper.rb, ainsi que d’ajouter use_doorkeeper à votre fichier de routes. Vous avez donc maintenant une liste de routes générées par Doorkeeper, que nous modifierons pour l’adapter à nos besoins.

GET       /oauth/authorize/:code
GET       /oauth/authorize
POST      /oauth/authorize
DELETE    /oauth/authorize
POST      /oauth/token
POST      /oauth/revoke
resources /oauth/applications
GET       /oauth/authorized_applications
DELETE    /oauth/authorized_applications/:id
GET       /oauth/token/info

Enfin utilisez cette commande pour générer la migration :

rails generate doorkeeper:migration

Cette migration créera trois tables oauth_access_grants, oauth_access_tokens et oauth_applications, qui servent respectivement à la gestion des autorisations d’accès, des jetons d’accès et des applications. Un accès autorisé à une application pour un utilisateur est représenté par une entrée dans la table oauth_access_grants. Lorsque l’utilisateur essaye de se connecter par le biais d’une application, Doorkeeper regarde donc si un accès existe entre cet utilisateur et cette application. Si c’est le cas, alors un jeton d’accès est généré pour une certaine durée. Une entrée est alors créée dans la table oauth_access_tokens avec ces données.

Il ne reste plus qu’à ajouter une migration pour la table users et nous en avons fini pour la partie préparation.

Modifier le comportement par défaut

Les modifications vont consister à remplacer le contrôleur Authorizations de Doorkeeper ainsi que les routes qui correspondent.

Commencez par ajouter un dossier oauth au dossier controllers dans lequel vous ajoutez un contrôleur Authorizations :

module Oauth
  class AuthorizationsController < Doorkeeper::AuthorizationsController

  end
end

L’administrateur doit pouvoir créer des accès et les supprimer, il faut alors définir les méthodes create et destroy. Doorkeeper::AccessGrant est le modèle qui sert à la gestion des autorisations :

def create
  @access_grant = Doorkeeper::AccessGrant.where(access_grant_params).first_or_initialize
  @access_grant.redirect_uri = @access_grant.application.try(:redirect_uri)
  @access_grant.expires_in = 0 # access granted until deleted

  if @access_grant.save
    redirect_to :back
  else
    render :edit
  end
end

def destroy
  @access_grant = Doorkeeper::AccessGrant.find(params[:id])
  @access_grant.destroy
  redirect_to :back
end

private

def access_grant_params
  params.require(:doorkeeper_access_grant).permit(:application_id, :resource_owner_id)
end

Pour commencer, réutilisez un accès s’il a déjà été défini, de cette manière l’administrateur crée un accès pour un utilisateur ou le retire. Il n’est pas nécessaire de gérer plusieurs accès à une application par utilisateur, ce qui est le cas de base avec Doorkeeper. Ensuite redirect_uri et expires_in étant deux attributs obligatoires, le redirect_uri de l’accès sera le même que celui de l’application et attribuons à expires_in la valeur 0. expires_in est utilisé de base par Doorkeeper pour limiter la durée des autorisations. Pour nous, cet attribut ne nous servant pas, la valeur 0 sert seulement à indiquer que l’accès n’a pas de limite de durée.

Enfin pensez à bien faire parvenir au contrôleur les deux paramètres qui vont servir à créer l’autorisation, à savoir application_id et resource_owner_id.

Il faut maintenant indiquer à Doorkeeper d’utiliser notre contrôleur Authorizations :

use_doorkeeper do
  controllers authorizations: "oauth/authorizations"
end

Conclusion

Nous avons maintenant un SSO géré par un administrateur et les utilisateurs n’ont plus qu’à se connecter par le biais des applications auxquelles ils ont accès, ou bien de cliquer sur le lien d’une des applications parmi la liste qui leur sera affichée après connexion directe au SSO.

Je n’ai pas traité ici la partie authentification, car mon but était de vous donner une manière d’adapter Doorkeeper pour ajouter la notion d’administration des accès au provider. Mais cela pourra faire l’objet d’un prochain article.

L’équipe Synbioz.

Libres d’être ensemble.

Articles connexes

Git mailmap ou comment identifier les contributeurs d'un projet

27/11/2020

Vous êtes-vous déjà demandé, après avoir lancé un git blame sur un fichier, qui est le collègue qui se cache derrière cet obscur pseudo ? Vous est-il déjà arrivé de pousser un commit avec une...

Linux sur mobile, enfin ?

24/07/2020

En 2017 Purism réussi un financement participatif pour son nouveau produit le Librem 5. L’idée est d’avoir un smartphone centré sur la protection de la vie privée et fonctionnant avec des logiciels...

Linux Open : Ou comment automatiser des trucs simples

23/04/2020

Hey Reed ! Je viens de jouer à un super jeu. Tu connais ? https://www.youtube.com/watch?v=fWlHjpKmvh8 Je clique, ça s’ouvre sur mon navigateur web. Mhhh… Pourquoi mon environnement ne l’ouvre-t-il...

Facilitez-vous les tests avec Wiremock !

26/03/2020

Il arrive parfois que les applications que nous développons soient dépendantes d’autres applications ou API.