Tutoriel : Développer et planifier le provisionnement d’un point de terminaison SCIM dans Azure Active Directory

En tant que développeur d'applications, vous pouvez utiliser l'API de gestion des utilisateurs SCIM (System for Cross-Domain Identity Management) pour permettre le provisionnement automatique des utilisateurs et des groupes entre votre application et Azure Active Directory (Azure AD). Cet article explique comment créer un point de terminaison SCIM et l'intégrer au service d'approvisionnement Azure AD. La spécification SCIM fournit un schéma utilisateur commun pour l’approvisionnement. Utilisé avec des normes de fédération telles que SAML ou OpenID Connect, SCIM offre aux administrateurs une solution de bout en bout, fondée sur des normes, pour la gestion des accès.

Approvisionnement d'Azure AD vers une application avec SCIM

SCIM 2.0 est une définition normalisée de deux points d'extrémité : un point d'extrémité /Users et un point d'extrémité/Groups. Il utilise les points de terminaison courants de l'API REST pour créer, mettre à jour et supprimer des objets. Le SCIM consiste en un schéma prédéfini pour les attributs communs tels que le nom de groupe, le nom d'utilisateur, le prénom, le nom de famille et l'adresse électronique.

Les applications proposant une API REST SCIM 2.0 peuvent réduire ou éliminer les difficultés liées à l’utilisation d’une API de gestion des utilisateurs propriétaires. Par exemple, tout client SCIM conforme sait comment effectuer une requête HTTP POST d’objet JSON sur le point de terminaison /Users pour créer une entrée d’utilisateur. Sans devoir utiliser une API légèrement différente pour les mêmes actions de base, les applications conformes à la norme SCIM peuvent instantanément tirer parti des clients, des outils et du code existants.

Le schéma d’objet utilisateur standard et les API REST de gestion définies dans SCIM 2.0 (RFC 7642, 7643, 7644) permettent aux fournisseurs d’identité et aux applications de s’intégrer plus facilement entre eux. Les développeurs d’applications qui créent un point de terminaison SCIM peuvent s’intégrer à n’importe quel client conforme à SCIM sans avoir à effectuer de travail personnalisé.

Pour automatiser l’approvisionnement d’une application, il nécessite la création et l’intégration d’un point de terminaison SCIM qui est accessible par le service d’approvisionnement Azure AD. Effectuez les étapes suivantes pour commencer à provisionner des utilisateurs et des groupes dans votre application.

  1. Concevoir votre schéma d'utilisateurs et de groupes - Identifiez les objets et les attributs de l'application pour déterminer comment ils correspondent au schéma d'utilisateurs et de groupes pris en charge par l'implémentation Azure AD SCIM.

  2. Comprendre l’implémentation SCIM d’Azure AD : découvrez comment le service d’approvisionnement Azure AD est implémenté pour modéliser la gestion et les réponses de vos demandes de protocole SCIM.

  3. Construire un point de terminaison SCIM - Un point de terminaison doit être compatible avec SCIM 2.0 pour s'intégrer au service de provisionnement Azure AD. Vous pouvez utiliser des bibliothèques Microsoft Common Language Infrastructure (CLI) et des exemples de code pour créer votre point de terminaison. Ces exemples sont fournis à des fins de référence et de test uniquement. Nous vous déconseillons de les utiliser comme des dépendances dans votre application de production.

  4. Intégrez votre point de terminaison SCIM au service Azure AD Provisioning. Si votre organisation utilise une application tierce pour implémenter un profil SCIM°2.0 pris en charge par Azure AD, vous pouvez automatiser rapidement le provisionnement et le déprovisionnement d’utilisateurs et de groupes.

  5. [Facultatif] Publiez votre application dans la galerie d’applications Azure AD - facilitez la découverte de votre application et la configuration facile de l’approvisionnement.

Diagramme indiquant les étapes nécessaires à l'intégration d'un terminal SCIM avec Azure AD.

Concevoir votre schéma d'utilisateurs et de groupes

Chaque application nécessite des attributs différents pour créer un utilisateur ou un groupe. Commencez votre intégration en identifiant les objets (utilisateurs, groupes) et attributs (nom, responsable, fonction, etc.) nécessaires à votre application.

La norme SCIM définit un schéma pour la gestion des utilisateurs et des groupes.

Le schéma utilisateur core ne nécessite que trois attributs (tous les autres attributs sont facultatifs) :

  • id, identificateur défini par le fournisseur de services
  • userName, identificateur unique de l’utilisateur (mappe généralement au nom d’utilisateur principal Azure AD)
  • meta, métadonnées en lecture seule gérées par le fournisseur de services

Outre le schéma utilisateur core, la norme SCIM définit une extension utilisateur enterprise avec un modèle permettant d’étendre le schéma utilisateur en fonction des besoins de votre application.

Par exemple, si votre application exige à la fois l’adresse e-mail de l’utilisateur et le responsable de l’utilisateur, utilisez le schéma utilisateur core pour collecter l’adresse e-mail, et le schéma utilisateur enterprise pour collecter le responsable.

Pour concevoir votre schéma, effectuez les étapes suivantes :

  1. Répertoriez les attributs requis par votre application, puis catégorisez en tant qu’attributs nécessaires pour l’authentification (par exemple, loginName et e-mail). Les attributs sont nécessaires pour gérer le cycle de vie de l’utilisateur (par exemple, état/actif) et tous les autres attributs nécessaires pour que l’application fonctionne (par exemple, gestionnaire, balise).

  2. Vérifiez si ces attributs sont déjà définis dans le schéma utilisateur core ou le schéma utilisateur enterprise. Si ce n’est pas le cas, vous devez définir une extension pour le schéma utilisateur afin d’inclure les attributs manquants. Pour voir une extension utilisateur permettant de provisionner un tag utilisateur, consultez l’exemple ci-dessous.

  3. Mappez les attributs SCIM aux attributs d’utilisateur dans Azure AD. Si l’un des attributs que vous avez définis dans votre point de terminaison SCIM n’a pas d’équivalent clair dans le schéma utilisateur Azure AD, expliquez à l’administrateur de locataire comment étendre son schéma ou utiliser un attribut d’extension, comme indiqué ci-dessous pour la propriété tags.

Le tableau suivant répertorie un exemple d’attributs requis :

Attribut d’application obligatoire Attribut SCIM mappé Attribut Azure AD mappé
loginName userName userPrincipalName
firstName name.givenName givenName
lastName name.familyName surName
workMail emails[type eq “work”].value Messagerie
manager manager manager
tag urn:ietf:params:scim:schemas:extension:CustomExtensionName:2.0:User:tag extensionAttribute1
status active isSoftDeleted (valeur calculée non stockée sur l’utilisateur)

La charge utile JSON suivante montre un exemple de schéma SCIM :

{
     "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User",
      "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",
      "urn:ietf:params:scim:schemas:extension:CustomExtensionName:2.0:User"],
     "userName":"bjensen@testuser.com",
     "id": "48af03ac28ad4fb88478",
     "externalId":"bjensen",
     "name":{
       "familyName":"Jensen",
       "givenName":"Barbara"
     },
     "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {
     "Manager": "123456"
   },
     "urn:ietf:params:scim:schemas:extension:CustomExtensionName:2.0:User": {
     "tag": "701984",
   },
   "meta": {
     "resourceType": "User",
     "created": "2010-01-23T04:56:22Z",
     "lastModified": "2011-05-13T04:42:34Z",
     "version": "W\/\"3694e05e9dff591\"",
     "location":
 "https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646"
   }
}   

Notes

En plus des attributs exigés par l’application, la représentation JSON contient également les attributs obligatoires id, externalId et meta.

Cela permet de les classer dans les catégories /User et /Group en vue de mapper les attributs utilisateur par défaut entre Azure AD et le RFC SCIM. Pour plus d’informations, découvrez comment les attributs personnalisés sont mappés entre Azure AD et votre point de terminaison SCIM.

Le tableau suivant présente un exemple d'attributs d'utilisateur :

Utilisateur Azure AD urn:ietf:params:scim:schemas:extension:enterprise:2.0:User
IsSoftDeleted active
department urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department
displayName displayName
employeeId urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:employeeNumber
Facsimile-TelephoneNumber phoneNumbers[type eq "fax"].value
givenName name.givenName
jobTitle title
mail emails[type eq "work"].value
mailNickName externalId
manager urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:manager
mobile phoneNumbers[type eq "mobile"].value
postalCode addresses[type eq "work"].postalCode
proxy-Addresses emails[type eq "other"].Value
physical-Delivery-OfficeName addresses[type eq "other"].Formatted
streetAddress addresses[type eq "work"].streetAddress
surname name.familyName
telephone-Number phoneNumbers[type eq "work"].value
user-PrincipalName userName

