SCIM 2.0 : Usage avec WSO2 Identity Server [2/2]

Gregory EVE
Smile with WSO2
Published in
6 min readMar 9, 2021

SCIM 2.0 est devenu ces dernières années le standard de référence pour échanger des données d’identités entre domaines et applications. Nous allons dans cette série comprendre ses principes et comment l’utiliser avec WSO2 Identity Server.

Cette série, “SCIM 2.0” est en 2 parties :

1. Initiation au standard

2. Usage avec WSO2 Identity Server

Comment WSO2 l’implémente ?

WSO2 Charon 3

WSO2 Charon est né début 2012, c’est une librairie implémentant les spécifications du standard SCIM.

  • version 1.X et 2.X implémente SCIM 1.0
  • version 3.X implémente SCIM 2.0

WSO2 Charon est composé de 4 modules : Core, Implementation (ex. Deployment), Utils, Samples.

Au sein de WSO2 Identity Server seul le module core est utilisé. C’est lui qui implémente le cœur des spécifications SCIM (gestionnaires de ressources, schémas, opérations, etc.)

SCIM 2.0 Inbound and Outbound connectors

WSO2 Charon est utilisé par deux connecteurs de WSO2 Identity Server:

SCIM 2.0 inbound provisioning
SCIM 2.0 Outbound provisioning

Les 2 connecteurs implémentent et exposent les endpoints en entrée et en sortie et associent les attributs SCIM à leurs équivalents au sein du bus d’identité de WSO2 Identity Server.

Le bus d’identité est le cœur du système d’échange de données du produit. Il relie toutes les sources et destinations. Chaque source et destination n’a pas forcément besoin des mêmes attributs ou ceux-ci ne portent pas forcément le même nom. Le bus va permettre d’associer chaque attribut à un dialecte pivot pour ainsi rendre possible l’échanges de données entre toutes les parties.

Ajout par rapport au standard

WSO2 a ajouté une nouvelle ressource Role pour manipuler les rôles internes du produit à partir de la version 5.11.0.

Avant cette version les rôles étaient confondus avec les groupes.

Comment on le configure?

Claims et schémas SCIM 2.0

WSO2 embarque nativement 3 dialectes de claims concernant SCIM 2.0:

Si vous avez lu le premier article de cette série tout cela doit vous sembler familier.

  • urn:ietf:params:scim:schemas:core:2.0 : associe les attributs communs
  • urn:ietf:params:scim:schemas:core:2.0:User : associe les attributs core User
  • urn:ietf:params:scim:schemas:extension:enterprise:2.0:User : associe les attributs de l’extension EnterpriseUser

Ces claims sont bien beaux mais SCIM 2.0 a une représentation arborescente et non pas à plat, alors comment elle est réalisée?

Pour les attributs core la structure JSON est hardcodé dans la librairie car elle est imposé par le standard vous ne pouvez jouer que sur les associations de claims.

Pour les attributs d’extension la structure est, elle, personnalisable via un fichier de configuration <IS_HOME>/repository/conf/scim2-schema-extension.config.

Attention, le produit ne gère pour le moment que l’extension enterpriseUser et ne permet pas de créer une autre extension personnalisée (voir https://github.com/wso2/charon/pull/283).

Pour chaque attribut nous retrouvons l’association avec le dialecte d’extension (attributeURI), les caractéristiques de l’attribut, et la liste de ses sous-attributs (subAttributes) s’il est de type complex (dataType):

{
"attributeURI":"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:customClaim",
"attributeName":"customClaim",
"dataType":"boolean",
"multiValued":"false",
"description":"customClaim",
"required":"false",
"caseExact":"false",
"mutability":"readwrite",
"returned":"default",
"uniqueness":"none",
"subAttributes":"null",
"canonicalValues":[],
"referenceTypes":[]
}
{ "attributeURI":"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",
"attributeName":"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",
"dataType":"complex",
"multiValued":"false",
"description":"Enterprise User",
"required":"false",
"caseExact":"false",
"mutability":"readWrite",
"returned":"default",
"uniqueness":"none",
"subAttributes":"employeeNumber costCenter organization division department manager customClaim",
"canonicalValues":[],
"referenceTypes":["external"]
}

Résumons! Si vous souhaiter ajouter un nouvel attribut vous devez:

  1. définir un nouveau claim dans le dialect urn:ietf:params:scim:schemas:extension:enterprise:2.0:User et l’associer avec un claim du dialect pivot http://wso2.org/claims.
  2. ajouter l’attribut SCIM dans le fichier scim2-schema-extension.config en l’associant au claim créé précédemment et en le liant à un attribut parent

Attention, il existe une convention implicite, que vous devez absolument respecter, sous peine de voir apparaître des exceptions java. Quand vous définissez le nom de votre claim il doit être formalisé sous forme d’un fil d’Ariane de sa localisation dans l’arborescence JSON de votre schema SCIM.

Par exemple:

urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:manager.displayName

signifie que Display name se trouvera à ce niveau de l’arborescence:

{
"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {
"manager": {
"displayName": "XXX"
}
}
}

