Skip to content

Commit 6d247f2

Browse files
Update use-scim-to-provision-users-and-groups.md
1 parent b67cd3e commit 6d247f2

File tree

1 file changed

+249
-1
lines changed

1 file changed

+249
-1
lines changed

articles/active-directory/app-provisioning/use-scim-to-provision-users-and-groups.md

Lines changed: 249 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,255 @@ TLS 1.2 Cipher Suites minimum bar:
757757
Now that you have desidned your schema and understood the Azure AD SCIM implementation, you can get started developing your SCIM endpoint. Rather than starting from scratch and building the implementation completely on your own, you can rely on a number of open source SCIM libraries published by the SCIM commuinty.
758758
The open source .NET Core [reference code](https://aka.ms/SCIMReferenceCode) published by the Azure AD provisioning team is one such resource that can jump start your development. Once you've built your SCIM endpoint, you'll want to test it out. You can use the collection of [postman tests](https://github.com/AzureAD/SCIMReferenceCode/wiki/Test-Your-SCIM-Endpoint) provided as part of the reference code or run through the sample requests / responses provided [above](https://docs.microsoft.com/azure/active-directory/app-provisioning/use-scim-to-provision-users-and-groups#user-operations).
759759

760-
760+
Here’s how it works:
761+
762+
1. Azure AD provides a common language infrastructure (CLI) library named Microsoft.SystemForCrossDomainIdentityManagement, included with the code samples describe below. System integrators and developers can use this library to create and deploy a SCIM-based web service endpoint that can connect Azure AD to any application’s identity store.
763+
2. Mappings are implemented in the web service to map the standardized user schema to the user schema and protocol required by the application.
764+
3. The endpoint URL is registered in Azure AD as part of a custom application in the application gallery.
765+
4. Users and groups are assigned to this application in Azure AD. Upon assignment, they're put into a queue to be synchronized to the target application. The synchronization process handling the queue runs every 40 minutes.
766+
767+
### Code samples
768+
769+
To make this process easier, [code samples](https://github.com/Azure/AzureAD-BYOA-Provisioning-Samples/tree/master) are provided, which create a SCIM web service endpoint and demonstrate automatic provisioning. The sample is of a provider that maintains a file with rows of comma-separated values representing users and groups.
770+
771+
**Prerequisites**
772+
773+
* Visual Studio 2013 or later
774+
* [Azure SDK for .NET](https://azure.microsoft.com/downloads/)
775+
* Windows machine that supports the ASP.NET framework 4.5 to be used as the SCIM endpoint. This machine must be accessible from the cloud.
776+
* [An Azure subscription with a trial or licensed version of Azure AD Premium](https://azure.microsoft.com/services/active-directory/)
777+
778+
### Getting started
779+
780+
The easiest way to implement a SCIM endpoint that can accept provisioning requests from Azure AD is to build and deploy the code sample that outputs the provisioned users to a comma-separated value (CSV) file.
781+
782+
#### To create a sample SCIM endpoint
783+
784+
1. Download the code sample package at [https://github.com/Azure/AzureAD-BYOA-Provisioning-Samples/tree/master](https://github.com/Azure/AzureAD-BYOA-Provisioning-Samples/tree/master)
785+
1. Unzip the package and place it on your Windows machine at a location such as C:\AzureAD-BYOA-Provisioning-Samples\.
786+
1. In this folder, launch the FileProvisioning\Host\FileProvisioningService.csproj project in Visual Studio.
787+
1. Select **Tools** > **NuGet Package Manager** > **Package Manager Console**, and execute the following commands for the FileProvisioningService project to resolve the solution references:
788+
789+
```powershell
790+
Update-Package -Reinstall
791+
```
792+
793+
1. Build the FileProvisioningService project.
794+
1. Launch the Command Prompt application in Windows (as an Administrator), and use the **cd** command to change the directory to your **\AzureAD-BYOA-Provisioning-Samples\FileProvisioning\Host\bin\Debug** folder.
795+
1. Run the following command, replacing `<ip-address>` with the IP address or domain name of the Windows machine:
796+
797+
```
798+
FileSvc.exe http://<ip-address>:9000 TargetFile.csv
799+
```
800+
801+
1. In Windows under **Windows Settings** > **Network & Internet Settings**, select the **Windows Firewall** > **Advanced Settings**, and create an **Inbound Rule** that allows inbound access to port 9000.
802+
1. If the Windows machine is behind a router, the router needs to be configured to run Network Access Translation between its port 9000 that is exposed to the internet, and port 9000 on the Windows machine. This configuration is required for Azure AD to access this endpoint in the cloud.
803+
804+
#### To register the sample SCIM endpoint in Azure AD
805+
806+
1. Sign in to the [Azure Active Directory portal](https://aad.portal.azure.com).
807+
1. Select **Enterprise applications** from the left pane. A list of all configured apps is shown, including apps that were added from the gallery.
808+
1. Select **+ New application** > **All** > **Non-gallery application**.
809+
1. Enter a name for your application, and select **Add** to create an app object. The application object created is intended to represent the target app you would be provisioning to and implementing single sign-on for, and not just the SCIM endpoint.
810+
1. In the app management screen, select **Provisioning** in the left panel.
811+
1. In the **Provisioning Mode** menu, select **Automatic**.
812+
1. In the **Tenant URL** field, enter the URL of the application's SCIM endpoint. Example: https://api.contoso.com/scim/
813+
814+
1. If the SCIM endpoint requires an OAuth bearer token from an issuer other than Azure AD, then copy the required OAuth bearer token into the optional **Secret Token** field. If this field is left blank, Azure AD includes an OAuth bearer token issued from Azure AD with each request. Apps that use Azure AD as an identity provider can validate this Azure AD-issued token.
815+
1. Select **Test Connection** to have Azure Active Directory attempt to connect to the SCIM endpoint. If the attempt fails, error information is displayed.
816+
817+
> [!NOTE]
818+
> **Test Connection** queries the SCIM endpoint for a user that doesn't exist, using a random GUID as the matching property selected in the Azure AD configuration. The expected correct response is HTTP 200 OK with an empty SCIM ListResponse message
819+
1. If the attempts to connect to the application succeed, then select **Save** to save the admin credentials.
820+
1. In the **Mappings** section, there are two selectable sets of attribute mappings: one for user objects and one for group objects. Select each one to review the attributes that are synchronized from Azure Active Directory to your app. The attributes selected as **Matching** properties are used to match the users and groups in your app for update operations. Select **Save** to commit any changes.
821+
1. Under **Settings**, the **Scope** field defines which users and or groups are synchronized. Select **"Sync only assigned users and groups** (recommended) to only sync users and groups assigned in the **Users and groups** tab.
822+
1. Once your configuration is complete, set the **Provisioning Status** to **On**.
823+
1. Select **Save** to start the Azure AD provisioning service.
824+
1. If syncing only assigned users and groups (recommended), be sure to select the **Users and groups** tab and assign the users or groups you want to sync.
825+
Once the initial cycle has started, you can select **Audit logs** in the left panel to monitor progress, which shows all actions done by the provisioning service on your app. For more information on how to read the Azure AD provisioning logs, see [Reporting on automatic user account provisioning](check-status-user-account-provisioning.md).
826+
827+
The final step in verifying the sample is to open the TargetFile.csv file in the \AzureAD-BYOA-Provisioning-Samples\ProvisioningAgent\bin\Debug folder on your Windows machine. Once the provisioning process is run, this file shows the details of all assigned and provisioned users and groups.
828+
829+
### Development libraries
830+
831+
To develop your own web service that conforms to the SCIM specification, first familiarize yourself with the following libraries provided by Microsoft to help accelerate the development process:
832+
833+
* Common Language Infrastructure (CLI) libraries are offered for use with languages based on that infrastructure, such as C#. One of those libraries, Microsoft.SystemForCrossDomainIdentityManagement.Service, declares an interface, Microsoft.SystemForCrossDomainIdentityManagement.IProvider, shown in the following illustration. A developer using the libraries would implement that interface with a class that may be referred to, generically, as a provider. The libraries let the developer deploy a web service that conforms to the SCIM specification. The web service can be either hosted within Internet Information Services, or any executable CLI assembly. Request is translated into calls to the provider’s methods, which would be programmed by the developer to operate on some identity store.
834+
835+
![Breakdown: A request translated into calls to the provider's methods](media/use-scim-to-provision-users-and-groups/scim-figure-3.png)
836+
837+
* [Express route handlers](https://expressjs.com/guide/routing.html) are available for parsing node.js request objects representing calls (as defined by the SCIM specification), made to a node.js web service.
838+
839+
### Building a custom SCIM endpoint
840+
841+
Developers using the CLI libraries can host their services within any executable CLI assembly, or within Internet Information Services. Here is sample code for hosting a service within an executable assembly, at the address http://localhost:9000:
842+
843+
```csharp
844+
private static void Main(string[] arguments)
845+
{
846+
// Microsoft.SystemForCrossDomainIdentityManagement.IMonitor,
847+
// Microsoft.SystemForCrossDomainIdentityManagement.IProvider and
848+
// Microsoft.SystemForCrossDomainIdentityManagement.Service are all defined in
849+
// Microsoft.SystemForCrossDomainIdentityManagement.Service.dll.
850+
Microsoft.SystemForCrossDomainIdentityManagement.IMonitor monitor =
851+
new DevelopersMonitor();
852+
Microsoft.SystemForCrossDomainIdentityManagement.IProvider provider =
853+
new DevelopersProvider(arguments[1]);
854+
Microsoft.SystemForCrossDomainIdentityManagement.Service webService = null;
855+
try
856+
{
857+
webService = new WebService(monitor, provider);
858+
webService.Start("http://localhost:9000");
859+
Console.ReadKey(true);
860+
}
861+
finally
862+
{
863+
if (webService != null)
864+
{
865+
webService.Dispose();
866+
webService = null;
867+
}
868+
}
869+
}
870+
public class WebService : Microsoft.SystemForCrossDomainIdentityManagement.Service
871+
{
872+
private Microsoft.SystemForCrossDomainIdentityManagement.IMonitor monitor;
873+
private Microsoft.SystemForCrossDomainIdentityManagement.IProvider provider;
874+
public WebService(
875+
Microsoft.SystemForCrossDomainIdentityManagement.IMonitor monitoringBehavior,
876+
Microsoft.SystemForCrossDomainIdentityManagement.IProvider providerBehavior)
877+
{
878+
this.monitor = monitoringBehavior;
879+
this.provider = providerBehavior;
880+
}
881+
public override IMonitor MonitoringBehavior
882+
{
883+
get
884+
{
885+
return this.monitor;
886+
}
887+
set
888+
{
889+
this.monitor = value;
890+
}
891+
}
892+
public override IProvider ProviderBehavior
893+
{
894+
get
895+
{
896+
return this.provider;
897+
}
898+
set
899+
{
900+
this.provider = value;
901+
}
902+
}
903+
}
904+
```
905+
906+
This service must have an HTTP address and server authentication certificate of which the root certification authority is one of the following names:
907+
908+
* CNNIC
909+
* Comodo
910+
* CyberTrust
911+
* DigiCert
912+
* GeoTrust
913+
* GlobalSign
914+
* Go Daddy
915+
* VeriSign
916+
* WoSign
917+
918+
A server authentication certificate can be bound to a port on a Windows host using the network shell utility:
919+
920+
```
921+
netsh http add sslcert ipport=0.0.0.0:443 certhash=0000000000003ed9cd0c315bbb6dc1c08da5e6 appid={00112233-4455-6677-8899-AABBCCDDEEFF}
922+
```
923+
924+
Here, the value provided for the certhash argument is the thumbprint of the certificate, while the value provided for the appid argument is an arbitrary globally unique identifier.
925+
926+
To host the service within Internet Information Services, a developer would build a CLI code library assembly with a class named Startup in the default namespace of the assembly. Here is a sample of such a class:
927+
928+
```csharp
929+
public class Startup
930+
{
931+
// Microsoft.SystemForCrossDomainIdentityManagement.IWebApplicationStarter,
932+
// Microsoft.SystemForCrossDomainIdentityManagement.IMonitor and
933+
// Microsoft.SystemForCrossDomainIdentityManagement.Service are all defined in
934+
// Microsoft.SystemForCrossDomainIdentityManagement.Service.dll.
935+
Microsoft.SystemForCrossDomainIdentityManagement.IWebApplicationStarter starter;
936+
public Startup()
937+
{
938+
Microsoft.SystemForCrossDomainIdentityManagement.IMonitor monitor =
939+
new DevelopersMonitor();
940+
Microsoft.SystemForCrossDomainIdentityManagement.IProvider provider =
941+
new DevelopersProvider();
942+
this.starter =
943+
new Microsoft.SystemForCrossDomainIdentityManagement.WebApplicationStarter(
944+
provider,
945+
monitor);
946+
}
947+
public void Configuration(
948+
Owin.IAppBuilder builder) // Defined in Owin.dll.
949+
{
950+
this.starter.ConfigureApplication(builder);
951+
}
952+
}
953+
```
954+
955+
### Handling endpoint authentication
956+
957+
Requests from Azure Active Directory include an OAuth 2.0 bearer token. Any service receiving the request should authenticate the issuer as being Azure Active Directory for the expected Azure Active Directory tenant, for access to the Microsoft Graph API service. In the token, the issuer is identified by an iss claim, like "iss":"https://sts.windows.net/cbb1a5ac-f33b-45fa-9bf5-f37db0fed422/". In this example, the base address of the claim value, https://sts.windows.net, identifies Azure Active Directory as the issuer, while the relative address segment, cbb1a5ac-f33b-45fa-9bf5-f37db0fed422, is a unique identifier of the Azure Active Directory tenant for which the token was issued. The audience for the token will be the application template ID for the app in the gallery. The application template ID for all custom apps is 8adf8e6e-67b2-4cf2-a259-e3dc5476c621. The application template ID for each app in the gallery varies. Please contact [email protected] for questions on the application template ID for a gallery application. Each of the applications registered in a single tenant may receive the same `iss` claim with SCIM requests.
958+
959+
> [!NOTE]
960+
> It's ***not*** recommended to leave this field blank and rely on a token generated by Azure AD. This option is primarily available for testing purposes.
961+
Developers using the CLI libraries provided by Microsoft for building a SCIM service can authenticate requests from Azure Active Directory using the Microsoft.Owin.Security.ActiveDirectory package by following these steps:
962+
First, in a provider, implement the Microsoft.SystemForCrossDomainIdentityManagement.IProvider.StartupBehavior property by having it return a method to be called whenever the service is started:
963+
964+
```csharp
965+
public override Action<Owin.IAppBuilder, System.Web.Http.HttpConfiguration.HttpConfiguration> StartupBehavior
966+
{
967+
get
968+
{
969+
return this.OnServiceStartup;
970+
}
971+
}
972+
private void OnServiceStartup(
973+
Owin.IAppBuilder applicationBuilder, // Defined in Owin.dll.
974+
System.Web.Http.HttpConfiguration configuration) // Defined in System.Web.Http.dll.
975+
{
976+
}
977+
```
978+
979+
Next, add the following code to that method to have any request to any of the service’s endpoints authenticated as bearing a token issued by Azure Active Directory for a specified tenant, for access to the Microsoft Graph API service:
980+
981+
```csharp
982+
private void OnServiceStartup(
983+
Owin.IAppBuilder applicationBuilder IAppBuilder applicationBuilder,
984+
System.Web.Http.HttpConfiguration HttpConfiguration configuration)
985+
{
986+
// IFilter is defined in System.Web.Http.dll.
987+
System.Web.Http.Filters.IFilter authorizationFilter =
988+
new System.Web.Http.AuthorizeAttribute(); // Defined in System.Web.Http.dll.configuration.Filters.Add(authorizationFilter);
989+
// SystemIdentityModel.Tokens.TokenValidationParameters is defined in
990+
// System.IdentityModel.Token.Jwt.dll.
991+
SystemIdentityModel.Tokens.TokenValidationParameters tokenValidationParameters =
992+
new TokenValidationParameters()
993+
{
994+
ValidAudience = "8adf8e6e-67b2-4cf2-a259-e3dc5476c621"
995+
};
996+
// WindowsAzureActiveDirectoryBearerAuthenticationOptions is defined in
997+
// Microsoft.Owin.Security.ActiveDirectory.dll
998+
Microsoft.Owin.Security.ActiveDirectory.
999+
WindowsAzureActiveDirectoryBearerAuthenticationOptions authenticationOptions =
1000+
new WindowsAzureActiveDirectoryBearerAuthenticationOptions() {
1001+
TokenValidationParameters = tokenValidationParameters,
1002+
Tenant = "03F9FCBC-EA7B-46C2-8466-F81917F3C15E" // Substitute the appropriate tenant’s
1003+
// identifier for this one.
1004+
};
1005+
applicationBuilder.UseWindowsAzureActiveDirectoryBearerAuthentication(authenticationOptions);
1006+
}
1007+
```
1008+
7611009

7621010
## Step 4: Integrate your SCIM endpoint with the Azure AD SCIM client
7631011

0 commit comments

Comments
 (0)