Le tableau suivant donne un exemple d'attributs de groupe :

Groupe Azure AD urn:ietf:params:scim:schemas:core:2.0:Group
displayName displayName
membres membres
objectId externalId

Notes

Il n’est pas nécessaire de prendre en charge à la fois les utilisateurs et les groupes, ou tous les attributs indiqués ici. Nous montrons simplement comment les attributs Azure AD sont souvent mappés aux propriétés du protocole SCIM.

Plusieurs points de terminaison sont définis dans la RFC SCIM. Vous pouvez commencer avec le point de terminaison /User, puis développer à partir de celui-ci. Le tableau suivant répertorie certains points de terminaison SCIM :

Point de terminaison Description
/User Permet d’effectuer des opérations CRUD sur un objet utilisateur.
/Group Permet d’effectuer des opérations CRUD sur un objet groupe.
/Schemas L’ensemble des attributs pris en charge par chaque client et chaque fournisseur de services peut varier. Un fournisseur de services peut inclure name, title et emails, tandis qu’un autre fournisseur de services utilise name, title et phoneNumbers. Le point de terminaison /Schemas permet la découverte des attributs pris en charge.
/Bulk Les opérations en bloc vous permettent d’effectuer des opérations sur un grand nombre d’objets ressource à la fois (par exemple, pour mettre à jour les appartenances dans un grand groupe).
/ServiceProviderConfig Fournit des détails sur les fonctionnalités de la norme SCIM prises en charge, par exemple les ressources prises en charge et la méthode d’authentification.
/ResourceTypes Spécifie les métadonnées relatives à chaque ressource.

Notes

Utilisez le point de terminaison /Schemas pour prendre en charge les attributs personnalisés. Vous pouvez également l’utiliser si votre schéma change fréquemment, car il permet à un client de récupérer automatiquement le schéma le plus à jour. Utilisez le point de terminaison /Bulk pour prendre en charge les groupes.

Comprendre l'implémentation de SCIM Azure AD

Pour prendre en charge une API de gestion des utilisateurs SCIM 2.0, cette section décrit la mise en œuvre du service d'approvisionnement Azure AD et montre comment modéliser le traitement des demandes et des réponses du protocole SCIM.

Important

La dernière mise à jour du comportement de l’implémentation SCIM d’Azure AD a été effectuée le 18 décembre 2018. Pour plus d’informations sur ce qui a changé, consultez Conformité au protocole SCIM 2.0 du service de provisionnement des utilisateurs Azure AD.

Dans la spécification du protocole SCIM 2.0, votre application doit satisfaire aux conditions suivantes :

Condition requise Notes de référence (protocole SCIM)
Créer des utilisateurs, et facultativement des groupes Section 3.3
Modifier des utilisateurs ou des groupes avec des requêtes PATCH Section 3.5.2. La prise en charge garantit que les groupes et les utilisateurs sont provisionnés de manière performante.
Récupérer une ressource connue pour un utilisateur ou un groupe créé précédemment Section 3.4.1
Interroger des utilisateurs ou des groupes Section 3.4.2. Par défaut, les utilisateurs sont récupérés par leur id et interrogés via leur username et externalId, et les groupes sont interrogés via displayName.
Le filtre excludedAttributes=members lors de l’interrogation de la ressource de groupe Section 3.4.2.2.
Prendre en charge la création d’une liste d’utilisateurs et la pagination Section 3.4.2.4.
Suppression réversible d’un utilisateur active=false et restauration de l’utilisateur active=true. L’objet utilisateur doit être retourné dans une requête, que l’utilisateur soit actif ou non. La seule fois où l’utilisateur ne doit pas être retourné est lorsqu’il est supprimé définitivement de l’application.
Prendre en charge le point de terminaison /Schemas Section 7 Le point de terminaison de découverte de schéma est utilisé pour découvrir des attributs supplémentaires.
Acceptation d’un jeton du porteur unique pour l’authentification et l’autorisation d’Azure AD dans votre application.

Suivez ces recommandations lors de l’implémentation d’un point de terminaison SCIM pour garantir la compatibilité avec Azure AD :

Général :

  • id est une propriété obligatoire pour toutes les ressources. Chaque réponse qui retourne une ressource doit garantir que chaque ressource dispose de cette propriété, sauf pour ListResponse sans élément.
  • Les valeurs envoyées doivent être stockées dans le même format que celui dans lequel elles ont été envoyées. Les valeurs non valides doivent être rejetées avec un message d’erreur descriptif et exploitable. Les transformations de données ne doivent pas se produire entre les données envoyées par Azure AD et les données stockées dans l’application SCIM. (par exemple. Un numéro de téléphone envoyé comme 55555555555 ne doit pas être enregistré/retourné sous la forme + 5 (555) 555-5555)
  • Il n’est pas nécessaire d’inclure la ressource entière dans la réponse PATCH.
  • N’exigez pas un respect de la casse pour les éléments structurels SCIM, en particulier pour les valeurs d’opération PATCHop, comme défini dans la section 3.5.2. Azure AD émet les valeurs de op ainsi : Ajouter, Remplacer et Supprimer.
  • Microsoft Azure AD effectue des requêtes pour extraire un utilisateur et un groupe aléatoires pour vous assurer que le point de terminaison et les informations d’identification sont valides. C’est également fait dans le cadre d’un flux de Connexion test dans le portail Azure.
  • Prenez en charge HTTPS sur votre point de terminaison SCIM.
  • Les attributs complexes et à valeurs multiples personnalisés sont pris en charge, mais Azure AD ne dispose pas de nombreuses structures de données complexes pour extraire des données dans ces cas. Les attributs complexes de type nom/valeur en paires simples peuvent être mappés facilement, mais la circulation d’attributs complexes avec au moins trois sous-attributs n’est pas bien prise en charge pour le moment.
  • Les valeurs de sous-attribut « type » des attributs complexes à valeurs multiples doivent être uniques. Par exemple, il ne peut pas y avoir deux adresses e-mail différentes avec le sous-type « work ».
  • L’en-tête de toutes les réponses doit être de type « content » : application/scim+json

Récupération de ressources :

