Follow this procedure to set up Microsoft Entra ID (formerly known as Microsoft Azure Active Directory) as a proxy system.
-
You've logged on to Microsoft Azure Portal, with credentials for a user with directory role Global administrator. For more information, see Microsoft Entra built-in roles.
-
In Azure Active Directory > App registrations, you've registered an application with a secret key and permissions for Microsoft Graph API. These permissions must be consented by an administrator. For more information, see Microsoft Graph permissions reference.
-
(Relevant to target systems) Your registered application is assigned the User Account Administrator role. This role allows you to deprovision users. For more information, see Add-MsolRoleMember.
If this role isn't assigned, you can only disable users. To do that, set the
accountEnabled
property to false. For more information, see MS Graph: user resource type
Administrators of bundle tenants on Neo environment should enable the Manage OAuth Clients permission, as described in Neo Environment section in Manage Authorizations
↗️ .
Permissions
Assign the following permissions to your application, according to your scenario. Also, the permissions have to be of type Application.
- Users – User.ReadWrite.All, Directory.AccessAsUser.All
- Groups – Group.ReadWrite.All
For more information, see MS Graph: Users and MS Graph: Groups
When using it as a proxy system, you can write both users and groups, read from any source system you've added in the Identity Provisioning user interface. The Microsoft Entra ID proxy systems use Microsoft Graph API. For more information, see Microsoft Graph.
If you've successfully finished with the initial setup (described in the Prerequisites section), continue with the procedure.
The Identity Provisioning implementation of the Proxy System SCIM API (based on the SCIM Query) supports single entity and delta read filtering for users and groups. For more information, see Query Parameters for Proxy System SCIM API.
-
Open your subaccount in SAP BTP cockpit (valid for OAuth authentication to the Identity Provisioning proxy system).
If you have a bundle tenant, then in the cockpit → Neo → Overview, you can see the Global account, which SAP provides for your bundle in the corresponding Identity Provisioning region. Then, in the global account, you can see your subaccount, where the Identity Provisioning is enabled as a service for the bundle. The display name of the subaccount starts with SAP_BUNDLE.
-
Sign in to the administration console of SAP Cloud Identity Services and navigate to Users & Authorizations > Administrators.
-
Create a technical user with the necessary authorizations. It will later be used by the external consumer to connect to Identity Provisioning.
-
For Certificate-based authentication, follow the procedure in Manage Certificates for Inbound Connection → SAP BTP, Neo Environment
-
For OAuth authentication, proceed as follows:
-
Go to Security > OAuth > Clients and choose Register New Client.
-
From the Subscription combo box, select <provider_subaccount>/ipsproxy.
-
From the Authorization Grant combo box, select Client Credentials.
-
In the Secret field, enter a password (client secret) and remember it. You will need it later, for the repository configuration in the external system.
-
Copy/paste and save (in a notepad) the generated Client ID. You will need it later, too.
-
From the left-side navigation, choose Subscriptions > Java Applications > ipsproxy .
-
From the left-side navigation, choose Roles > IPS_PROXY_USER.
-
Choose Assign and enter oauth_client_<client_ID>.
For <client_ID>, enter the one you have saved in the previous main step.
-
-
For Certificate-based authentication, upload the certificate for the technical user of type System, as described in Add System as Administrator and enable the Access Proxy System API permission.
-
For Basic authentication, proceed as follows:
-
Add an administrator user of type System and configure the basic authentication method for this user.
If you already have a technical user, skip this step.
-
Save your changes.
-
Select your administrator user of type System and enable the Access Proxy System API permission.
-
Save your changes.
-
-
-
Access the Identity Provisioning UI.
-
Add Microsoft Entra ID as a proxy system. For more information, see Add New Systems.
-
Choose the Properties tab to configure the connection settings for your system.
If your tenant is running on SAP BTP, Neo environment, you can create a connectivity destination in your subaccount in the SAP BTP cockpit, and then select it from the Destination Name combo box in your Identity Provisioning User Interface.
If one and the same property exists both in the cockpit and in the Properties tab, the value set in the Properties tab is considered with higher priority.
We recommend that you use the Properties tab. Use a connectivity destination only if you need to reuse one and the same configuration for multiple provisioning systems.
Mandatory Properties
Property Name
Description & Value
Type
Enter: HTTP
URL
Enter: https://graph.microsoft.com
ProxyType
Enter: Internet
Authentication
Enter: BasicAuthentication
User
Enter the application ID registered in your Microsoft Entra ID subscription (see the Prerequisites section).
Password
(Credential) Enter the secret key associated to your app registration.
aad.domain.name
Enter one of the verified domain names from the corresponding Microsoft Entra ID tenant. On this domain, you perform the provisioning operations. For more information, see Managing custom domain names in your Microsoft Entra ID.
oauth.resource.name
Enter: https://graph.microsoft.com
OAuth2TokenServiceURL
Enter: https://login.microsoftonline.com/<your_domain>/oauth2/token, where
<your_domain>
is the domain name you have set in theaad.domain.name
property.(Optional)
aad.group.member.attributes
This property defines the attributes of a group member to be read by the Identity Provisioning. By default, it always reads the type and the id of a member.
If you want the Identity Provisioning to read additional attributes, enter them as a single or a comma-separated value. For example:
-
If you want to read the e-mails too, enter:
aad.group.member.attributes
=mailThis will read a member's type, ID, and e-mail.
-
If you want to read multiple additional attributes, enter:
aad.group.member.attributes
=mail,mobilePhone,displayNameThis will read a member's type, ID, e-mail, phone, and display name.
(Optional)
aad.user.attributes.membership.active
Use this property if you want to get information about all the groups to which the users are assigned (if any).
- If the property is missing, or is set to false – group membership details for the users will not be extracted.
- If the property is set to true – group membership details for the users will be extracted.
To learn more, see: List of Properties
(Optional)
aad.user.filter
Use this property to filter users by specific criteria, according to the Microsoft Graph REST API.
This property replaces the deprecated
msgraph-filter
property. To learn more, see: List of Properties(Optional)
aad.group.filter
Use this property to filter groups by specific criteria, according to the Microsoft Graph REST API.
(Optional)
aad.user.filter.group.filter.combine
Use this property to filter users based on their group assignments.
When set to true, this property combines user and group filters defined on the
aad.user.filter
andaad.group.filter
properties to further narrow the search results. This way, only users that meet the following filtering criteria are returned:-
Users that match the user filter and at the same time are members of groups that match the group filter.
-
Members of the filtered groups that match the user filter.
When set to false, user and group filters are not combined.
To learn more, see: List of Properties
(Optional)
aad.user.attributes
Defines which user attributes are read from Microsoft Entra ID system.
The property is set during system creation with the following default value: id,mail,userPrincipalName,displayName,mailNickname,givenName,surname,mobilePhone,businessPhones
This means that by default, Identity Provisioning will read from Microsoft Entra ID the user attributes defined in the property value. Those attributes are used in the default read transformation.
To check the complete set of user attributes (properties) supported by Microsoft Entra ID, see: Microsoft Graph: User Properties
To learn more, see: List of Properties
(Optional)
aad.group.attributes
Defines which group attributes are read from Microsoft Entra ID system.
The property is set during system creation with the following default value: id,displayName,mailNickname
This means that by default, Identity Provisioning will read from Microsoft Entra ID the group attributes defined in the property value and will also return the members attribute. Those attributes are used in the default read transformation.
To check the complete set of group attributes (properties) supported by Microsoft Entra ID, see: Microsoft Graph: Group Properties
To learn more, see: List of Properties
(Optional)
aad.entities.top
This property defines the number of entities to be read per page. Default value: 100
To learn what additional properties are relevant to this system, see List of Properties. You can use the main search, or filter properties by the Name or System Type columns.
-
-
(Optional) Configure the transformations.
Transformations are used to map the user attributes from the data model of the source system to the data model of the target system, and the other way around. The Identity Provisioning offers a default transformation for the Microsoft Entra ID proxy system, whose settings are displayed under the Transformations tab after saving its initial configuration.
You can change the default transformation mapping rules to reflect your current setup of entities in your Microsoft Entra ID. For more information, see:
Default read and write transformations:
The proxy Read Transformation is used when the external client application (for example, SAP Identity Management) makes initial load. That is, executing GET requests to the resource endpoints (/Users or /Groups) to retrieve the corresponding entities of the particular type. The external client application can also execute GET requests to a single resource endpoint (querying a single resource is supported). In this case, the proxy system acts as a source one.
The proxy Write Transformation is used when the external application manages the entities in the proxy system – creates new entities, updates existing ones, or deletes existing ones. In this case, the proxy system acts as a target one.
However, after a Create or Update operation is performed on the proxy system, the Read Transformation is applied to the result, so that the created or updated entity is sent back to the external application. This behavior demonstrates that the proxy Read Transformation is used for write cases, as well.
Read Transformation
Write Transformation
{ "user": { "scimEntityEndpoint": "Users", "condition": "$.userPrincipalName EMPTY false", "mappings": [ { "sourcePath": "$.id", "targetVariable": "entityIdSourceSystem", "targetPath": "$.id" }, { "sourceVariable": "entityBaseLocation", "targetVariable": "entityLocationSourceSystem", "targetPath": "$.meta.location", "functions": [ { "type": "concatString", "suffix": "${entityIdSourceSystem}" } ] }, { "constant": "urn:ietf:params:scim:schemas:core:2.0:User", "targetPath": "$.schemas[0]" }, { "sourcePath": "$.mail", "targetPath": "$.emails[0].value", "correlationAttribute": true }, { "sourcePath": "$.userPrincipalName", "targetPath": "$.userName", "correlationAttribute": true }, { "sourcePath": "$.displayName", "optional": true, "targetPath": "$.displayName" }, { "sourcePath": "$.mailNickname", "optional": true, "targetPath": "$.externalId", "correlationAttribute": true }, { "sourcePath": "$.givenName", "optional": true, "targetPath": "$.name.givenName" }, { "sourcePath": "$.surname", "optional": true, "targetPath": "$.name.familyName" }, { "sourcePath": "$.mobilePhone", "optional": true, "targetPath": "$.phoneNumbers[0].value" }, { "condition": "$.mobilePhone EMPTY false", "constant": "mobile", "targetPath": "$.phoneNumbers[0].type" }, { "sourcePath": "$.businessPhones[0]", "optional": true, "targetPath": "$.phoneNumbers[1].value" }, { "condition": "$.businessPhones.length() > 0", "constant": "work", "targetPath": "$.phoneNumbers[1].type" }, { "sourcePath": "$.groups", "preserveArrayWithSingleElement": true, "optional": true, "targetPath": "$.groups" }, { "sourcePath": "$.manager.id", "targetPath": "$['urn:ietf:params:scim:schemas:extension:enterprise:2.0:User']['manager']['value']", "optional": true }, { "sourcePath": "$.manager.displayName", "targetPath": "$['urn:ietf:params:scim:schemas:extension:enterprise:2.0:User']['manager']['displayName']", "optional": true } ] }, "group": { "scimEntityEndpoint": "Groups", "mappings": [ { "constant": "urn:ietf:params:scim:schemas:core:2.0:Group", "targetPath": "$.schemas[0]" }, { "sourcePath": "$.id", "targetVariable": "entityIdSourceSystem", "targetPath": "$.id" }, { "sourceVariable": "entityBaseLocation", "targetVariable": "entityLocationSourceSystem", "targetPath": "$.meta.location", "functions": [ { "type": "concatString", "suffix": "${entityIdSourceSystem}" } ] }, { "sourcePath": "$.displayName", "targetPath": "$.displayName" }, { "sourcePath": "$.members", "preserveArrayWithSingleElement": true, "optional": true, "targetPath": "$.members" }, { "targetPath": "$.members[*].id", "constant": "value", "type": "rename", "optional": true } ] } }
{ "user": { "scimEntityEndpoint": "Users", "mappings": [ { "optional": true, "sourcePath": "$.onPremisesImmutableId", "targetPath": "$.onPremisesImmutableId" }, { "sourcePath": "$.active", "optional": true, "targetPath": "$.accountEnabled" }, { "sourcePath": "$.name.givenName", "optional": true, "targetPath": "$.mailNickname" }, { "sourcePath": "$.displayName", "optional": true, "targetPath": "$.displayName" }, { "sourcePath": "$.name.givenName", "optional": true, "targetPath": "$.givenName" }, { "sourcePath": "$.name.familyName", "optional": true, "targetPath": "$.surname" }, { "sourcePath": "$.addresses[0].locality", "optional": true, "targetPath": "$.city" }, { "sourcePath": "$.addresses[0].country", "optional": true, "targetPath": "$.country" }, { "scope": "createEntity", "sourcePath": "$.userName", "targetPath": "$.userPrincipalName", "functions": [ { "type": "concatString", "suffix": "@%aad.domain.name%" } ] }, { "scope": "createEntity", "constant": "true", "targetPath": "$.accountEnabled" }, { "scope": "createEntity", "sourcePath": "$.active", "optional": true, "targetPath": "$.accountEnabled" }, { "scope": "createEntity", "sourcePath": "name.givenName", "targetPath": "$.mailNickname" }, { "scope": "createEntity", "sourcePath": "$.displayName", "targetPath": "$.displayName" }, { "scope": "createEntity", "targetPath": "$.passwordProfile.password", "functions": [ { "type": "randomPassword", "passwordLength": 16, "minimumNumberOfLowercaseLetters": 1, "minimumNumberOfUppercaseLetters": 1, "minimumNumberOfDigits": 1, "minimumNumberOfSpecialSymbols": 0 } ] }, { "scope": "createEntity", "constant": false, "targetPath": "$.passwordProfile.forceChangePasswordNextSignIn" } ] }, "group": { "scimEntityEndpoint": "Groups", "mappings": [ { "sourceVariable": "entityIdTargetSystem", "targetPath": "$.id" }, { "optional": true, "sourcePath": "$.displayName", "targetPath": "$.displayName" }, { "scope": "createEntity", "sourcePath": "$.displayName", "targetPath": "$.displayName" }, { "scope": "createEntity", "sourcePath": "$.externalId", "targetPath": "$.mailNickname" }, { "scope": "createEntity", "constant": true, "targetPath": "$.mailEnabled" }, { "scope": "createEntity", "constant": false, "targetPath": "$.securityEnabled" }, { "scope": "createEntity", "constant": "Unified", "targetPath": "$.groupTypes[0]" } ] } }
Custom Configurations
Goal
Action
Result
You want Identity Provisioning to read the additional user attributes specified in property
aad.user.attributes
and write them successfully in the external back-end system.In the Read Transformation, extend the "user" mapping as follows:
{ "user": { "condition": "$.userPrincipalName EMPTY false", "mappings": [ { "sourcePath": "$", "targetPath": "$" }, { "sourcePath": "$.id", "targetVariable": "entityIdSourceSystem" }, ...
For example, you specify the
aad.user.attributes
property and set its value to: id,mail,userPrincipalName,city,department,companyNameAs a result, every user in the external back-end system will have the following attributes populated – ID, e-mail, user principle name, city, department, and company name.
Returned information of an exemplary user:
... { "Resources":[ { "id":"555-aaaa-333-abcd-111222333", "mail":"[email protected]", "userPrincipalName":"[email protected]", "city": "Sofia", "department":"029", "companyName":"SAP" } ... ] }
You want Identity Provisioning to read the additional group attributes specified in property
aad.group.attributes
and write them successfully in the target system.Extend the "group" mapping as follows:
{ "group": { "ignore": false, "mappings": [ { "sourcePath": "$", "targetPath": "$" }, { "constant": "urn:ietf:params:scim:schemas:core:2.0:Group", "targetPath": "$.schemas[0]" }, ...
Example: Specify the
aad.group.attributes
property and set its value to: id,displayName,recommendation,isSubscribedByMailAs a result, every group in the target system will have the following attributes populated – ID, display name, date and time of the last renewal, and information if it's subscribed by e-mail or not.
Returned information of an exemplary group:
... { "Resources":[ { "id":"12345-ccc-000-xyz-777888999", "displayName":"ImportantGroup3", "renewedDateTime":"2018-01-01T00:00:00Z", "isSubscribedByMail":"true" } ... ] }
You want the returned value of a group member to be not the ID but a different attribute.
Replace id with the new attribute. For example:
If you replace id with mail, the transformation will look like this:
... { "sourcePath": "$.members", "preserveArrayWithSingleElement": true, "optional": true, "targetPath": "$.members" }, { "targetPath": "$.members[*].mail", "constant": "value", "type": "rename", "optional": true } ...
Make sure that you've added this attribute as a value of property aad.group.member.attributes.
Returned information of an exemplary group member:
... { "members":[ { "id":"5555555-aaaa-333-abcd-1111122223333", "type":"user", "value":"[email protected]" } ] } ...
-
Connect the external consumer to Identity Provisioning with the technical user you have created in step 2.
If the external consumer system is SAP Identity Management, you can export the newly created proxy system as a SCIM repository from Identity Provisioning and import it in SAP Identity Management. This will create a SCIM repository in SAP Identity Management where most of the repository constants will be automatically filled in. You need to provide the technical user credentials that you have set up in step 2 and the SCIM assignment method as described below:
-
For AUTH_USER and AUTH_PASSWORD, enter your client ID and secret.
-
For the SCIM_ASSIGNMENT_METHOD constant, make sure the value is PUT.
-
For AUTH_USER and AUTH_PASSWORD, enter the user ID and password of the Identity Authentication technical user for which you have set permission Access Proxy System API.
-
For the SCIM_ASSIGNMENT_METHOD constant, make sure the value is PUT.
For external consumer systems, other than SAP Identity Management, you should also use the PUT method for modifying entities.
-
When a proxy system is connected to an external backend system (in the case of SAP Identity Management this means the exported CSV file is imported into the Identity Management Admin UI and a repository is configured), you can start managing the users and groups into this external system. Usually, the first operation is the initial load of the existing entities into your external system. When this load has finished, changes in the external system, such as creating new users or updating existing ones, can trigger CRUD requests back to the proxy system.
To see an example with SAP Identity Management, see Hybrid Scenario: SAP Identity Management → sections Next Steps and Future Identity Lifecycle.
Effective September 2020, Shanghai (China) tenants that reside on SAP BTP, Neo environment can be only accessed on the following domain:
dispatcher.cn1.platform.sapcloud.cn
So make sure you use the correct domain when you construct your REST API requests.
For example: GET https://ipsproxyabcd12345-xyz789.dispatcher.cn1.platform.sapcloud.cn/ipsproxy/api/v1/scim/bbb111aa-1234-aaaa-7777-1234567abcde/Users/s123456789
To learn more, see: Proxy Systems