Traitement des attributs multivalués

Le support des attributs multivalués SCIM est réalisé de 3 manières selon votre configuration d’attribut et de claim.

  • multivalent avec des primitives :
attribut SCIM 2.0 : 
"emails":[toto@exemple.com, corp@exemple.com]
claim:
urn:ietf:params:scim:schemas:core:2.0:User:emails
  • une seule valeur avec des séparations internes par des virgules (traitement comme monovalent) :
attribut SCIM 2.0 : 
"emails":["toto@exemple.com, corp@exemple.com"]
claims:
urn:ietf:params:scim:schemas:core:2.0:User:emails
urn:ietf:params:scim:schemas:core:2.0:User:emails.default
  • multivalent complexe avec typage des valeurs :
attribut SCIM 2.0 : 
"emails":[{"type":"work","value":"corp@exemple.com"},{"type":"home","value":"toto@exemple.com"}]
claims:
urn:ietf:params:scim:schemas:core:2.0:User:emails
urn:ietf:params:scim:schemas:core:2.0:User:emails.home
urn:ietf:params:scim:schemas:core:2.0:User:emails.work

Attention:

  • la notion de primary, désignant la valeur par défaut d’un attribut multivalué n’est pour le moment pas géré par le produit.
  • l’attribut addresses ne respecte par le standard SCIM 2.0.

Comment on l’utilise?

Pour appeler le service SCIM 2 rien de plus simple! La documentation est par là : https://is.docs.wso2.com/en/latest/develop/using-the-scim-2.0-rest-apis/

Création d’une identité :

curl -X POST https://localhost:9443/scim2/Users \
-H "accept: application/scim+json" \
-H "Content-Type: application/scim+json"
-d '{ "schemas": [], "name": { "firstName": "Kim", "lastName": "Berry" }, "userName": "kim", "password": "abc123", "emails": [ [ { "type": "home", "value": "kim@gmail.com", "primary": true }, { "type": "work", "value": "kim@wso2,com" } ] ], "EnterpriseUser": { "employeeNumber": "1234A", "manager": { "value": "Taylor" } }}'

Consultation d’une identité :

curl -X GET https://localhost:9443/scim2/Me -H "accept: application/scim+json"

Ajouter un utilisateur dans un groupe :

curl -X PATCH \
-H "accept: application/scim+json" \
-H "Content-Type: application/scim+json" \
-d '{ "schemas": [ "urn:ietf:params:scim:api:messages:2.0:PatchOp" ], "Operations": [ { "op": "add", "value": { "members": [ { "display": "kris", "value": "409ca90b-2ba6-4474-9a45-2cf7376e6e43" } ] } } ]}'
https://localhost:9443/scim2/Groups/7bac6a86-1f21-4937-9fb1-5be4a93ef469

Comment sont gérés les accès?

Rien de plus simple : par scope comme toutes les APIs REST du produit !

Pour en savoir plus je vous renvoie vers notre précédente série : Gestion des accès aux APIs REST WSO2

Limitation de l’implémentation?

L’implémentation actuelle n’est pas exempt de tout reproche. A la décharge de l’éditeur, et comme traité dans le premier article de cette série, le standard est difficile à implémenter de manière complète et fonctionnelle pour tous les cas de figures. L’éditeur a un plan de remédiation en cours pour régler au fur et à mesure ces problématiques à court/moyen/long terme.

Les limitations qui doivent être prisent en compte lors de la conception d’un projet sont :

  • l’absence de support de multiples extensions au schema
  • le support partiel du multivalué (notamment dans le cas de addresses et primary)
  • certaines caractéristiques, comme l’unicité, qui ne sont pas implémentées
  • la profondeur de l’arbre JSON limité à 3 niveaux
  • l’absence de support de certains opérateurs de filtre comme le OR
  • une pagination à prendre avec des pincettes (non supporté pas le standard LDAP donc simulé sur un userstore LDAP par exemple)
  • l’absence de configuration des extensions par tenant
  • des performances qui laissent à désirer notamment quand on manipule de larges groupes. (le standard semble intrinsèquement mal conçu pour ce type d’usage, notamment avec la présence de l’attribut members dont rien empêche la présence d’1 million d’entrées)
  • La validation des entrées perfectibles
  • La gestion d’erreur rendant difficile la compréhension des problèmes (des améliorations sont à noter dans les dernières versions)
  • le parsing et la validation des filtres qui mériterait d’être réalisé avec une framework tel que ANTLR

--

--

Gregory EVE
Smile with WSO2

Solution Architect at Smile, french lover and open source supporter. Integrate, Search, Leverage and Secure your data what else?