/Users :

  • L’attribut de droit n’est pas pris en charge.
  • Tous les attributs pris en compte pour l’unicité de l’utilisateur doivent être utilisables dans le cadre d’une requête filtrée. (par exemple, si l’unicité de l’utilisateur est évaluée pour userName et emails[type eq "work"], un GET sur /Users avec un filtre doit permettre les requêtes userName eq "user@contoso.com" et emails[type eq "work"].value eq "user@contoso.com".

/Groups :

  • Les groupes sont facultatifs et uniquement pris en charge si l’implémentation SCIM prend en charge les requêtes PATCH.
  • Les groupes doivent avoir unicité sur la valeur « displayName » pour qu’ils correspondent à Azure AD et à l’application SCIM. L'unicité n'est pas une exigence du protocole SCIM, mais une exigence pour l'intégration d'un point de terminaison SCIM avec Azure AD.

/Schemas (découverte de schéma) :

  • Exemple de demande/réponse
  • La découverte de schéma n’est pas actuellement prise en charge sur l’application hors galerie personnalisée, mais elle est utilisée sur certaines applications de la galerie. À l’avenir, la découverte de schéma sera la seule méthode utilisée pour ajouter des attributs supplémentaires au schéma d’une application SCIM de la galerie existante.
  • Si une valeur n’est pas présente, n’envoyez pas de valeurs Null.
  • Utilisez une casse mixte pour les valeurs de propriété (par exemple, readWrite).
  • Doit retourner une réponse de liste.
  • La requête /schémas sera effectuée par le service de provisionnement Azure AD chaque fois qu'une personne enregistre la configuration de provisionnement dans le portail Azure ou chaque fois qu'un utilisateur accède à la page de modification du provisionnement dans le portail Azure. Les autres attributs découverts seront présentés aux clients dans les mappages d'attributs sous la liste des attributs cibles. La découverte de schémas ne fait qu'entraîner l'ajout de nouveaux attributs cibles. Elle n’entraîne pas la suppression d’attributs.

Approvisionnement et déprovisionnement d'utilisateurs

Le diagramme suivant montre les messages qu'Azure AD envoie à un point de terminaison SCIM pour gérer le cycle de vie d'un utilisateur dans le magasin d'identité de votre application.

Diagramme qui montre la séquence de déprovisionnement des utilisateurs.

Approvisionnement et déprovisionnement de groupes

L’approvisionnement et le déprovisionnement de groupes sont facultatifs. Lorsqu'elle est mise en œuvre et activée, l'illustration suivante montre les messages qu'Azure AD envoie à un point de terminaison SCIM pour gérer le cycle de vie d'un groupe dans le magasin d'identité de votre application. Ces messages diffèrent des messages concernant les utilisateurs de deux manières :

  • Les demandes d’extraction de groupes précisent que l’attribut des membres doit être exclu des ressources fournies en réponse à la demande.
  • Les requêtes permettant de déterminer si un attribut de référence a une certaine valeur sont des requêtes sur les attributs membres.

Le diagramme suivant montre la séquence de déprovisionnement de groupe :

Diagramme qui montre la séquence de déprovisionnement du groupe.

Demandes et réponses du protocole SCIM

Cet article fournit des exemples de demandes SCIM émises par le service d’approvisionnement Azure Active Directory (Azure AD) et des exemples de réponses attendues. Pour de meilleurs résultats, vous devez coder votre application pour gérer ces demandes dans ce format et émettre les réponses attendues.

Important

Pour comprendre comment et quand le service d'approvisionnement d'utilisateurs d'Azure AD émet les opérations décrites ci-dessous, consultez la section Cycles d'approvisionnement : cycle initial et cycle incrémentiel de l'article Fonctionnement de l'approvisionnement.

Opérations utilisateur

Opérations de groupe

Découverte de schéma

Opérations utilisateur

  • Les utilisateurs peuvent être interrogés via les attributs userName ou emails[type eq "work"].

Create User

Requête

POST /Users

{
    "schemas": [
        "urn:ietf:params:scim:schemas:core:2.0:User",
        "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"],
    "externalId": "0a21f0f2-8d2a-4f8e-bf98-7363c4aed4ef",
    "userName": "Test_User_ab6490ee-1e48-479e-a20b-2d77186b5dd1",
    "active": true,
    "emails": [{
        "primary": true,
        "type": "work",
        "value": "Test_User_fd0ea19b-0777-472c-9f96-4f70d2226f2e@testuser.com"
    }],
    "meta": {
        "resourceType": "User"
    },
    "name": {
        "formatted": "givenName familyName",
        "familyName": "familyName",
        "givenName": "givenName"
    },
    "roles": []
}
response

HTTP/1.1 201 Created

{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
    "id": "48af03ac28ad4fb88478",
    "externalId": "0a21f0f2-8d2a-4f8e-bf98-7363c4aed4ef",
    "meta": {
        "resourceType": "User",
        "created": "2018-03-27T19:59:26.000Z",
        "lastModified": "2018-03-27T19:59:26.000Z"
    },
    "userName": "Test_User_ab6490ee-1e48-479e-a20b-2d77186b5dd1",
    "name": {
        "formatted": "givenName familyName",
        "familyName": "familyName",
        "givenName": "givenName",
    },
    "active": true,
    "emails": [{
        "value": "Test_User_fd0ea19b-0777-472c-9f96-4f70d2226f2e@testuser.com",
        "type": "work",
        "primary": true
    }]
}

Obtenir un utilisateur

Requête

GET /Users/5d48a0a8e9f04aa38008

Réponse (Utilisateur trouvé)

HTTP/1.1 200 OK

{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
    "id": "5d48a0a8e9f04aa38008",
    "externalId": "58342554-38d6-4ec8-948c-50044d0a33fd",
    "meta": {
        "resourceType": "User",
        "created": "2018-03-27T19:59:26.000Z",
        "lastModified": "2018-03-27T19:59:26.000Z"
    },
    "userName": "Test_User_feed3ace-693c-4e5a-82e2-694be1b39934",
    "name": {
        "formatted": "givenName familyName",
        "familyName": "familyName",
        "givenName": "givenName",
    },
    "active": true,
    "emails": [{
        "value": "Test_User_22370c1a-9012-42b2-bf64-86099c2a1c22@testuser.com",
        "type": "work",
        "primary": true
    }]
}
Requête

GET /Users/5171a35d82074e068ce2

Réponse (Utilisateur non trouvé. Le détail n'est pas requis, seulement le statut).
{
    "schemas": [
        "urn:ietf:params:scim:api:messages:2.0:Error"
    ],
    "status": "404",
    "detail": "Resource 23B51B0E5D7AE9110A49411D@7cca31655d49f3640a494224 not found"
}

Obtenir un utilisateur par requête

Requête

GET /Users?filter=userName eq "Test_User_dfeef4c5-5681-4387-b016-bdf221e82081"

response

HTTP/1.1 200 OK

{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
    "totalResults": 1,
    "Resources": [{
        "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
        "id": "2441309d85324e7793ae",
        "externalId": "7fce0092-d52e-4f76-b727-3955bd72c939",
        "meta": {
            "resourceType": "User",
            "created": "2018-03-27T19:59:26.000Z",
            "lastModified": "2018-03-27T19:59:26.000Z"
            
        },
        "userName": "Test_User_dfeef4c5-5681-4387-b016-bdf221e82081",
        "name": {
            "familyName": "familyName",
            "givenName": "givenName"
        },
        "active": true,
        "emails": [{
            "value": "Test_User_91b67701-697b-46de-b864-bd0bbe4f99c1@testuser.com",
            "type": "work",
            "primary": true
        }]
    }],
    "startIndex": 1,
    "itemsPerPage": 20
}

Obtenir un utilisateur par requête - sans résultat

Requête

GET /Users?filter=userName eq "non-existent user"

response

HTTP/1.1 200 OK

{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
    "totalResults": 0,
    "Resources": [],
    "startIndex": 1,
    "itemsPerPage": 20
}

Mettre à jour un utilisateur [Propriétés à plusieurs valeurs]

Requête

PATCH /Users/6764549bef60420686bc HTTP/1.1

{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [
            {
            "op": "Replace",
            "path": "emails[type eq \"work\"].value",
            "value": "updatedEmail@microsoft.com"
            },
            {
            "op": "Replace",
            "path": "name.familyName",
            "value": "updatedFamilyName"
            }
    ]
}
response

HTTP/1.1 200 OK

{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
    "id": "6764549bef60420686bc",
    "externalId": "6c75de36-30fa-4d2d-a196-6bdcdb6b6539",
    "meta": {
        "resourceType": "User",
        "created": "2018-03-27T19:59:26.000Z",
        "lastModified": "2018-03-27T19:59:26.000Z"
    },
    "userName": "Test_User_fbb9dda4-fcde-4f98-a68b-6c5599e17c27",
    "name": {
        "formatted": "givenName updatedFamilyName",
        "familyName": "updatedFamilyName",
        "givenName": "givenName"
    },
    "active": true,
    "emails": [{
        "value": "updatedEmail@microsoft.com",
        "type": "work",
        "primary": true
    }]
}

Mettre à jour un utilisateur [Propriétés à une seule valeur]

Requête

PATCH /Users/5171a35d82074e068ce2 HTTP/1.1

{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [{
        "op": "Replace",
        "path": "userName",
        "value": "5b50642d-79fc-4410-9e90-4c077cdd1a59@testuser.com"
    }]
}
response

HTTP/1.1 200 OK

{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
    "id": "5171a35d82074e068ce2",
    "externalId": "aa1eca08-7179-4eeb-a0be-a519f7e5cd1a",
    "meta": {
        "resourceType": "User",
        "created": "2018-03-27T19:59:26.000Z",
        "lastModified": "2018-03-27T19:59:26.000Z"
        
    },
    "userName": "5b50642d-79fc-4410-9e90-4c077cdd1a59@testuser.com",
    "name": {
        "formatted": "givenName familyName",
        "familyName": "familyName",
        "givenName": "givenName",
    },
    "active": true,
    "emails": [{
        "value": "Test_User_49dc1090-aada-4657-8434-4995c25a00f7@testuser.com",
        "type": "work",
        "primary": true
    }]
}

Désactiver l’utilisateur

Requête

PATCH /Users/5171a35d82074e068ce2 HTTP/1.1

{
    "Operations": [
        {
            "op": "Replace",
            "path": "active",
            "value": false
        }
    ],
    "schemas": [
        "urn:ietf:params:scim:api:messages:2.0:PatchOp"
    ]
}
response
{
    "schemas": [
        "urn:ietf:params:scim:schemas:core:2.0:User"
    ],
    "id": "CEC50F275D83C4530A495FCF@834d0e1e5d8235f90a495fda",
    "userName": "deanruiz@testuser.com",
    "name": {
        "familyName": "Harris",
        "givenName": "Larry"
    },
    "active": false,
    "emails": [
        {
            "value": "gloversuzanne@testuser.com",
            "type": "work",
            "primary": true
        }
    ],
    "addresses": [
        {
            "country": "ML",
            "type": "work",
            "primary": true
        }
    ],
    "meta": {
        "resourceType": "Users",
        "location": "/scim/5171a35d82074e068ce2/Users/CEC50F265D83B4530B495FCF@5171a35d82074e068ce2"
    }
}

Supprimer l'utilisateur

Requête

DELETE /Users/5171a35d82074e068ce2 HTTP/1.1

response

HTTP/1.1 204 No Content

Opérations de groupe

  • Les groupes doivent toujours être créés avec une liste de membre vide.
  • Les groupes peuvent être interrogés via l’attribut displayName.
  • La mise à jour de la requête PATCH de groupe doit renvoyer HTTP 204 No Content dans la réponse. Il n’est pas conseillé de renvoyer un corps avec une liste de tous les membres.
  • Il n’est pas nécessaire de prendre en charge le renvoi de tous les membres du groupe.

Créer un groupe

Requête

POST /Groups HTTP/1.1

{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group", "http://schemas.microsoft.com/2006/11/ResourceManagement/ADSCIM/2.0/Group"],
    "externalId": "8aa1a0c0-c4c3-4bc0-b4a5-2ef676900159",
    "displayName": "displayName",
    "meta": {
        "resourceType": "Group"
    }
}
response

HTTP/1.1 201 Created

{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
    "id": "927fa2c08dcb4a7fae9e",
    "externalId": "8aa1a0c0-c4c3-4bc0-b4a5-2ef676900159",
    "meta": {
        "resourceType": "Group",
        "created": "2018-03-27T19:59:26.000Z",
        "lastModified": "2018-03-27T19:59:26.000Z"
        
    },
    "displayName": "displayName",
    "members": []
}

Obtenir un groupe

Requête

GET /Groups/40734ae655284ad3abcc?excludedAttributes=members HTTP/1.1

response

HTTP/1.1 200 OK

{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
    "id": "40734ae655284ad3abcc",
    "externalId": "60f1bb27-2e1e-402d-bcc4-ec999564a194",
    "meta": {
        "resourceType": "Group",
        "created": "2018-03-27T19:59:26.000Z",
        "lastModified": "2018-03-27T19:59:26.000Z"
    },
    "displayName": "displayName",
}

Obtenir un groupe par displayName

Requête

GET /Groups?excludedAttributes=members&filter=displayName eq "displayName" HTTP/1.1

response

HTTP/1.1 200 OK

{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
    "totalResults": 1,
    "Resources": [{
        "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
        "id": "8c601452cc934a9ebef9",
        "externalId": "0db508eb-91e2-46e4-809c-30dcbda0c685",
        "meta": {
            "resourceType": "Group",
            "created": "2018-03-27T22:02:32.000Z",
            "lastModified": "2018-03-27T22:02:32.000Z",
            
        },
        "displayName": "displayName",
    }],
    "startIndex": 1,
    "itemsPerPage": 20
}

Mettre à jour un groupe [Attributs non membre]

Requête

PATCH /Groups/fa2ce26709934589afc5 HTTP/1.1

{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [{
        "op": "Replace",
        "path": "displayName",
        "value": "1879db59-3bdf-4490-ad68-ab880a269474updatedDisplayName"
    }]
}
response

HTTP/1.1 204 No Content

Mettre à jour un groupe [Ajouter des membres]

Requête

PATCH /Groups/a99962b9f99d4c4fac67 HTTP/1.1

{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [{
        "op": "Add",
        "path": "members",
        "value": [{
            "$ref": null,
            "value": "f648f8d5ea4e4cd38e9c"
        }]
    }]
}
response

HTTP/1.1 204 No Content

Mettre à jour un groupe [Supprimer des membres]

Requête

PATCH /Groups/a99962b9f99d4c4fac67 HTTP/1.1

{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [{
        "op": "Remove",
        "path": "members",
        "value": [{
            "$ref": null,
            "value": "f648f8d5ea4e4cd38e9c"
        }]
    }]
}
response

HTTP/1.1 204 No Content

Suppression d’un groupe

Requête

DELETE /Groups/cdb1ce18f65944079d37 HTTP/1.1

response

HTTP/1.1 204 No Content

Découverte de schéma

Découvrir le schéma

Requête

GET /Schemas

response

HTTP/1.1 200 OK

{
    "schemas": [
        "urn:ietf:params:scim:api:messages:2.0:ListResponse"
    ],
    "itemsPerPage": 50,
    "startIndex": 1,
    "totalResults": 3,
    "Resources": [
  {
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Schema"],
    "id" : "urn:ietf:params:scim:schemas:core:2.0:User",
    "name" : "User",
    "description" : "User Account",
    "attributes" : [
      {
        "name" : "userName",
        "type" : "string",
        "multiValued" : false,
        "description" : "Unique identifier for the User, typically
used by the user to directly authenticate to the service provider.
Each User MUST include a non-empty userName value.  This identifier
MUST be unique across the service provider's entire set of Users.
REQUIRED.",
        "required" : true,
        "caseExact" : false,
        "mutability" : "readWrite",
        "returned" : "default",
        "uniqueness" : "server"
      },                
    ],
    "meta" : {
      "resourceType" : "Schema",
      "location" :
        "/v2/Schemas/urn:ietf:params:scim:schemas:core:2.0:User"
    }
  },
  {
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Schema"],
    "id" : "urn:ietf:params:scim:schemas:core:2.0:Group",
    "name" : "Group",
    "description" : "Group",
    "attributes" : [
      {
        "name" : "displayName",
        "type" : "string",
        "multiValued" : false,
        "description" : "A human-readable name for the Group.
REQUIRED.",
        "required" : false,
        "caseExact" : false,
        "mutability" : "readWrite",
        "returned" : "default",
        "uniqueness" : "none"
      },
    ],
    "meta" : {
      "resourceType" : "Schema",
      "location" :
        "/v2/Schemas/urn:ietf:params:scim:schemas:core:2.0:Group"
    }
  },
  {
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Schema"],
    "id" : "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",
    "name" : "EnterpriseUser",
    "description" : "Enterprise User",
    "attributes" : [
      {
        "name" : "employeeNumber",
        "type" : "string",
        "multiValued" : false,
        "description" : "Numeric or alphanumeric identifier assigned
to a person, typically based on order of hire or association with an
organization.",
        "required" : false,
        "caseExact" : false,
        "mutability" : "readWrite",
        "returned" : "default",
        "uniqueness" : "none"
      },
    ],
    "meta" : {
      "resourceType" : "Schema",
      "location" :
"/v2/Schemas/urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
    }
  }
]
}

Spécifications de sécurité

Versions du protocole TLS

Les seules versions du protocole TLS autorisées sont TLS 1.2 et TLS 1.3. Aucune autre version de TLS n’est autorisée. Aucune version de SSL n’est autorisée.

  • Les clés RSA doivent comporter au moins 2 048 bits.
  • Les clés ECC doivent avoir au moins 256 bits et être générées à l’aide d’une courbe elliptique approuvée

Longueur des clés

Tous les services doivent utiliser des certificats X.509 générés à l’aide de clés de chiffrement d’une longueur suffisante, à savoir :

Suites de chiffrement

Tous les services doivent être configurés pour utiliser les suites de chiffrement suivantes, dans l’ordre exact indiqué ci-dessous. Si vous ne disposez que d'un certificat RSA, l'installation des suites de chiffrement ECDSA n'a aucun effet.

Barre minimale des suites de chiffrement TLS 1.2 :

  • TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  • TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384

Plages d’adresses IP

Le service de provisionnement Azure AD fonctionne actuellement dans le cadre des plages d’adresses IP pour AzureActiveDirectory, comme indiqué ici. Vous pouvez ajouter les plages d’adresses IP listées sous la balise AzureActiveDirectory pour autoriser le trafic en provenance du service de provisionnement Azure AD dans votre application. Vous devrez examiner attentivement la liste des plages d'adresses IP pour les adresses calculées. Une adresse telle que « 40.126.25.32 » peut être représentée dans la liste de plages d’adresses IP sous la forme « 40.126.0.0/18 ». Vous pouvez aussi récupérer programmatiquement la liste de plages d’adresses IP avec l’API suivante.

Azure AD prend également en charge une solution basée sur agent pour assurer la connectivité aux applications dans les réseaux privés (localement, hébergés dans Azure, hébergés dans AWS, etc.). Les clients peuvent déployer un agent léger, qui permet de se connecter à Azure AD sans ouvrir de ports entrants sur un serveur de leur réseau privé. En savoir plus ici.

Créer un point de terminaison SCIM

Maintenant que vous avez conçu votre schéma et compris l'implémentation d'Azure AD SCIM, vous pouvez commencer à développer votre point de terminaison SCIM. Plutôt que de partir de zéro et de construire la mise en œuvre entièrement par vos propres moyens, vous pouvez vous appuyer sur de nombreuses bibliothèques SCIM open source publiées par la communauté SCIM.

Pour obtenir des conseils sur la façon de créer un point de terminaison SCIM avec des exemples, consultez Développer un exemple de point de terminaison SCIM.

L’exemple de code de référence .NET Core open source publié par l’équipe de provisionnement Azure AD est une ressource qui peut vous permettre de démarrer rapidement votre développement. Après avoir créé votre point de terminaison SCIM, il vous faudra le tester. Vous pouvez utiliser la collection de tests Postman fournie dans le cadre du code de référence ou vous servir des exemples de requêtes/réponses fournis ci-dessus.

Notes

Le code de référence est destiné à vous aider à prendre en main la création d’un point de terminaison SCIM et est fourni « tel quel ». Les contributions de la communauté sont destinées à vous aider à créer le code et à le tenir à jour.

La solution est composée de deux projets, Microsoft.SCIM et Microsoft.SCIM.WebHostSample.

Le projet Microsoft.SCIM est la bibliothèque qui définit les composants du service web conforme à la spécification SCIM. Elle déclare l’interface Microsoft.SCIM.IProvider, les requêtes sont traduites en appels envoyés aux méthodes du fournisseur, lesquelles seraient programmées pour fonctionner sur un magasin d’identités.

Décomposition : Une requête est traduite en appels vers les méthodes du fournisseur

Le projet Microsoft.SCIM.WebHostSample est une application Web ASP.NET Core, basée sur le modèle Empty. Cela permet de déployer l’exemple de code de manière autonome dans des conteneurs ou au sein d’Internet Information Services. Il implémente également l’interface Microsoft.SCIM.IProvider en conservant les classes en mémoire comme exemple de magasin d’identités.

public class Startup
{
    ...
    public IMonitor MonitoringBehavior { get; set; }
    public IProvider ProviderBehavior { get; set; }

    public Startup(IWebHostEnvironment env, IConfiguration configuration)
    {
        ...
        this.MonitoringBehavior = new ConsoleMonitor();
        this.ProviderBehavior = new InMemoryProvider();
    }
    ...

Création d’un point de terminaison SCIM personnalisé

Le service SCIM doit avoir une adresse HTTP et un certificat d’authentification émanant du serveur dont l’autorité de certification racine est l’un des noms suivants :

  • CNNIC
  • Comodo
  • CyberTrust
  • DigiCert
  • GeoTrust
  • GlobalSign
  • Go Daddy
  • VeriSign
  • WoSign
  • DST Root CA X3

Le kit SDK .NET Core comprend un certificat de développement HTTPS qui peut être utilisé lors du développement, et le certificat est installé dans le cadre de la première exécution. Selon la façon dont vous exécutez l’application web ASP.NET Core, elle écoute un autre port :

  • Microsoft.SCIM.WebHostSample : https://localhost:5001
  • IIS Express : https://localhost:44359

Pour plus d’informations sur le protocole HTTPS dans ASP.NET Core, utilisez le lien suivant : Appliquer le protocole HTTPS dans ASP.NET Core

Gestion de l’authentification du point de terminaison

Les demandes provenant du service d'approvisionnement Azure AD comprennent un jeton de support OAuth 2.0. Le jeton du porteur est un jeton de sécurité émis par un serveur d’autorisation, tel qu’Azure AD et approuvé par votre application. Vous pouvez configurer le service de provisionnement Azure AD pour utiliser l’un des jetons suivants :

  • Un jeton porteur à longue durée de vie. Si le point de terminaison SCIM requiert un jeton de porteur OAuth d’un émetteur autre qu’Azure AD, copiez le jeton de porteur OAuth requis dans le champ facultatif Secret Token (Jeton secret). Dans un environnement de développement, vous pouvez utiliser le jeton de test à partir du point de terminaison /scim/token. Les jetons de test ne doivent pas être utilisés dans les environnements de production.

  • Jeton du porteur Azure AD. Si le champ Secret Token est laissé vide, Azure AD inclut un jeton de porteur OAuth émis par Azure AD avec chaque demande. Les applications qui utilisent Azure AD comme fournisseur d'identité peuvent valider ce jeton émis par Azure AD.

    • L’application qui reçoit des demandes doit valider l’émetteur de jeton comme étant Azure AD pour un locataire Azure AD attendu.
    • Dans le jeton, l'émetteur est identifié par une revendication iss. Par exemple : "iss":"https://sts.windows.net/12345678-0000-0000-0000-000000000000/". Dans cet exemple, l'adresse de base de la valeur de réclamation, https://sts.windows.net identifie Azure AD comme l'émetteur, tandis que le segment d'adresse relative, 12345678-0000-0000-0000-000000000000 , est un identifiant unique du locataire Azure AD pour lequel le jeton a été émis.
    • L’audience d’un jeton est l’ID d’application de l’application dans la galerie. Les applications enregistrées dans un seul locataire reçoivent la même revendication iss avec les demandes SCIM. L'ID de l'application pour toutes les applications personnalisées est 8adf8e6e-67b2-4cf2-a259-e3dc5476c621. Le jeton généré par le service de provisionnement d’Azure AD doit être utilisé uniquement pour le test. Il ne doit pas être utilisé dans les environnements de production.

Dans l’exemple de code, les requêtes sont authentifiées à l’aide du package Microsoft.AspNetCore.Authentication.JwtBearer. Le code suivant garantit que les demandes adressées à l'un des points de terminaison du service sont authentifiées à l'aide du jeton de support émis par Azure AD pour un locataire donné :

public void ConfigureServices(IServiceCollection services)
{
    if (_env.IsDevelopment())
    {
        ...
    }
    else
    {
        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })
            .AddJwtBearer(options =>
            {
                options.Authority = " https://sts.windows.net/12345678-0000-0000-0000-000000000000/";
                options.Audience = "8adf8e6e-67b2-4cf2-a259-e3dc5476c621";
                ...
            });
    }
    ...
}

public void Configure(IApplicationBuilder app)
{
    ...
    app.UseAuthentication();
    app.UseAuthorization();
    ...
}

Un jeton du porteur est également requis pour utiliser les tests Postman fournis et effectuer un débogage local à l’aide de localhost. L’exemple de code utilise des environnements ASP.NET Core pour modifier les options d’authentification pendant la phase de développement et activer l’utilisation d’un jeton autosigné.

Pour plus d’informations sur l’utilisation de plusieurs environnements dans ASP.NET Core, consultez Utiliser plusieurs environnements dans ASP.NET Core.

Le code suivant impose que les requêtes envoyées à l’un des points de terminaison du service soient authentifiées à l’aide du jeton du porteur signé avec une clé personnalisée :

public void ConfigureServices(IServiceCollection services)
{
    if (_env.IsDevelopment())
    {
        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters =
                new TokenValidationParameters
                {
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    ValidateLifetime = false,
                    ValidateIssuerSigningKey = false,
                    ValidIssuer = "Microsoft.Security.Bearer",
                    ValidAudience = "Microsoft.Security.Bearer",
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("A1B2C3D4E5F6A1B2C3D4E5F6"))
                };
        });
    }
