---
title: Microsoft Graph API Java connector
description: Connectors continue to be released outside the IDM release. For the latest documentation, refer to the OpenICF documentation.
component: pingidm
version: 7.2
page_id: pingidm:connector-reference:ms-graph-api
canonical_url: https://docs.pingidentity.com/pingidm/7.2/connector-reference/ms-graph-api.html
section_ids:
  msgraphi-before-you-start: Before you start
  ms-graph-api-configure: Configure the MS Graph API connector
  ms-graph-api-test: Test the MS Graph API connector
  ms-graph-api-licenses: Manage user licenses
  ms-graph-api-sync: Synchronize accounts between IDM and Azure
  implemented-interfaces-org-forgerock-openicf-connectors-msgraphapi-MSGraphAPIConnector-1.5.20.15: OpenICF Interfaces Implemented by the MSGraphAPI Connector
  config-properties-org-forgerock-openicf-connectors-msgraphapi-MSGraphAPIConnector-1.5.20.15: MSGraphAPI Connector Configuration
  basic-configuration-properties-org-forgerock-openicf-connectors-msgraphapi-MSGraphAPIConnector-1.5.20.15: Basic Configuration Properties
---

# Microsoft Graph API Java connector

|   |                                                                                                                                                                                   |
| - | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | Connectors continue to be released outside the IDM release. For the latest documentation, refer to the [OpenICF documentation](https://docs.pingidentity.com/openicf/index.html). |

The Microsoft (MS) Graph API Java connector uses the [Microsoft Graph SDK for Java](https://github.com/microsoftgraph/msgraph-sdk-java) and the [Authentication Providers for the Microsoft Graph Java SDK](https://github.com/microsoftgraph/msgraph-sdk-java-auth). Unlike the [PowerShell connector for Azure](powershell.html#powershell-connector-azure), the MS Graph API connector is a Java connector, and does not need [.NET RCS](remote-connector.html#install-.net-connector) to run. As a Java connector, the MS Graph API connector functions like any standard IDM connector.

The MS Graph API connector can read, search, and fetch data from Microsoft Azure, when Azure is the authoritative data source, and can provision to Azure, when IDM is the authoritative data source.

The MS Graph API connector is bundled with IDM, and available from the [ForgeRock Download Center](https://backstage.forgerock.com/downloads/browse/idm/featured/connectors). The connector bundles all its dependencies.

## Before you start

Before you can use the connector, you must register an application with Azure. You need a Microsoft Azure subscription to complete this procedure:

1. Log in to the [MS Azure portal](https://portal.azure.com/) as an administrative user.

2. Under Azure services , select App registrations.

3. On the Register an application page, enter a name for the application; for example, FR-Connector.

4. Select the supported account types, and enter a Redirect URI.

   The redirect URI is the IDM URI that Azure should redirect to after successful authentication; for example, `https://idm.example.com:8443/`.

5. On the new registration page for your application, make a note of the Application (client) ID and the Directory (tenant) ID. You will need these to configure the connector:

   ![shared:ms-graph-api-app](../_images/ms-graph-api-app.png)

6. Generate a client secret:

   1. Select Certificates & secrets > New client secret .

   2. Enter a description, select an expiration date, and click Add.

   3. Copy the client secret Value:

      ![shared:ms-graph-api-secret](../_images/ms-graph-api-secret.png)

   |   |                                                                                             |
   | - | ------------------------------------------------------------------------------------------- |
   |   | You will not be able to retrieve the client secret in cleartext after you exit this screen. |

7. Set the API permissions:

   1. Select API permissions, click Microsoft Graph, and then click Application permissions.

      ![shared:ms-graph-api-app-permissions](../_images/ms-graph-api-app-permissions.png)

   2. From the User item, select the following permissions:

      * `User.Export.All`

      * `User.ManageIdentities.All`

      * `User.Read.All`

      * `User.ReadWrite.All`

   3. From the Group item, select the following permissions:

      * `Group.Create`

      * `Group.Read.All`

      * `Group.ReadWrite.All`

   4. From the Directory item, select the following permissions:

      * `Directory.Read.All`

      * `Directory.ReadWrite.All`

   5. Click Add permissions .

8. Grant admin consent for the API permissions:

   On the Configured permissions page, Grant admin consent for org-name, then click Yes.

   ![shared:ms-graph-api-consent](../_images/ms-graph-api-consent.png)

## Configure the MS Graph API connector

IDM bundles version 1.5.20.15 of the MS Graph API connector in the `openidm/connectors` directory. Alternatively, download the connector .jar file from the [ForgeRock Download Center](https://backstage.forgerock.com/downloads/browse/idm/featured/connectors)

Create a connector configuration using the admin UI:

1. From the navigation bar, click Configure > Connectors.

2. On the Connectors page, click New Connector.

3. On the New Connector page, type a Connector Name.

4. From the Connector Type drop-down list, select MSGraphAPI Connector - 1.5.20.15.

5. Complete the Base Connector Details.

6. Click Save.

Alternatively, copy the sample connector configuration file from `/path/to/openidm/samples/example-configurations/provisioners/provisioner.openicf-azuread.json` to your project's `conf/` directory.

Set at least the Azure `tenant`, `clientId` and `clientSecret` in the `configurationProperties`. For example:

```json
"configurationProperties" : {
    "tenant" : "your tenant ID",
    "clientId" : "your client ID",
    "clientSecret" : "your client secret"
}
```

## Test the MS Graph API connector

Start IDM, if it is not running. Then use these examples to test that the connector is configured correctly and operating as expected:

> **Collapse: Check the Connector Configuration**
>
> ```
> curl \
> --header "X-OpenIDM-Username: openidm-admin" \
> --header "X-OpenIDM-Password: openidm-admin" \
> --header "Accept-API-Version: resource=1.0" \
> --request POST \
> "http://localhost:8080/openidm/system?_action=test"
> {
>   "name": "azuread",
>   "enabled": true,
>   "config": "config/provisioner.openicf/azuread",
>   "connectorRef": {
>     "bundleVersion": "[1.5.19.0,1.6.0.0]",
>     "bundleName": "org.forgerock.openicf.connectors.msgraphapi-connector",
>     "connectorName": "org.forgerock.openicf.connectors.msgraphapi.MSGraphAPIConnector"
>   },
>   "displayName": "MSGraphAPI Connector",
>   "objectTypes": [
>     "subscribedSku",
>     "team",
>     "user",
>     "__ALL__",
>     "group"
>   ],
>   "ok": true
> }
> ```
>
> A status of `"ok": true` indicates that the connector is configured correctly.

> **Collapse: List User Entries**
>
> This command retrieves a list of users in your Azure tenant. You can also use any system-enabled filter, such as those described in [Construct Queries](../objects-guide/queries.html#constructing-queries):
>
> ```
> curl \
> --header "X-OpenIDM-Username: openidm-admin" \
> --header "X-OpenIDM-Password: openidm-admin" \
> --header "Accept-API-Version: resource=1.0" \
> --request GET \
> "http://localhost:8080/openidm/system/azuread/user?_queryId=query-all-ids"
> {
>   "result": [
>     {
>       "_id": "c48be8cc-5846-4059-95e8-a7acbf6aec31"
>     },
>     {
>       "_id": "c7fe57e2-3159-45e1-b67a-435232fd88d9"
>     },
>     {
>       "_id": "9e714b5c-345a-430c-93f5-d8c6f9a2f225"
>     },
>     ...
>   ],
>   ...
> }
> ```

> **Collapse: Return a User Entry**
>
> This command retrieves a specific user entry from your Azure tenant:
>
> ```
> curl \
> --header "X-OpenIDM-Username: openidm-admin" \
> --header "X-OpenIDM-Password: openidm-admin" \
> --header "Accept-API-Version: resource=1.0" \
> --request GET \
> "http://localhost:8080/openidm/system/azuread/user/c48be8cc-5846-4059-95e8-a7acbf6aec31"
> {
>   "_id": "c48be8cc-5846-4059-95e8-a7acbf6aec31",
>   "surname": "Jensen",
>   "displayName": "Babs Jensen",
>   "memberOf": [
>     "036f288c-6f71-41ae-9d09-6a68c8ba315b"
>   ],
>   "mail": "babs.jensen@example.onmicrosoft.com",
>   "onPremisesExtensionAttributes": {
>     ...
>   },
>   "usageLocation": "FR",
>   "userType": "Member",
>   "identities": [
>     {
>       "signInType": "userPrincipalName",
>       "issuerAssignedId": "00991235@example.onmicrosoft.com",
>       "issuer": "example.onmicrosoft.com"
>     }
>   ],
>   "businessPhones": [],
>   "createdDateTime": "2020-11-20T11:09:15Z",
>   "accountEnabled": true,
>   "userPrincipalName": "00991235@example.onmicrosoft.com",
>   "proxyAddresses": [
>     "smtp:00991235@example.onmicrosoft.com",
>     "SMTP:babs.jensen@example.onmicrosoft.com"
>   ],
>   "imAddresses": [],
>   "passwordPolicies": "None",
>   "mailNickname": "00991235",
>   "givenName": "Babs",
>   "__NAME__": "00991235@example.onmicrosoft.com"
> }
> ```

> **Collapse: Create Users or Groups**
>
> This command creates a new user in your Azure tenant:
>
> ```
> curl \
> --header "X-OpenIDM-Username: openidm-admin" \
> --header "X-OpenIDM-Password: openidm-admin" \
> --header "Accept-API-Version: resource=1.0" \
> --request POST \
> --header "content-type: application/json" \
> --data '{
>   "surname": "Carter",
>   "displayName": "Steve Carter",
>   "givenName": "Steve",
>   "userType": "Member",
>   "accountEnabled": true,
>   "mailNickname": "00654321",
>   "userPrincipalName": "00654321@forgedemo.onmicrosoft.com",
>   "__PASSWORD__": "MyPassw0rd"
> }' \
> "http://localhost:8080/openidm/system/azuread/user?_action=create"
> {
>   "_id": "9fa6c765-0872-45f6-8714-1dcd1ed94859",
>   "surname": "Carter",
>   "displayName": "Steve Carter",
>   "memberOf": [],
>   "onPremisesExtensionAttributes": {
>     "extensionAttribute14": null,
>     ...
>   },
>   "userType": "Member",
>   "identities": [
>     {
>       "signInType": "userPrincipalName",
>       "issuerAssignedId": "00654321@example.onmicrosoft.com",
>       "issuer": "example.onmicrosoft.com"
>     }
>   ],
>   "businessPhones": [],
>   "createdDateTime": "2020-12-18T13:23:58Z",
>   "accountEnabled": true,
>   "userPrincipalName": "00654321@example.onmicrosoft.com",
>   "proxyAddresses": [],
>   "imAddresses": [],
>   "mailNickname": "00654321",
>   "givenName": "Steve",
>   "__NAME__": "00654321@example.onmicrosoft.com"
> }
> ```

> **Collapse: Update Entries**
>
> This command changes the password for the user created previously:
>
> ```
> curl \
> --header "X-OpenIDM-Username: openidm-admin" \
> --header "X-OpenIDM-Password: openidm-admin" \
> --header "Accept-API-Version: resource=1.0" \
> --request PATCH \
> --header "content-type: application/json" \
> --data '[ {
>   "operation": "replace",
>   "field": "__PASSWORD__",
>   "value": "MyNewPassw0rd"
> } ]' \
> "http://localhost:8080/openidm/system/azuread/user/9fa6c765-0872-45f6-8714-1dcd1ed94859"
> {
>   "_id": "9fa6c765-0872-45f6-8714-1dcd1ed94859",
>   "surname": "Carter",
>   "displayName": "Steve Carter",
>   "memberOf": [],
>   "onPremisesExtensionAttributes": {
>     "extensionAttribute14": null,
>     ...
>   },
>   "userType": "Member",
>   "identities": [
>     {
>       "signInType": "userPrincipalName",
>       "issuerAssignedId": "00654321@forgedemo.onmicrosoft.com",
>       "issuer": "forgedemo.onmicrosoft.com"
>     }
>   ],
>   "businessPhones": [],
>   "createdDateTime": "2020-12-18T13:23:58Z",
>   "accountEnabled": true,
>   "userPrincipalName": "00654321@forgedemo.onmicrosoft.com",
>   "proxyAddresses": [],
>   "imAddresses": [],
>   "mailNickname": "00654321",
>   "givenName": "Steve",
>   "__NAME__": "00654321@forgedemo.onmicrosoft.com"
> }
> ```

> **Collapse: Delete Users and Groups**
>
> This command deletes the user created previously:
>
> ```
> curl \
> --header "X-OpenIDM-Username: openidm-admin" \
> --header "X-OpenIDM-Password: openidm-admin" \
> --header "Accept-API-Version: resource=1.0" \
> --request DELETE \
> "http://localhost:8080/openidm/system/azuread/user/9fa6c765-0872-45f6-8714-1dcd1ed94859"
> {
>   "_id": "9fa6c765-0872-45f6-8714-1dcd1ed94859",
>   "surname": "Carter",
>   "displayName": "Steve Carter",
>   "memberOf": [],
>   "onPremisesExtensionAttributes": {
>     "extensionAttribute14": null,
>     ...
>   },
>   "userType": "Member",
>   "identities": [
>     {
>       "signInType": "userPrincipalName",
>       "issuerAssignedId": "00654321@forgedemo.onmicrosoft.com",
>       "issuer": "forgedemo.onmicrosoft.com"
>     }
>   ],
>   "businessPhones": [],
>   "createdDateTime": "2020-12-18T13:23:58Z",
>   "accountEnabled": true,
>   "userPrincipalName": "00654321@forgedemo.onmicrosoft.com",
>   "proxyAddresses": [],
>   "imAddresses": [],
>   "mailNickname": "00654321",
>   "givenName": "Steve",
>   "__NAME__": "00654321@forgedemo.onmicrosoft.com"
> }
> ```

## Manage user licenses

The MS Graph API connector lets you list the available licenses in your Azure data source, and manage those licenses for specific users:

> **Collapse: List Available Licenses in Azure**
>
> This command lists the values of the read-only `subscribedSku` object. For more information about this object class, see the corresponding [Microsoft documentation](https://docs.microsoft.com/en-us/graph/api/resources/subscribedsku?view=graph-rest-1.0):
>
> ```
> curl \
> --header "X-OpenIDM-Username: openidm-admin" \
> --header "X-OpenIDM-Password: openidm-admin" \
> --header "Accept-API-Version: resource=1.0" \
> --request GET \
> "http://localhost:8080/openidm/system/azuread/subscribedSku?_queryFilter=true"
> {
>   "result": [
>     {
>       "_id": "5ee8xxxx-xxxx-xxxx-xxxx-76dc2c2c30bc_f245ecc8-xxxx-xxxx-xxxx-xxxx114de5f3",
>       "prepaidUnits": {
>         "warning": 0,
>         "enabled": 1,
>         "suspended": 0
>       },
>       "skuId": "f245ecc8-xxxx-xxxx-xxxx-xxxx114de5f3",
>       "skuPartNumber": "O365_BUSINESS_PREMIUM",
>       "capabilityStatus": "Enabled",
>       "appliesTo": "User",
>       "consumedUnits": 1,
>       "__NAME__": "O365_BUSINESS_PREMIUM",
>       "servicePlans": [
>         {
>           "servicePlanName": "RMS_S_BASIC",
>           "provisioningStatus": "PendingProvisioning",
>           "appliesTo": "Company",
>           "servicePlanId": "31cxxxxxxxxxxxxxxxxxxxxxxxxxxx122"
>         },
>         {
>           "servicePlanName": "POWER_VIRTUAL_AGENTS_O365_P2",
>           "provisioningStatus": "PendingProvisioning",
>           "appliesTo": "User",
>           "servicePlanId": "041xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxaee"
>         },
>         {
>           "servicePlanName": "CDS_O365_P2",
>           "provisioningStatus": "PendingProvisioning",
>           "appliesTo": "User",
>           "servicePlanId": "95bxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx95a"
>         },
>         ...
>       ]
>     }
>   ],
>   ...
> }
> ```

> **Collapse: List a User's Licenses**
>
> Each user object can include a read-only `licenses` property that contains an array of objects (maps).
>
> This command lists a specific user's licenses:
>
> ```
> curl \
> --header "X-OpenIDM-Username: openidm-admin" \
> --header "X-OpenIDM-Password: openidm-admin" \
> --header "Accept-API-Version: resource=1.0" \
> --request GET \
> "http://localhost:8080/openidm/system/azuread/user/c48be8cc-5846-4059-95e8-a7acbf6aec31?_fields=licenses"
> {
>     "_id": "c48be8cc-5846-4059-95e8-a7acbf6aec31",
>     "licenses": [
>         {
>             "skuPartNumber": "O365_BUSINESS_PREMIUM",
>             "servicePlans": [
>                 {
>                     "servicePlanName": "RMS_S_BASIC",
>                     "provisioningStatus": "PendingProvisioning",
>                     "appliesTo": "Company",
>                     "servicePlanId": "31cxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx122"
>                 },
>                 {
>                     "servicePlanName": "POWER_VIRTUAL_AGENTS_O365_P2",
>                     "provisioningStatus": "PendingProvisioning",
>                     "appliesTo": "Company",
>                     "servicePlanId": "041xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxaee"
>                 },
>                 {
>                     "servicePlanName": "CDS_O365_P2",
>                     "provisioningStatus": "PendingProvisioning",
>                     "appliesTo": "Company",
>                     "servicePlanId": "95bxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx95a"
>                 },
>                 ...
>             ],
>             "id": "c8noxxxxsEqoxxxxLCwwxxxxRfKvxxxxth8nxxxx5fM",
>             "skuId": "f24xxxxx-xxxx-xxxx-xxxx-xxxxxxxxx5f3"
>         }
>     ]
> }
> ```

> **Collapse: Add and Remove a User's Licenses**
>
> You cannot manipulate a user's `licenses` property directly, because it is read-only. To add or remove licenses for a user, set the `addLicenses` or `removeLicenses` properties when you create or update the user.
>
> |   |                                                                                                                                                                  |
> | - | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
> |   | The connector does not currently support PATCH `add` or PATCH `remove` operations. PATCH `replace` is supported because it is the equivalent of a PUT operation. |
>
> This command updates an existing user entry to add a license with the \`skuId`` `f24xxxxx-xxxx-xxxx-xxxx-xxxxxxxxx5f3 ``:
>
> ```
> curl \
> --header "X-OpenIDM-Username: openidm-admin" \
> --header "X-OpenIDM-Password: openidm-admin" \
> --header "Accept-API-Version: resource=1.0" \
> --header "Content-Type: application/json" \
> --header "If-None-Match: *" \
> --request PUT \
> --data '{
>   "addLicenses": [
>     {
>       "skuId": "f24xxxxx-xxxx-xxxx-xxxx-xxxxxxxxx5f3"
>     }
>   ]
> }' \
> "http://localhost:8080/openidm/system/azuread/user/c48be8cc-5846-4059-95e8-a7acbf6aec31"
> ```
>
> This command updates the user entry to remove the license with \`skuId`` `f24xxxxx-xxxx-xxxx-xxxx-xxxxxxxxx5f3 ``:
>
> ```
> curl \
> --header "X-OpenIDM-Username: openidm-admin" \
> --header "X-OpenIDM-Password: openidm-admin" \
> --header "Accept-API-Version: resource=1.0" \
> --header "Content-Type: application/json" \
> --header "If-Match: *" \
> --request PUT \
> --data '{
>   "removeLicenses": "f24xxxxx-xxxx-xxxx-xxxx-xxxxxxxxx5f3"
> }' \
> "http://localhost:8080/openidm/system/azuread/user/c48be8cc-5846-4059-95e8-a7acbf6aec31"
> ```

## Synchronize accounts between IDM and Azure

To use the MS Graph API connector to synchronize accounts between IDM and Azure, set up a [mapping](../synchronization-guide/mappings.html) between the two data stores.

You can use the sample configuration file at `/path/to/openidm/samples/sync-with-azuread/conf/sync.json` as a starting point.

## OpenICF Interfaces Implemented by the MSGraphAPI Connector

The MSGraphAPI Connector implements the following OpenICF interfaces. For additional details, see [OpenICF interfaces](interfaces.html):

* Authenticate

  Provides simple authentication with two parameters, presumed to be a user name and password.

* Create

  Creates an object and its `uid`.

* Delete

  Deletes an object, referenced by its `uid`.

* Schema

  Describes the object types, operations, and options that the connector supports.

* Script on Connector

  Enables an application to run a script in the context of the connector.

  Any script that runs on the connector has the following characteristics:

  * The script runs in the same execution environment as the connector and has access to all the classes to which the connector has access.

  * The script has access to a `connector` variable that is equivalent to an initialized instance of the connector. At a minimum, the script can access the connector configuration.

  * The script has access to any script arguments passed in by the application.

* Search

  Searches the target resource for all objects that match the specified object class and filter.

* Sync

  Polls the target resource for synchronization events, that is, native changes to objects on the target resource.

* Test

  Tests the connector configuration.

  Testing a configuration checks all elements of the environment that are referred to by the configuration are available. For example, the connector might make a physical connection to a host that is specified in the configuration to verify that it exists and that the credentials that are specified in the configuration are valid.

  This operation might need to connect to a resource, and, as such, might take some time. Do not invoke this operation too often, such as before every provisioning operation. The test operation is not intended to check that the connector is alive (that is, that its physical connection to the resource has not timed out).

  You can invoke the test operation before a connector configuration has been validated.

* Update

  Updates (modifies or replaces) objects on a target resource.

## MSGraphAPI Connector Configuration

The MSGraphAPI Connector has the following configurable properties:

### Basic Configuration Properties

| Property                                                                                                              | Type            | Default | Encrypted(1)             | Required(2)               |
| --------------------------------------------------------------------------------------------------------------------- | --------------- | ------- | ------------------------ | ------------------------- |
| `tenant`                                                                                                              | `String`        | `null`  |                          | [icon: check, set=fas]Yes |
| The Azure AD tenant name or id                                                                                        |                 |         |                          |                           |
| `clientId`                                                                                                            | `String`        | `null`  |                          | [icon: check, set=fas]Yes |
| The clientID used by the connector during the OAuth flow                                                              |                 |         |                          |                           |
| `clientSecret`                                                                                                        | `GuardedString` | `null`  | [icon: lock, set=fas]Yes | [icon: times, set=fas]No  |
| The client secret used by the connector during the OAuth flow                                                         |                 |         |                          |                           |
| `httpProxyHost`                                                                                                       | `String`        | `null`  |                          | [icon: times, set=fas]No  |
| The Http proxy host                                                                                                   |                 |         |                          |                           |
| `httpProxyPort`                                                                                                       | `Integer`       | `null`  |                          | [icon: times, set=fas]No  |
| The Http proxy port                                                                                                   |                 |         |                          |                           |
| `httpProxyUsername`                                                                                                   | `String`        | `null`  |                          | [icon: times, set=fas]No  |
| The Http proxy user name                                                                                              |                 |         |                          |                           |
| `httpProxyPassword`                                                                                                   | `GuardedString` | `null`  | [icon: lock, set=fas]Yes | [icon: times, set=fas]No  |
| The Http proxy user password                                                                                          |                 |         |                          |                           |
| `performHardDelete`                                                                                                   | `boolean`       | `false` |                          | [icon: times, set=fas]No  |
| If set to true, the Azure object will be deleted permanently on delete operation.                                     |                 |         |                          |                           |
| `readRateLimit`                                                                                                       | `String`        | `null`  |                          | [icon: times, set=fas]No  |
| Define throttling for read operations either per seconds ("30/sec") or per minute ("100/min").                        |                 |         |                          |                           |
| `writeRateLimit`                                                                                                      | `String`        | `null`  |                          | [icon: times, set=fas]No  |
| Define throttling for write operations (create/update/delete) either per second ("30/sec") or per minute ("100/min"). |                 |         |                          |                           |

(1) Whether the property value is considered confidential, and is therefore encrypted in IDM.

(2) A list of operations in this column indicates that the property is required for those operations.
