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.
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.
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
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.