...

Envoyez une requête GET au contrôleur de jetons pour obtenir un jeton du porteur valide, la méthode GenerateJSONWebToken est chargée de créer un jeton correspondant aux paramètres configurés pour le développement :

private string GenerateJSONWebToken()
{
    // Create token key
    SymmetricSecurityKey securityKey =
        new SymmetricSecurityKey(Encoding.UTF8.GetBytes("A1B2C3D4E5F6A1B2C3D4E5F6"));
    SigningCredentials credentials =
        new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

    // Set token expiration
    DateTime startTime = DateTime.UtcNow;
    DateTime expiryTime = startTime.AddMinutes(120);

    // Generate the token
    JwtSecurityToken token =
        new JwtSecurityToken(
            "Microsoft.Security.Bearer",
            "Microsoft.Security.Bearer",
            null,
            notBefore: startTime,
            expires: expiryTime,
            signingCredentials: credentials);

    string result = new JwtSecurityTokenHandler().WriteToken(token);
    return result;
}

Gestion du provisionnement et de l’annulation du provisionnement des utilisateurs

Exemple 1. Interroger le service pour obtenir un utilisateur correspondant

Azure AD interroge le service pour un utilisateur dont la valeur d'attribut externalId correspond à la valeur d'attribut mailNickname d'un utilisateur dans Azure AD. La requête est exprimée dans le protocole HTTP (Hypertext Transfer Protocol) comme dans cet exemple, jyoung étant un exemple de mailNickname d’utilisateur dans Azure AD.

