使用 Microsoft Graph Api 配置设置Configure provisioning using Microsoft Graph APIs

Azure 门户是一次为单个应用程序配置设置的一种简便方法。The Azure portal is a convenient way to configure provisioning for individual apps one at a time. 但是,如果您要创建应用程序的多个实例(甚至上百个实例),则使用 Microsoft Graph Api 自动创建和配置应用程序会更加容易。But if you're creating several—or even hundreds—of instances of an application, it can be easier to automate app creation and configuration with the Microsoft Graph APIs. 本文概述如何通过 Api 自动化预配配置。This article outlines how to automate provisioning configuration through APIs. 此方法通常用于应用程序(如Amazon Web 服务)。This method is commonly used for applications like Amazon Web Services.

使用 Microsoft Graph Api 以自动化预配配置的步骤概述Overview of steps for using Microsoft Graph APIs to automate provisioning configuration

步骤Step 详细信息Details
步骤1。创建库应用程序Step 1. Create the gallery application 登录到 API 客户端Sign-in to the API client
检索库应用程序模板Retrieve the gallery application template
创建库应用程序Create the gallery application
步骤2。创建基于模板的设置作业Step 2. Create provisioning job based on template 检索预配连接器的模板Retrieve the template for the provisioning connector
创建设置作业Create the provisioning job
步骤3。授权访问Step 3. Authorize access 测试与应用程序的连接Test the connection to the application
保存凭据Save the credentials
步骤4。启动预配作业Step 4. Start provisioning job 启动作业Start the job
步骤5。监视器预配Step 5. Monitor provisioning 检查设置作业的状态Check the status of the provisioning job
检索设置日志Retrieve the provisioning logs
  1. 启动 Microsoft Graph 浏览器Start Microsoft Graph Explorer.

  2. 选择 "使用 Microsoft 登录" 按钮,并使用 Azure AD 全局管理员或应用程序管理员凭据登录。Select the "Sign-In with Microsoft" button and sign in using Azure AD global administrator or App Admin credentials.

    图形登录

  3. 成功登录后,将在左侧窗格中看到用户帐户详细信息。Upon successful sign-in, you'll see the user account details in the left-hand pane.

Azure AD 应用程序库中的每个应用程序都有一个应用程序模板,用于描述该应用程序的元数据。Applications in the Azure AD application gallery each have an application template that describes the metadata for that application. 使用此模板,可以在租户中创建应用程序和服务主体的实例以进行管理。Using this template, you can create an instance of the application and service principal in your tenant for management.

请求Request

GET https://graph.microsoft.com/beta/applicationTemplates

响应Response

HTTP/1.1 200 OK
Content-type: application/json

