Connecting to Azure with SCIM v2.0

Azure AD supports User and Group provisioning via SCIM v2.0 for the Azure Enterprise Apps.

Microsoft also offers rich documentation on this topic here: https://docs.microsoft.com/en-us/azure/active-directory/app-provisioning/user-provisioning

Setup

  1. The fIrst step, is to create an Enterprise App Registration in your Azure AD Tenant.
19211921
  1. Click "New application".
19241924
  1. Click "Create your own application".
19201920
  1. Give the application a name such as intranet.acme.com - SCIM Provisioning, select "Integrate any other application you don't find in the gallery (Non-gallery)", and hit "Create"
19181918
  1. Wait for the application to create.
  2. Click "Provisioning", and then click "Get Started".
19191919
  1. Select "Automatic", fill in the form, and hit "Test Connection".
  • Tenant URL: https://intranet.acme.com/api/v2/scim/v2 <- intranet.acme.com should be replaced with your intranet domain.
  • Secret Token: This is generated under Application Settings -> Manage Profiles -> Manage Profile Sources -> (you can generate a new SCIM connector and Secret Token here)
19201920
  1. Wait for the Connection Test to finish. You will get a notification to tell you if the connection worked or not.

Successful connection example:

  • Everything is good, and Azure AD can communicate with Interact's SCIM service.
19191919

Unsuccessful connection example:

  • Check the domain and path are correct.
  • Check the Secret Token value and make sure it is correct.
19201920
  1. Once the connection has been successful, hit "Save".
19191919
  1. Now you will be given 2 more sections for configuration. "Mappings", and "Settings".
  • Mappings - we need to adjust them (in the following steps.)
  • Settings - you can add an email address where you'd like provisioning failure notifications from Azure AD (highly recommended.)