Notes

Il s'agit simplement d'un exemple. Tous les utilisateurs n’auront pas d’attribut mailNickname, et la valeur dont dispose un utilisateur peut ne pas être unique dans le répertoire. De plus, l’attribut utilisé pour la correspondance (dans ce cas, externalId) est configurable dans les mappages d’attribut Azure AD.

GET https://.../scim/Users?filter=externalId eq jyoung HTTP/1.1
 Authorization: Bearer ...

Dans l’exemple de code, la requête est traduite en un appel à la méthode QueryAsync du fournisseur du service. Voici la signature de cette méthode :

// System.Threading.Tasks.Tasks is defined in mscorlib.dll.  
// Microsoft.SCIM.IRequest is defined in 
// Microsoft.SCIM.Service.  
// Microsoft.SCIM.Resource is defined in 
// Microsoft.SCIM.Schemas.  
// Microsoft.SCIM.IQueryParameters is defined in 
// Microsoft.SCIM.Protocol.  

Task<Resource[]> QueryAsync(IRequest<IQueryParameters> request);

Dans l’exemple de requête, pour un utilisateur avec une valeur d’attribut externalId donnée, les valeurs des arguments transmis à la méthode QueryAsync sont :

  • parameters.AlternateFilters.Count: 1
  • parameters.AlternateFilters.ElementAt(0).AttributePath: "externalId"
  • parameters.AlternateFilters.ElementAt(0).ComparisonOperator: ComparisonOperator.Equals
  • parameters.AlternateFilter.ElementAt(0).ComparisonValue: "jyoung"