{
  "value": [
  {
    "id": "8b1025e4-1dd2-430b-a150-2ef79cd700f5",
        "displayName": "Amazon Web Services (AWS)",
        "homePageUrl": "http://aws.amazon.com/",
        "supportedSingleSignOnModes": [
             "password",
             "saml",
             "external"
         ],
         "supportedProvisioningTypes": [
             "sync"
         ],
         "logoUrl": "https://az495088.vo.msecnd.net/app-logo/aws_215.png",
         "categories": [
             "developerServices"
         ],
         "publisher": "Amazon",
         "description": null    
  
}

在最后一步中使用为应用程序检索的模板 ID,以在租户中创建应用程序和服务主体的实例Use the template ID retrieved for your application in the last step to create an instance of the application and service principal in your tenant.

请求Request

POST https://graph.microsoft.com/beta/applicationTemplates/{id}/instantiate
Content-type: application/json

{
  "displayName": "AWS Contoso"
}

响应Response

HTTP/1.1 201 OK
Content-type: application/json


{
    "application": {
        "objectId": "cbc071a6-0fa5-4859-8g55-e983ef63df63",
        "appId": "92653dd4-aa3a-3323-80cf-e8cfefcc8d5d",
        "applicationTemplateId": "8b1025e4-1dd2-430b-a150-2ef79cd700f5",
        "displayName": "AWS Contoso",
        "homepage": "https://signin.aws.amazon.com/saml?metadata=aws|ISV9.1|primary|z",
        "replyUrls": [
            "https://signin.aws.amazon.com/saml"
        ],
        "logoutUrl": null,
        "samlMetadataUrl": null,
    },
    "servicePrincipal": {
        "objectId": "f47a6776-bca7-4f2e-bc6c-eec59d058e3e",
        "appDisplayName": "AWS Contoso",
        "applicationTemplateId": "8b1025e4-1dd2-430b-a150-2ef79cd700f5",
        "appRoleAssignmentRequired": true,
        "displayName": "My custom name",
        "homepage": "https://signin.aws.amazon.com/saml?metadata=aws|ISV9.1|primary|z",
        "replyUrls": [
            "https://signin.aws.amazon.com/saml"
        ],
        "servicePrincipalNames": [
            "93653dd4-aa3a-4323-80cf-e8cfefcc8d7d"
        ],
        "tags": [
            "WindowsAzureActiveDirectoryIntegratedApp"
        ],
    }
}

步骤2:基于模板创建设置作业Step 2: Create the provisioning job based on the template

检索预配连接器的模板Retrieve the template for the provisioning connector

启用了预配的库中的应用程序具有简化配置的模板。Applications in the gallery that are enabled for provisioning have templates to streamline configuration. 使用下面的请求检索设置配置的模板Use the request below to retrieve the template for the provisioning configuration. 请注意,你将需要提供 ID。Note that you will need to provide the ID. ID 引用前面的资源,在此示例中为 servicePrincipal 资源。The ID refers to the preceding resource, which in this case is the servicePrincipal resource.

请求Request

GET https://graph.microsoft.com/beta/servicePrincipals/{id}/synchronization/templates

响应Response

HTTP/1.1 200 OK

{
    "value": [
        {
            "id": "aws",
            "factoryTag": "aws",
            "schema": {
                    "directories": [],
                    "synchronizationRules": []
                    }
        }
    ]
}

创建设置作业Create the provisioning job

若要启用预配,首先需要创建一个作业To enable provisioning, you'll first need to create a job. 使用以下请求创建设置作业。Use the following request to create a provisioning job. 在指定要用于作业的模板时,请使用上一步中的 templateId。Use the templateId from the previous step when specifying the template to be used for the job.

请求Request

POST https://graph.microsoft.com/beta/servicePrincipals/{id}/synchronization/jobs
Content-type: application/json

{ 
    "templateId": "aws"
}

响应Response

HTTP/1.1 200 OK
Content-type: application/json

{
    "id": "{jobId}",
    "templateId": "aws",
    "schedule": {
        "expiration": null,
        "interval": "P10675199DT2H48M5.4775807S",
        "state": "Disabled"
    },
    "status": {
        "countSuccessiveCompleteFailures": 0,
        "escrowsPruned": false,
        "synchronizedEntryCountByType": [],
        "code": "NotConfigured",
        "lastExecution": null,
        "lastSuccessfulExecution": null,
        "lastSuccessfulExecutionWithExports": null,
        "steadyStateFirstAchievedTime": "0001-01-01T00:00:00Z",
        "steadyStateLastAchievedTime": "0001-01-01T00:00:00Z",
        "quarantine": null,
        "troubleshootingUrl": null
    }
}

步骤3:授权访问Step 3: Authorize access

测试与应用程序的连接Test the connection to the application

测试与第三方应用程序的连接。Test the connection with the third-party application. 下面的示例针对的是需要客户端密码和机密令牌的应用程序。The following example is for an application that requires a client secret and secret token. 每个应用程序都有其自己的要求。Each application has its own requirements. 应用程序通常使用基址替代客户端密码。Applications often use a base address in place of a client secret. 若要确定您的应用程序需要哪些凭据,请转到应用程序的 "设置配置" 页,并在开发人员模式下单击 "测试连接"。To determine what credentials your app requires, go to the provisioning configuration page for your application and in developer mode click test connection. 网络流量将显示用于凭据的参数。The network traffic will show the parameters used for credentials. 有关凭据的完整列表,请参阅synchronizationJob: validateCredentialsFor a full list of credentials, see synchronizationJob: validateCredentials.

请求Request

POST https://graph.microsoft.com/beta/servicePrincipals/{id}/synchronization/jobs/{id}/validateCredentials
{ 
    credentials: [ 
        { key: "ClientSecret", value: "xxxxxxxxxxxxxxxxxxxxx" },
        { key: "SecretToken", value: "xxxxxxxxxxxxxxxxxxxxx" }
    ]
}

响应Response

HTTP/1.1 204 No Content

保存凭据Save your credentials

配置设置需要在 Azure AD 和应用程序之间建立信任关系。Configuring provisioning requires establishing a trust between Azure AD and the application. 授权对第三方应用程序的访问。Authorize access to the third-party application. 下面的示例适用于需要客户端密码和机密令牌的应用程序。The following example is for an application that requires a client secret and a secret token. 每个应用程序都有其自己的要求。Each application has its own requirements. 查看API 文档以查看可用选项。Review the API documentation to see the available options.

请求Request

PUT https://graph.microsoft.com/beta/servicePrincipals/{id}/synchronization/secrets 
 
{ 
    value: [ 
        { key: "ClientSecret", value: "xxxxxxxxxxxxxxxxxxxxx" },
        { key: "SecretToken", value: "xxxxxxxxxxxxxxxxxxxxx" }
    ]
}

响应Response

HTTP/1.1 204 No Content

步骤4:启动设置作业Step 4: Start the provisioning job

现在配置了预配作业,请使用以下命令启动作业Now that the provisioning job is configured, use the following command to start the job.

请求Request

POST https://graph.microsoft.com/beta/servicePrincipals/{id}/synchronization/jobs/{jobId}/start

响应Response

HTTP/1.1 204 No Content

步骤5:监视器预配Step 5: Monitor provisioning

监视设置作业状态Monitor the provisioning job status

现在设置作业正在运行,请使用以下命令来跟踪当前设置周期的进度以及截止到目前为止已在目标系统中创建的用户和组的数量的统计信息。Now that the provisioning job is running, use the following command to track the progress of the current provisioning cycle as well as statistics to date such as the number of users and groups that have been created in the target system.

请求Request

GET https://graph.microsoft.com/beta/servicePrincipals/{id}/synchronization/jobs/{jobId}/

响应Response

HTTP/1.1 200 OK
Content-type: application/json
Content-length: 2577

{
    "id": "{jobId}",
    "templateId": "aws",
    "schedule": {
        "expiration": null,
        "interval": "P10675199DT2H48M5.4775807S",
        "state": "Disabled"
    },
    "status": {
        "countSuccessiveCompleteFailures": 0,
        "escrowsPruned": false,
        "synchronizedEntryCountByType": [],
        "code": "Paused",
        "lastExecution": null,
        "lastSuccessfulExecution": null,
        "progress": [],
        "lastSuccessfulExecutionWithExports": null,
        "steadyStateFirstAchievedTime": "0001-01-01T00:00:00Z",
        "steadyStateLastAchievedTime": "0001-01-01T00:00:00Z",
        "quarantine": null,
        "troubleshootingUrl": null
    },
    "synchronizationJobSettings": [
      {
          "name": "QuarantineTooManyDeletesThreshold",
          "value": "500"
      }
    ]
}

使用预配日志监视预配事件Monitor provisioning events using the provisioning logs

除了监视设置作业的状态之外,还可以使用预配日志来查询正在发生的所有事件。In addition to monitoring the status of the provisioning job, you can use the provisioning logs to query for all the events that are occurring. 例如,查询特定用户并确定是否成功设置了这些用户。For example, query for a particular user and determine if they were successfully provisioned.

请求Request

GET https://graph.microsoft.com/beta/auditLogs/provisioning

响应Response

HTTP/1.1 200 OK
Content-type: application/json

{
    "@odata.context": "https://graph.microsoft.com/beta/$metadata#auditLogs/provisioning",
    "value": [
        {
            "id": "gc532ff9-r265-ec76-861e-42e2970a8218",
            "activityDateTime": "2019-06-24T20:53:08Z",
            "tenantId": "7928d5b5-7442-4a97-ne2d-66f9j9972ecn",
            "jobId": "BoxOutDelta.7928d5b574424a97ne2d66f9j9972ecn",
            "cycleId": "44576n58-v14b-70fj-8404-3d22tt46ed93",
            "changeId": "eaad2f8b-e6e3-409b-83bd-e4e2e57177d5",
            "action": "Create",
            "durationInMilliseconds": 2785,
            "sourceSystem": {
                "id": "0404601d-a9c0-4ec7-bbcd-02660120d8c9",
                "displayName": "Azure Active Directory",
                "details": {}
            },
            "targetSystem": {
                "id": "cd22f60b-5f2d-1adg-adb4-76ef31db996b",
                "displayName": "Box",
                "details": {
                    "ApplicationId": "f2764360-e0ec-5676-711e-cd6fc0d4dd61",
                    "ServicePrincipalId": "chc46a42-966b-47d7-9774-576b1c8bd0b8",
                    "ServicePrincipalDisplayName": "Box"
                }
            },
            "initiatedBy": {
                "id": "",
                "displayName": "Azure AD Provisioning Service",
                "initiatorType": "system"
            },
            "sourceIdentity": {
                "id": "5e6c9rae-ab4d-5239-8ad0-174391d110eb",
                "displayName": "Self-service Pilot",
                "identityType": "Group",
                "details": {}
            },
            "targetIdentity": {
                "id": "",
                "displayName": "",
                "identityType": "Group",
                "details": {}
            },
            "statusInfo": {
                "@odata.type": "#microsoft.graph.statusDetails",
                "status": "failure",
                "errorCode": "BoxEntryConflict",
                "reason": "Message: Box returned an error response with the HTTP status code 409.  This response indicates that a user or a group already exisits with the same name. This can be avoided by identifying and removing the conflicting user from Box via the Box administrative user interface, or removing the current user from the scope of provisioning either by removing their assignment to the Box application in Azure Active Directory or adding a scoping filter to exclude the user.",
                "additionalDetails": null,
                "errorCategory": "NonServiceFailure",
                "recommendedAction": null
            },
            "provisioningSteps": [
                {
                    "name": "EntryImportAdd",
                    "provisioningStepType": "import",
                    "status": "success",
                    "description": "Received Group 'Self-service Pilot' change of type (Add) from Azure Active Directory",
                    "details": {}
                },
                {
                    "name": "EntrySynchronizationAdd",
                    "provisioningStepType": "matching",
                    "status": "success",
                    "description": "Group 'Self-service Pilot' will be created in Box (Group is active and assigned in Azure Active Directory, but no matching Group was found in Box)",
                    "details": {}
                },
                {
                    "name": "EntryExportAdd",
                    "provisioningStepType": "export",
                    "status": "failure",
                    "description": "Failed to create Group 'Self-service Pilot' in Box",
                    "details": {
                        "ReportableIdentifier": "Self-service Pilot"
                    }
                }
            ],
            "modifiedProperties": [
                {
                    "displayName": "objectId",
                    "oldValue": null,
                    "newValue": "5e0c9eae-ad3d-4139-5ad0-174391d110eb"
                },
                {
                    "displayName": "displayName",
                    "oldValue": null,
                    "newValue": "Self-service Pilot"
                },
                {
                    "displayName": "mailEnabled",
                    "oldValue": null,
                    "newValue": "False"
                },
                {
                    "displayName": "mailNickname",
                    "oldValue": null,
                    "newValue": "5ce25n9a-4c5f-45c9-8362-ef3da29c66c5"
                },
                {
                    "displayName": "securityEnabled",
                    "oldValue": null,
                    "newValue": "True"
                },
                {
                    "displayName": "Name",
                    "oldValue": null,
                    "newValue": "Self-service Pilot"
                }
            ]
       }
    ]
}

另请参阅See also