e-Xpert Solutions Lausanne
Auteur : Gilliek
Date de publication : 29 novembre 2017 - Dernière mise à jour : 6 juillet 2018
Dans cet article, nous allons traiter de l’architecture de notre portail d’applications, et plus particulièrement de la partie authentification. Nous allons nous intéresser à tout ce qui a trait à la gestion de l’identité et à l’autorisation. Avant de rentrer dans le vif du sujet, attardons nous un peu sur comment sont organisés notre portail et nos applications. Tout d’abord, nous fonctionnons avec une API REST. Chaque application est en réalité une simple API qui est exposée et l’application web n’est qu’un client de cette API, au même titre que le serait une application mobile Android. Nous avons donc deux parties complètement distinctes et détachées pour chaque application, le backend (API) et le frontend (web app). Afin d’unifier chacun de nos services, nous avons besoin d’un pilier central qui soit capable de gérer la partie identité de nos utilisateurs. Cette application, nommée “Accounts”, se charge de toute la partie authentification, authorization et gestion d’identité de notre portail. Le schema ci-dessous illustre notre portail et ses applications:
Afin de gérer l’accès à nos API, nous avons choisi d’utiliser le protocol OAuth 2.0 et pour la couche identité nous utilisons le protocol OpenID Connect 1.0, basé sur OAuth. Le schema ci-dessous montre de manière abstraite l’idée derrière le protocol OAuth 2.0, c’est-à-dire comment fonctionnent et intéragissent les composants entre eux:
source:digitalocean
Détaillons chaque composant impliqués :
Pour nos Access Tokens et nos ID Tokens nous utilisons JWT (JSON Web Tokens). Un tel jeton est composé de trois parties: l’en-tête (Header), les données (Payload) et d’une signature cryptographique. Les deux premières parties sont au format JSON. Voici un exemple de jeton JWT:
On retrouve dans la partie Header les meta-informations concernant le jeton. Typiquement le type, qui sera “JWT”, ainsi que l’algorithme utilisé pour la signature: HS256 (HMAC SHA 256), signature avec une clé symétrique, ou RS256 (RSA et SHA 256), signature asymétrique. Dans la partie Payload, on a les informations du token. On y retrouve un certain nombre de champs prédéfinis par le standard JWT, tels que l’issuer (iss), la date d’expiration (exp) ou encore l’audience à qui le jeton est destiné (aud). Il est également possible d’ajouter des champs librement (name, admin, etc.). Puis, dans la partie Signature, on a la signature du jeton qui est calculée à partir de la représentation en base 64 du Header et du Payload séparé par un point (“.”). Celle-ci permet entre autre de garantir que le jeton n’a pas été alteré (intégrité). Finalement, chacune des parties est encodée en base 64 et séparée par un point “.”. Le jeton présenté dans l’exemple ci-dessus, donnerait donc:
Revenons sur Oauth et OpenID Connect et sur leurs jetons. L’Access Token contient un champ scope qui définit la portée du jeton, c’est-à-dire ce à quoi l’utilisateur aura accès. Il est transmis à chaque requête à l’API, afin que cette dernière puisse décider si oui ou non elle autorise l’accès à la ressource. Quant à l’ID Token, il est contient un certain nombre d’information sur l’utilisateur. Il va permet à l’application de personnaliser l’interface en fonction de l’utilisateur (nom d’utilisateur, adresse email, administrateur ou simple utilisateur, rôles, etc.). L’utilisation de ces protocoles nous permet d’avoir de manière sûre et efficace l’accès à nos APIs, le tout de manière standardisée. Cela offre également la possibilité à des applications tierces, des scripts ou applications mobiles d’exploiter nos API.
// ServiceAccountTokenGetter defines functions to retrieve a named service account and secret
type ServiceAccountTokenGetter interface {
GetServiceAccount(namespace, name string) (*v1.ServiceAccount, error)
GetPod(namespace, name string) (*v1.Pod, error)
GetSecret(namespace, name string) (*v1.Secret, error)
}
type TokenGenerator interface {
// GenerateToken generates a token which will identify the given
// ServiceAccount. privateClaims is an interface that will be
// serialized into the JWT payload JSON encoding at the root level of
// the payload object. Public claims take precedent over private
// claims i.e. if both claims and privateClaims have an "exp" field,
// the value in claims will be used.
GenerateToken(claims *jwt.Claims, privateClaims interface{}) (string, error)
}
Events
Archives