Exemple 2. Approvisionner un utilisateur

Si la réponse à une requête adressée au point de terminaison SCIM pour un utilisateur dont la valeur d'attribut externalId correspond à la valeur d'attribut mailNickname d'un utilisateur ne renvoie aucun utilisateur, Azure AD demande au service de fournir un utilisateur correspondant à celui qui se trouve dans Azure AD. Voici un exemple de requête :

POST https://.../scim/Users HTTP/1.1
Authorization: Bearer ...
Content-type: application/scim+json
{
   "schemas":
   [
     "urn:ietf:params:scim:schemas:core:2.0:User",
     "urn:ietf:params:scim:schemas:extension:enterprise:2.0User"],
   "externalId":"jyoung",
   "userName":"jyoung@testuser.com",
   "active":true,
   "addresses":null,
   "displayName":"Joy Young",
   "emails": [
     {
       "type":"work",
       "value":"jyoung@Contoso.com",
       "primary":true}],
   "meta": {
     "resourceType":"User"},
    "name":{
     "familyName":"Young",
     "givenName":"Joy"},
   "phoneNumbers":null,
   "preferredLanguage":null,
   "title":null,
   "department":null,
   "manager":null}

Dans l’exemple de code, la requête est traduite en un appel à la méthode CreateAsync du fournisseur du service. Voici la signature de cette méthode :

// System.Threading.Tasks.Tasks is defined in mscorlib.dll.  
// Microsoft.SCIM.IRequest is defined in 
// Microsoft.SCIM.Service.  
// Microsoft.SCIM.Resource is defined in 
// Microsoft.SCIM.Schemas.  

Task<Resource> CreateAsync(IRequest<Resource> request);

Dans une demande de provisionnement d'un utilisateur, la valeur de l'argument ressource est une instance de la classe Microsoft.SCIM.Core2EnterpriseUser, définie dans la bibliothèque Microsoft.SCIM.Schemas. Si la requête d’approvisionnement de l’utilisateur réussit, l’implémentation de la méthode est supposée retourner une instance de la classe Microsoft.SCIM.Core2EnterpriseUser, avec la valeur de la propriété Identificateur définie sur l’identificateur unique de l’utilisateur nouvellement approvisionné.

Exemple 3. Interroger l'état actuel d’un utilisateur

Pour mettre à jour un utilisateur qui existe dans un magasin d’identités avec SCIM frontal, Azure AD continue en demandant au service l’état actuel de cet utilisateur avec une requête de type :

GET ~/scim/Users/54D382A4-2050-4C03-94D1-E769F1D15682 HTTP/1.1
Authorization: Bearer ...

Dans l’exemple de code, la requête est traduite en un appel à la méthode RetrieveAsync du fournisseur du service. Voici la signature de cette méthode :

// System.Threading.Tasks.Tasks is defined in mscorlib.dll.  
// Microsoft.SCIM.IRequest is defined in 
// Microsoft.SCIM.Service.  
// Microsoft.SCIM.Resource and 
// Microsoft.SCIM.IResourceRetrievalParameters 
// are defined in Microsoft.SCIM.Schemas 

Task<Resource> RetrieveAsync(IRequest<IResourceRetrievalParameters> request);

Dans le cas d’une requête servant à récupérer l’état actuel d’un utilisateur, les valeurs des propriétés de l’objet fourni comme valeur d’argument des paramètres sont les suivantes :

  • Identificateur : "54D382A4-2050-4C03-94D1-E769F1D15682"
  • SchemaIdentifier : urn:ietf:params:scim:schemas:extension:enterprise:2.0:User

Exemple 4. Interroger la valeur d’un attribut de référence à mettre à jour

Si un attribut de référence doit être mis à jour, Azure AD interroge le service pour déterminer si la valeur actuelle de l’attribut de référence dans le magasin d’identités avec le service frontal correspond déjà à la valeur de cet attribut dans Azure AD. Pour les utilisateurs, le seul attribut dont la valeur actuelle est interrogée de cette manière est l’attribut manager. Voici un exemple de requête visant à déterminer si l’attribut manager d’un objet utilisateur a actuellement une certaine valeur : Dans l’exemple de code, la requête est traduite en un appel à la méthode QueryAsync du fournisseur du service. La valeur des propriétés de l’objet fourni en tant que valeur d’argument des paramètres est la suivante :

  • parameters.AlternateFilters.Count: 2
  • parameters.AlternateFilters.ElementAt(x).AttributePath: « ID »
  • parameters.AlternateFilters.ElementAt(x).ComparisonOperator: ComparisonOperator.Equals
  • parameters.AlternateFilter.ElementAt(x).ComparisonValue: "54D382A4-2050-4C03-94D1-E769F1D15682"
  • parameters.AlternateFilters.ElementAt(y).AttributePath: "manager
  • parameters.AlternateFilters.ElementAt(y).ComparisonOperator: ComparisonOperator.Equals
  • parameters.AlternateFilter.ElementAt(y).ComparisonValue: "2819c223-7f76-453a-919d-413861904646"
  • parameters.RequestedAttributePaths.ElementAt(0): « ID »
  • paramètres. SchemaIdentifier : urn:ietf:params:scim:schemas:extension:enterprise:2.0:User

La valeur de l’index x peut être 0 et la valeur de l’index y peut être 1. Ou la valeur de x peut être 1 et la valeur de y peut être 0. Elle dépend de l’ordre des expressions du paramètre de requête de filtre.

Exemple 5. Demande Azure AD à un service SCIM pour mettre à jour un utilisateur

Voici un exemple de demande d'Azure AD à un point de terminaison SCIM pour mettre à jour un utilisateur :