19191919
  1. Click "Save" (we'll adjust the mappings in a later step.)
19191919
  1. Go back to the Application main screen.
19191919

Mappings

  1. Shown below, are the links to control the settings for your Provisioning setup. Click on "Edit attribute mappings".
19201920
  1. There are a few additional attributes that need adding, for the Provisioning requests to contain all information required by Interact.

Let's start with Groups.
(If the Mappings panel is grayed out - give it a minute to load - it loads asynchronously on the page, and sometimes it can be quite slow to "enable" itself.)

Click "Provision Azure Active Directory Groups".

19191919
  1. Here you can see a few options related to provisioning Azure AD Groups, into an external system.

Target Object Actions allow you to control if you want to sent Create/Update/Delete events to the target system. eg. If you wanted groups to be synchronized to your Intranet, but didn't want them to be deleted from the Intranet, if the group was deleted in Azure, simply uncheck the "Delete" option.

Attribute Mappings shows the mapping table for taking Group properties in Azure AD, and mapping them to the SCIM schema. This is a very powerful tool, as it allows you to go beyond basic data field mappings, and allows you to use expressions to make logical expressions, and transform your data, before it is sent to your Intranet.

Supported Attributes is where you control which attributes you can map to. In Interact's case, we support several SCIM Extension schemas, specific to Interact, to really allow you to leverage your Intranet's functionality with SCIM. This is where you define the extra fields you want Azure AD to populate when provisioning your objects.

If you are performing tests, it might be best to initially turn off the "Delete" capability.

Click on "Edit attribute list for customappsso".

19201920
  1. Now, add a new attribute with the following details:
  • Name: urn:ietf:params:scim:schemas:extension:interactsoftware:2.0:Group:groupType
  • Type: String
  • Required: Yes

(This attribute is part of an Interact custom SCIM schema, and is required for groups to be provisioned successfully.)

19201920
  1. Hit "Save", and confirm the prompt by clicking "Yes".
19201920
  1. Now, we'll add a new mapping to the new attribute we have just defined.

Click "Add New Mapping".

19201920
  1. Here you can specify how you want to populate this value, the simplest option is the following setup:
  • Mapping type: Constant <- feel free to use an Expression if you'd like to make the groupType dynamic. The expression should yield any of the SCIM values in the table below (must be lower case) to provide a dynamic behaviour to the provisioned group type.
  • Constant Value: group
  • Target attribute: urn:ietf:params:scim:schemas:extension:interactsoftware:2.0:Group:groupType
Group TypeExpected SCIM Value
Companycompany
Departmentdepartment
Locationlocation
Security Groupgroup
19201920
  1. You should see your new mapping in the table as shown.
    Now, hit "OK", and confirm the prompt by clicking "Yes", to confirm your changes.
19201920
  1. Go back to the "Provisioning" screen.
19191919
  1. Click "Provision Azure Active Directory Users".
19201920
  1. This is the default mapping set proposed by Azure AD. Please remove the following Attribute Mappings from the table (customappsso Attribute column names):
  • displayName
  • name.formatted
  • addresses[type eq "work"].streetAddress
  • addresses[type eq "work"].locality
  • addresses[type eq "work"].region
  • addresses[type eq "work"].postalCode
  • addresses[type eq "work"].country
  • phoneNumbers[type eq "fax"].value
  • urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:employeeNumber

These columns are not supported in Interact's schema.

  • Recommendation: Use the granular address fields, to concatenate the full address, into a single value which goes into addresses[type eq "work"].formatted, so that the full address makes it to Interact upon provisioning.
19201920
  1. The table should look like this after the deletions have taken place. We highly recommend that for the User mapping field emails[type eq "work"].value, you switch this to Matching precedence of 2. This will make it so that before a new user is created within Interact, it will check both the username and primary email address.

Now we need to add the missing required Interact attributes.

Click "Edit attribute list for customappsso".

19201920
  1. Add the following new attributes:
NameType
urn:ietf:params:scim:schemas:extension:interactsoftware:2.0:User:locationString
urn:ietf:params:scim:schemas:extension:interactsoftware:2.0:User:loginTypeString

Make sure to remove any leading or trailing white space

Once added, hit "Save", and then confirm the changes by clicking "Yes" in the prompt.

19191919
  1. Click "Add New Mapping"
19191919
  1. Add the following 3 mappings:
Mapping TypeConstant Value/Source AttributeTarget Attribute
Constant

(feel free to use a Direct mapping or expression if you would like to load this value from another field, or an expression)
ACME

(this is your organisation name)
urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:organization
Direct

(feel free to use an expression if you would like to load this value from another field, or an expression)
Source Attribute: city

(feel free to use a more appropriate field relevant to your organisation.)
urn:ietf:params:scim:schemas:extension:interactsoftware:2.0:User:location
Constant

(feel free to use a Direct mapping or expression if you would like to load this value from another field, or an expression)
SAML

(other valid option is "Local Login", or "Windows Login")
urn:ietf:params:scim:schemas:extension:interactsoftware:2.0:User:loginType

Hit "Save", and then click "Yes" to confirm the changes in the prompt.

19191919

NOTE: It is worth noting that this is the process for adding further Interact fields that go beyond the minimal mapping required for the Provisioning to work - this may include:

  • The extended list of profile fields supported by Interact.
  • Additional fields declared by you within your Interact instance.
    etc.

The full list of fields supported on your Interact site can be loaded by calling the following Schema Discovery endpoint.

https://developer.interactsoftware.com/docs/scim-v20#supported-schemas

(Unfortunately, whilst Interact does support automatic schema discovery, Azure AD Provisioning does not, which requires the entry of new supported attributes to be done manually.)

  1. Go back to the Application page.

Selecting Users and Groups for Synchronisation

There are 2 ways of specifying which users and groups get synchronized to your Intranet.

  • Assigned Users and Groups Only
  • All Users and Groups.

All Users and Groups

  1. Click "Add scoping filters"
19191919
  1. Change the "Scope" to "Sync all users and groups". Hit "Save", and go back to the Application Page.

(If the dropdown is not there, give it a minute until the Mappings panel loads - the 2 options are loaded asynchronously and may seem delayed.)

19201920

Assigned Users and Groups Only

  1. Click on "Users and Groups", and click on "Add user/group".
19191919
  1. Use the search function provided to find the Users and Groups you'd like to select.

Select the desired users and groups.

Once done, click "Select".

19181918
  1. Hit "Assign".
19191919
  1. You should now see your users and groups assigned in the "Users and groups" table.
19181918

Enable Provisioning

Now that all the setup has been done, we're ready to enable the provisioning.

  1. On the "Provisioning" page of the application, hit "Start Provisioning".
19201920
  1. Once the Provisioning completes, you'll see the status (and any errors) on this "Provisioning" page.

(Example screenshot shown below.)

19181918

Troubleshooting

  • Make sure to utilize the Provisioning Logs provided by Azure AD.

  • Interact's SCIM implementation has been designed to be extremely verbose and provide necessary context with all errors, to ensure you have everything needed to resolve any issues.

  • You can check if the SCIM service is functional by opening your browser and using https://{yourURL}/api/v2/scim/v2/health. You might want to check this if you receive any errors like this:
    Error Code: SystemForCrossDomainIdentityManagementCredentialValidationUnavailable
    An HTTP/404 Not Found response was returned rather than the expected HTTP/200 OK response.

  • Errors will mention issues with specific attributes. eg.

    • Bad value type for attribute X
    • Missing attribute Y
    • Value in attribute Z does not comply to a required format (.....)
    • etc.
  • If the manager sync functionality is not working while you are testing this functionality, you need to ensure that, within Azure, the manager is part of the users being synced. The reconciliation of the manager information has to happen at the Azure side not within Interact... so the manager is required to be part of the Azure Provisioning.

Known Limitations of Azure AD SCIM support

  • Provisioning:

    • Groups. With an Azure AD Premium license plan, you can use groups to assign access to a SaaS application. Then, when the provisioning scope is set to Sync only assigned users and groups, the Azure AD provisioning service will provision or de-provision users based on whether they're members of a group that's assigned to the application. The group object itself isn't provisioned unless the application supports group objects. Ensure that groups assigned to your application have the property "SecurityEnabled" set to "True".
      • Dynamic groups. The Azure AD user provisioning service can read and provision users in dynamic groups. Keep these caveats and recommendations in mind:
      • Dynamic groups can impact the performance of end-to-end provisioning from Azure AD to SaaS applications.
      • How fast a user in a dynamic group is provisioned or de-provisioned in a SaaS application depends on how fast the dynamic group can evaluate membership changes. For information about how to check the processing status of a dynamic group, see Check processing status for a membership rule.
      • When a user loses membership in the dynamic group, it's considered a de-provisioning event. Consider this scenario when creating rules for dynamic groups.
    • Nested groups. The Azure AD user provisioning service can't read or provision users in nested groups. The service can only read and provision users that are immediate members of an explicitly assigned group. This limitation of "group-based assignments to applications" also affects single sign-on (see Using a group to manage access to SaaS applications). Instead, directly assign or otherwise scope in the groups that contain the users who need to be provisioned.
    • You cannot have an additional field inside Interact that has a questions mark (i.e. ?) in the field name or the process will not work. You will receive an Error 500 when trying to perform any activity within SCIM until the issue is resolved. You will need to remove the field completely and recreate it without a question mark.
    • Azure will not push an item to Interact if it is null.  So effectively it uses logic similar to Interact's "ApplyBlank" logic for all fields.  The "default value" field only works on the initial sync but doesn't help with subsequent syncs.  This causes an issue when you are dealing with required fields. If you want to force a field to either not be blank or force it to sync despite a null value, you can switch from a "direct" field mapping type to "expression" and use the following (as an example): Coalesce([otherMails], " ") Articles for reference: 
      https://docs.microsoft.com/en-us/azure/active-directory/app-provisioning/functions-for-customizing-application-data
      https://docs.microsoft.com/en-us/answers/questions/208948/user-provisioning-skipped-when-removing-user39s-at.html
      https://docs.microsoft.com/en-us/azure/active-directory/app-provisioning/known-issues
    • If you have an issue where Power User permissions are being removed, you need to make the following configuration change: for the User mapping field emails[type eq "work"].value, you need to switch the "Match objects using this attribute" setting to yes and "Matching precedence" to 2. If you already ran an sync and wiped Power User access, you will need to manually re-add this permission for your users.
    • If you are migrating from using Azure via the Manage Profile Sources inside Interact to Azure via SCIM and you have existing users in the Interact system that you do not want to delete or alter in the wrong way, you need to first gather the following information from Azure:
      mailNickName
      userPrincipalName
      mail
      givenName
      surname
      EntityID (or UID)
    • Then you need to compare that information with the following fields within Interact:
      UserName
      UID
      Email
      First Name
      Last Name
    • If you want no disruption in your existing users, you will need to map the proper values from Azure to the fields in Interact (i.e. how it was being done in Azure within Manage Profiles Sources) before performing the first sync.
    • You need to be very careful with using Azure's mapping type "constant". If you map a constant to a field like Organization, it will initially set that value as you intend; however, if you allow users to update their Organization manually, this will work unless you ever have an occasion to restart the Provisioning process. And if that happens, you could lose all the manual adjustments that users made to the Organization field because the constant could be pushes again. The better solution is to use the mapping type "None" and set a default value. Here is how Microsoft describes the "None" type: "None - the target attribute is left unmodified. However, if the target attribute is ever empty, it's populated with the Default value that you specify." This is exactly what most clients want... not a hardcoded value that is always that way but an initial default value that you expect users to adjust after the initial sync.  Overall, be careful with constants in Azure mapping especially when you are migrating from UMI to SCIM and have existing users... this "None" option is the best way to handle default values when the data doesn't exist in Azure.
    • When you need to map to the jobStartDate field, your data typically doesn't exist in the RFC3339 format that Interact expects.  Example: your field in Azure is of a "M/d/yyyy" or "MM/dd/yyyy" format but you need Interact's "yyyy-MM-ddTHH:mm:ssZ" format.  You can handle it with this expression: FormatDateTime([extensionAttribute8], , "M/d/yyyy", "yyyy-MM-ddTHH:mm:ssZ").  And if the format is different like MM/dd/yyyy, just replace that in the appropriate area.  Remember, zeroes matter so make sure you truly understand if a single digit month or day will have a leading zero or not. 
    • There are many expressions available within Azure to help with formatting data. See https://docs.microsoft.com/en-us/azure/active-directory/app-provisioning/functions-for-customizing-application-data for more detail. A frequently requested expression is for concatenating values. Use the JOIN command with a separator of "".
  • Deprovisioning:

    • If a user that was previously managed by the provisioning service is unassigned from an app, or from a group assigned to an app we will send a disable request. At that point, the user is not managed by the service and we will not send a delete request when they are deleted from the directory.
    • Provisioning a user that is disabled in Azure AD is not supported. They must be active in Azure AD before they are provisioned.
    • When a user goes from soft-deleted to active, the Azure AD provisioning service will activate the user in the target app, but will not automatically restore the group memberships. The target application should maintain the group memberships for the user in inactive state. If the target application does not support this, you can restart provisioning to update the group memberships.
      Source (https://docs.microsoft.com/en-us/azure/active-directory/app-provisioning/how-provisioning-works#provisioning-using-scim-20)
    • Microsoft says the following about SCIM deprovisioning:
584584

For the Red arrow, it basically says that if you soft delete, Azure will not send Interact a notification for 30 days. But in the meantime, the user is not able to login because the SSO app no longer supports that user. And 30 days later, the Interact license issue is cleaned-up by Azure by sending Interact the DELETE command (and thus the user is inactivated). This solution addresses the Interact licensing concern (since 30 days later the license is released by the inactive user) and the user cannot login (due to SSO); however, we find that many customers don't like this solution because 1) they don't want to wait 30 days for the user to be removed from Interact and 2) theoretically the user could log into our app (though that cannot happen because SSO won't work for the user... and even if they tried to login locally, the account is probably setup for SAML and there are no local credentials).

For the Yellow arrow, this is not an ideal solution but it works and SCIM sends Interact the DELETE command. So the user is removed immediately from Interact.

For the Purple arrow, don’t skip over this one quickly. Microsoft is very shrewdly saying that if you remove a user from an Azure SCIM app, it will send the DELETE command. What they don’t tell you is that most companies won’t put individual users in the Azure SCIM app… they register a Group (like Everyone group, Interact Users, etc.)… and removal of the user from the group that is part of the Azure SCIM app doesn’t fire the DELETE command.

If you are concerned with how deprovisioning works, we suggest that you file a ticket with Microsoft.

More information on bugs, and known issues in Azure AD Provisioning functionality, can be found here:
https://docs.microsoft.com/en-us/azure/active-directory/app-provisioning/known-issues