PATCH ~/scim/Users/54D382A4-2050-4C03-94D1-E769F1D15682 HTTP/1.1
Authorization: Bearer ...
Content-type: application/scim+json
{
    "schemas": 
    [
      "urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations":
    [
      {
        "op":"Add",
        "path":"manager",
        "value":
          [
            {
              "$ref":"http://.../scim/Users/2819c223-7f76-453a-919d-413861904646",
              "value":"2819c223-7f76-453a-919d-413861904646"}]}]}

Dans l’exemple de code, la requête est traduite en un appel à la méthode UpdateAsync du fournisseur du service. Voici la signature de cette méthode :

// System.Threading.Tasks.Tasks and 
// System.Collections.Generic.IReadOnlyCollection<T>  // are defined in mscorlib.dll.  
// Microsoft.SCIM.IRequest is defined in
// Microsoft.SCIM.Service.
// Microsoft.SCIM.IPatch, 
// is defined in Microsoft.SCIM.Protocol. 

Task UpdateAsync(IRequest<IPatch> request);

Dans le cas d’une demande de mise à jour d’un utilisateur, l’objet fourni comme valeur d’argument de correctif a les valeurs de propriété suivantes :

Argument Valeur
ResourceIdentifier.Identifier "54D382A4-2050-4C03-94D1-E769F1D15682"
ResourceIdentifier.SchemaIdentifier urn:ietf:params:scim:schemas:extension:enterprise:2.0:User
(PatchRequest as PatchRequest2).Operations.Count 1
(PatchRequest as PatchRequest2).Operations.ElementAt(0).OperationName OperationName.Add
(PatchRequest as PatchRequest2).Operations.ElementAt(0).Path.AttributePath Manager
(PatchRequest as PatchRequest2).Operations.ElementAt(0).Value.Count 1
(PatchRequest as PatchRequest2).Operations.ElementAt(0).Value.ElementAt(0).Reference http://.../scim/Users/2819c223-7f76-453a-919d-413861904646
(PatchRequest as PatchRequest2).Operations.ElementAt(0).Value.ElementAt(0).Value 2819c223-7f76-453a-919d-413861904646

Exemple 6. Déprovisionner un utilisateur

Pour déprovisionner un utilisateur à partir d'un magasin d'identités géré par un point de terminaison SCIM, Azure AD envoie une requête telle que :

DELETE ~/scim/Users/54D382A4-2050-4C03-94D1-E769F1D15682 HTTP/1.1
Authorization: Bearer ...

Dans l’exemple de code, la requête est traduite en un appel à la méthode DeleteAsync du fournisseur du service. Voici la signature de cette méthode :

// System.Threading.Tasks.Tasks is defined in mscorlib.dll.  
// Microsoft.SCIM.IRequest is defined in 
// Microsoft.SCIM.Service.  
// Microsoft.SCIM.IResourceIdentifier, 
// is defined in Microsoft.SCIM.Protocol. 

Task DeleteAsync(IRequest<IResourceIdentifier> request);

L’objet fourni en tant que valeur d’argument resourceIdentifier présente ces valeurs de propriété dans le cas d’une demande de déprovisionnement d'un utilisateur :

  • ResourceIdentifier.Identifier: "54D382A4-2050-4C03-94D1-E769F1D15682"
  • ResourceIdentifier.SchemaIdentifier : urn:ietf:params:scim:schemas:extension:enterprise:2.0:User

Intégrer votre terminal SCIM avec le service de provisionnement Azure AD

Azure AD peut être configuré pour attribuer automatiquement des utilisateurs et groupes dans les applications qui implémentent un profil spécifique du protocole SCIM 2.0. Les détails du profil sont documentés dans Comprendre l’implémentation de SCIM d’Azure AD.

Vérifiez avec votre fournisseur d’application ou dans la documentation du fournisseur de votre application la conformité à ces exigences.

Important

L’implémentation de SCIM d’Azure AD repose sur le service d’approvisionnement d’utilisateur Azure AD, conçu pour conserver constamment les utilisateurs synchronisés avec Azure AD et l’application cible, et implémente un ensemble très spécifique d’opérations standard. Il est important de comprendre ces comportements pour comprendre le comportement du service d'approvisionnement Azure AD. Pour plus d'informations, consultez la section Cycles d'approvisionnement : cycle initial et cycle incrémentiel de l'article Fonctionnement de l'approvisionnement.

Prise en main

Les applications qui prennent en charge le profil SCIM décrit dans cet article peuvent être connectées à Azure AD à l’aide de la fonctionnalité « application ne figurant pas dans la galerie » dans la galerie d’applications Azure AD. Une fois connecté, Azure AD exécute toutes les 40 minutes un processus de synchronisation au cours duquel il interroge le point de terminaison de SCIM de l’application concernant les utilisateurs et les groupes assignés, et les crée ou les modifie en fonction des détails de l’attribution.

Pour connecter une application qui prend en charge SCIM :

  1. Connectez-vous au portail Azure AD. Vous pouvez accéder à un essai gratuit d'Azure AD avec des licences P2 en vous inscrivant au programme de développement

  2. Dans le volet gauche, sélectionnez Applications d’entreprise. Une liste de toutes les applications configurées s’affiche, dont les applications qui ont été ajoutées à partir de la galerie.

  3. Sélectionnez + Nouvelle application>+ Créer votre propre application.

  4. Entrez un nom pour votre application, choisissez l’option « Intégrer une autre application que vous ne trouvez pas dans la galerie », puis sélectionnez Ajouter pour créer un objet d’application. La nouvelle application est ajoutée à la liste des applications d’entreprise et s’ouvre sur son écran de gestion d’application.

    La capture d'écran suivante montre la galerie d'applications Azure AD :

    La capture d'écran montre la galerie d'applications Azure AD.

    Notes

    Si vous utilisez l’ancienne expérience de la galerie d’applications, suivez le guide à l’écran ci-dessous.

    La capture d’écran suivante montre l’ancienne expérience de la galerie d’applications Azure AD :

    La capture d'écran montre l'expérience de l'ancienne galerie d'applications d'Azure AD

  5. Dans l’écran de gestion d’application, sélectionnez Approvisionnement dans le volet gauche.

  6. Dans le menu Mode d’approvisionnement, sélectionnez Automatique.

    La capture d'écran suivante montre la configuration des paramètres de provisionnement dans le portail Azure :

    Capture d'écran de la page de provisionnement des applications dans le portail Azure.

  7. Dans le champ URL du locataire, entrez l’URL du point de terminaison SCIM de l’application. Exemple : https://api.contoso.com/scim/

  8. Si le point de terminaison SCIM requiert un jeton de porteur OAuth d’un émetteur autre qu’Azure AD, copiez le jeton de porteur OAuth requis dans le champ facultatif Secret Token (Jeton secret). Si ce champ est laissé vide, Azure AD inclut un jeton de porteur OAuth émis par Azure AD avec chaque requête. Les applications qui utilisent Azure AD comme fournisseur d'identité peuvent valider ce jeton émis par Azure AD.

    Notes

    Il est déconseillé de laisser ce champ vide et d’utiliser un jeton généré par Azure AD. Cette option est principalement destinée à des fins de test.

  9. Sélectionnez Tester la connexion pour qu'Azure AD tente de se connecter au point de terminaison SCIM. Si la tentative échoue, des informations d’erreur s’affichent.

    Notes

    Tester la connexion interroge le point de terminaison SCIM pour un utilisateur qui n’existe pas, en utilisant un GUID aléatoire en tant que propriété correspondante sélectionnée dans la configuration Azure AD. La réponse correcte attendue est HTTP 200 OK avec un message SCIM ListResponse vide.

  10. Si la tentative de connexion à l’application réussit, sélectionnez Enregistrer pour enregistrer les informations d’identification d’administrateur.

  11. La section Mappages présente deux ensembles sélectionnables de mappages d’attributs : un pour les objets utilisateur et un autre pour les objets de groupe. Sélectionnez chacun d’eux pour consulter les attributs qui sont synchronisés entre Azure AD et votre application. Les attributs sélectionnés en tant que propriétés de Correspondance sont utilisés pour faire correspondre les utilisateurs et les groupes dans votre application pour les opérations de mise à jour. Sélectionnez Enregistrer pour valider les modifications.

    Notes

    Vous pouvez éventuellement désactiver la synchronisation des objets de groupe en désactivant le mappage « Groupes ».

  12. Sous Paramètres, le champ Étendue définit les utilisateurs et les groupes qui sont synchronisés. Sélectionnez Sync only assigned users and groups (recommended) (Synchroniser uniquement les utilisateurs et les groupes attribués (recommandé)) pour que seuls les utilisateurs et les groupes attribués soient synchronisés dans l’onglet Utilisateurs et groupes.

  13. Une fois votre configuration terminée, définissez l’état d’approvisionnement sur Activé.

  14. Sélectionnez Enregistrer pour démarrer le service d’approvisionnement Azure AD.

  15. Si vous souhaitez synchroniser uniquement les utilisateurs et groupes assignés (recommandé), sélectionnez l'onglet Utilisateurs et groupes. Ensuite, affectez les utilisateurs ou les groupes que vous souhaitez synchroniser.

Une fois le cycle initial démarré, vous pouvez sélectionner Journaux d’approvisionnement dans le panneau de gauche pour suivre la progression, qui indique toutes les actions effectuées par le service d'approvisionnement de votre application. Pour plus d’informations sur la lecture des journaux d’activité d’approvisionnement Azure AD, consultez Création de rapports sur l’approvisionnement automatique de comptes d’utilisateur.

Notes

Le cycle initial prend plus de temps que les synchronisations suivantes, qui se produisent environ toutes les 40 minutes, tant que le service est en cours d’exécution.

Si vous créez une application qui sera utilisée par plusieurs locataires, vous pouvez la rendre disponible dans la galerie d’applications Azure AD. Il est facile pour les organisations de découvrir l'application et de configurer le provisionnement. Vous pouvez facilement publier votre application dans la galerie Azure AD et mettre l’approvisionnement à la disposition d’autres utilisateurs. Découvrez les étapes ici. Microsoft vous aidera à intégrer votre application à la galerie, à tester votre point de terminaison et à publier la documentation d'intégration destinée aux clients.

Utilisez la liste de vérification pour intégrer rapidement votre application et permettre à vos clients une expérience de déploiement facile. Les informations seront collectées auprès de vous lors de l’intégration à la galerie.

  • Prise en charge d’un point de terminaison de groupe et d’utilisateur SCIM 2.0 (un seul est obligatoire, mais il est recommandé de disposer des deux)
  • Prise en charge d’au moins 25 requêtes par seconde par locataire pour s’assurer que les utilisateurs et les groupes sont provisionnés et déprovisionnés sans délai (obligatoire)
  • Établissement de contacts d’ingénierie et de support pour guider l’intégration des clients à la galerie de publications (obligatoire)
  • Trois informations d’identification de test sans date d’expiration pour l’application (obligatoire)
  • Prise en charge de l’octroi de code d’autorisation OAuth ou d’un jeton de longue durée, comme décrit ci-dessous (obligatoire)
  • Établissement d’un point de contact d’ingénierie et de support pour la prise en charge de l’intégration des clients à la galerie de publications (obligatoire)
  • Prise en charge de la détection de schéma (obligatoire)
  • Prise en charge de la mise à jour de l’appartenance à plusieurs groupes avec un seul correctif
  • Documentation publique de votre point de terminaison SCIM

La spécification SCIM ne définit pas un schéma propre à SCIM pour l’authentification et l’autorisation. En outre, elle s’appuie sur l’utilisation de normes industrielles existantes.

Méthode d’autorisation Avantages Inconvénients Support
Nom d’utilisateur et mot de passe (non recommandé ou pris en charge par Azure AD) Facile à implémenter Non sécurisé - Votre Pa$$word n’a pas d’importance Non pris en charge pour les nouvelles applications de la galerie ou hors galerie.
Jeton de porteur de longue durée Les jetons de longue durée ne nécessitent aucune intervention de la part d’un utilisateur. Ils sont simples à utiliser par les administrateurs qui configurent le provisionnement. Les jetons de longue durée peuvent être difficiles à partager avec un administrateur sans utiliser de méthodes non sécurisées telles que la messagerie électronique. Prise en charge pour toutes les applications (celles de la galerie et les autres).
Octroi du code d’autorisation OAuth Les jetons d’accès ont une durée de vie beaucoup plus courte que les mots de passe. Ils comportent un mécanisme d’actualisation automatisée, ce qui n’est pas le cas des jetons de porteur de longue durée. Un utilisateur doit être physiquement présent lors de l’autorisation initiale, ce qui ajoute un niveau de responsabilité. Nécessite la présence d’un utilisateur. Si l’utilisateur quitte l’organisation, le jeton n’est plus valide et l’autorisation doit être recommencée. Prise en charge pour les applications de la galerie, mais pas pour les autres. Toutefois, vous pouvez fournir un jeton d’accès dans l’interface utilisateur en tant que jeton secret à des fins de test à court terme. La prise en charge de l’octroi de code OAuth pour les applications hors galerie fait partie de notre backlog. De même, la prise en charge des URL d’authentification/de jeton configurables pour l’application de galerie fait également partie de notre backlog.
Octroi d’informations d’identification de client OAuth Les jetons d’accès ont une durée de vie beaucoup plus courte que les mots de passe. Ils comportent un mécanisme d’actualisation automatisée, ce qui n’est pas le cas des jetons de porteur de longue durée. L’octroi du code d’autorisation et l’octroi d’informations d’identification du client permettent de créer le même type de jeton d’accès. L’utilisation de l’une ou l’autre de ces méthodes est donc transparente pour l’API. L'approvisionnement peut être automatisé, et de nouveaux jetons peuvent être demandés silencieusement sans interaction avec l'utilisateur. Prise en charge pour les applications de la galerie, mais pas pour les autres. Toutefois, vous pouvez fournir un jeton d’accès dans l’interface utilisateur en tant que jeton secret à des fins de test à court terme. Notre backlog inclut une prise en charge de l’octroi de client OAuth sur une application ne figurant pas dans la galerie.

Notes

Il est déconseillé de laisser le champ du jeton vide dans l’interface utilisateur de l’application personnalisée de configuration du provisionnement Azure AD. Le jeton généré est principalement destiné à des fins de test.

Flux d’octroi du code OAuth

Le service de provisionnement prend en charge l’octroi de code d’autorisation. Une fois que vous aurez envoyé la demande de publication de votre application dans la galerie, notre équipe vous demandera les informations suivantes :

  • URL d’autorisation : URL client permettant d’obtenir l’autorisation du propriétaire de la ressource via la redirection de l’agent utilisateur. L’utilisateur est redirigé vers cette URL pour autoriser l’accès.

  • URL d’échange de jetons : URL client permettant d’échanger un octroi d’autorisation pour un jeton d’accès, généralement avec authentification du client.

  • ID client : serveur d’autorisation qui fournit au client inscrit un identifiant client. Il s’agit d’une chaîne unique représentant les informations d’inscription fournies par le client. L’identifiant client n’est pas secret ; il est exposé au propriétaire de la ressource et ne doit pas être utilisé seul à des fins d'authentification du client.

  • Secret client : secret généré par le serveur d’autorisation. Il doit s’agir d’une valeur unique connue uniquement du serveur d’autorisation.

Notes

L’URL d’autorisation et l’URL d’échange de jetons ne sont pas configurables par le locataire.

Notes

OAuth v1 n’est pas pris en charge en raison de l’exposition du secret client. OAuth v2 est pris en charge.

Bonnes pratiques (recommandées, mais pas obligatoires) :

  • Prise en charge de plusieurs URL de redirection. Les administrateurs peuvent configurer l’approvisionnement depuis « portal.azure.com » et « aad.portal.azure.com ». La prise en charge de plusieurs URL de redirection permet aux utilisateurs d'autoriser l’accès depuis l’un ou l’autre des portails.
  • Prise en charge de plusieurs secrets pour un renouvellement facile, sans temps d’arrêt.

Comment mettre en place le flux d'octroi de code OAuth

  1. Connectez-vous au portail Azure, accédez à Applications d’entreprise>Application>Provisionnement, puis sélectionnez Autoriser.

    1. Le portail Azure redirige l’utilisateur vers l’URL d’autorisation (page de connexion pour l’application tierce).

    2. L’administrateur fournit des informations d’identification à l’application tierce.

    3. L’application tierce redirige l’utilisateur vers portail Azure et fournit le code d’octroi

    4. Les services d’approvisionnement Azure AD appellent l’URL du jeton et fournissent le code d’octroi. L’application tierce répond avec le jeton d’accès, le jeton d’actualisation et la date d’expiration

  2. Lors du démarrage du cycle d’approvisionnement, le service vérifie si le jeton d’accès actuel est valide et l’échange contre un nouveau jeton si nécessaire. Le jeton d’accès est fourni dans chaque demande adressée à l’application et la validité de la demande est vérifiée avant chaque demande.

Notes

Même s’il n’est pas possible de configurer OAuth dans les applications qui ne figurent pas dans la galerie, vous pouvez générer manuellement un jeton d’accès à partir de votre serveur d’autorisation et l’entrer comme jeton secret pour une application ne figurant pas dans la galerie. Cela vous permet de vérifier la compatibilité de votre serveur SCIM avec le service d'approvisionnement Azure AD avant d'intégrer la galerie d'applications, qui prend en charge l'octroi de code OAuth.

Jetons de porteur OAuth à longue durée : Si votre application ne prend pas en charge le flux d’octroi de code OAuth, générez un jeton de porteur OAuth à longue durée qu’un administrateur peut utiliser pour configurer l’intégration du provisionnement. Le jeton doit être perpétuel, à défaut de quoi le travail d’approvisionnement sera mis en quarantaine à expiration du jeton.

Si vous souhaitez davantage de méthodes d’authentification et d’autorisation, faites-le nous savoir sur UserVoice.

Pour contribuer à la sensibilisation et à la demande de notre intégration conjointe, nous vous recommandons de mettre à jour votre documentation existante et d’amplifier son intégration dans vos canaux marketing. Nous vous recommandons de suivre la liste de contrôle suivante pour prendre en charge le lancement :

  • Assurez-vous que l’équipe du support technique et l’équipe commerciale sont informées et capables de parler des fonctionnalités d’intégration. Informez vos équipes, mettez à leur disposition la liste des questions fréquentes (FAQ), et incluez l’intégration dans vos documents de vente.
  • Élaborez un billet de blog ou un communiqué de presse décrivant l’intégration conjointe, les avantages et la prise en main. Exemple : Communiqué de presse Imprivata et Azure AD
  • Tirez parti de vos réseaux sociaux tels que Twitter, Facebook ou LinkedIn pour promouvoir l’intégration à vos clients. Veillez à inclure @AzureAD pour pouvoir retweeter votre publication. Exemple : Publication Twitter d’Imprivata
  • Créez ou mettez à jour vos pages marketing ou vos sites web (par exemple, page d’intégration, page de partenaire, page des tarifs, etc.) pour inclure la disponibilité de l’intégration conjointe. Exemple : Page d’intégration Pingboard, page d’intégration Smartsheet, page de tarification Monday.com
  • Créez un article du centre d’aide ou une documentation technique sur la façon dont les clients peuvent commencer. Exemple : Intégration Envoy + Microsoft Azure AD.
  • Avertissez les clients de la nouvelle intégration dans le cadre de votre communication (bulletins mensuels, campagnes par courrier électronique, notes de publication de produits).

Étapes suivantes