使用 Microsoft Graph API 配置 Microsoft Entra 应用程序代理

Microsoft Entra 应用程序代理 为本地 Web 应用程序提供安全的远程访问和单一登录 (SSO) 。 它允许用户通过外部 URL、“我的应用”门户或其他内部应用程序门户访问其本地应用程序。

本教程介绍如何使用 Microsoft Graph API 配置 Microsoft Entra 应用程序代理。

重要

特定于应用代理的 API 操作目前仅在终结点上 beta 可用。

先决条件

  • 安装连接器并完成应用程序代理 的先决条件 ,以便连接器可以与 Microsoft Entra 服务通信。
  • 使用至少具有云应用程序管理员角色的帐户登录到 API 客户端(例如 Graph 资源管理器 )。
  • 授予自己 Microsoft Graph Directory.ReadWrite.All 委托的权限。
  • 有一个要分配给应用程序的测试用户。

步骤 1:创建自定义应用程序

若要配置应用程序代理,请先创建自定义应用程序,然后在应用程序的 onPremisesPublishing 属性中更新应用代理设置。 在本教程中,将使用应用程序模板在租户中创建自定义应用程序和服务主体的实例。 自定义应用程序的模板 ID 为 8adf8e6e-67b2-4cf2-a259-e3dc5476c621,可以通过运行以下查询来发现: GET https://graph.microsoft.com/v1.0/applicationTemplates?$filter=displayName eq 'Custom'

在响应中,记录服务主体和应用程序对象的 ID ,以及 appId 的值,以供本教程稍后使用。

请求

POST https://graph.microsoft.com/v1.0/applicationTemplates/8adf8e6e-67b2-4cf2-a259-e3dc5476c621/instantiate
Content-type: application/json

{
  "displayName": "Contoso IWA App"
}

响应

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

{
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#microsoft.graph.applicationServicePrincipal",
    "application": {
        "id": "bf21f7e9-9d25-4da2-82ab-7fdd85049f83",
        "appId": "32977d3b-ee0e-4614-9f50-f583a07842d2",
        "applicationTemplateId": "8adf8e6e-67b2-4cf2-a259-e3dc5476c621",
        "createdDateTime": "2024-02-22T16:48:09Z",
        "deletedDateTime": null,
        "displayName": "Contoso IWA App",
        "description": null,
        "groupMembershipClaims": null,
        "identifierUris": [],
        "isFallbackPublicClient": false,
        "signInAudience": "AzureADMyOrg",
        "tags": [],
        "tokenEncryptionKeyId": null,
        "defaultRedirectUri": null,
        "samlMetadataUrl": null,
        "optionalClaims": null,
        "addIns": [],
        "api": {
            "acceptMappedClaims": null,
            "knownClientApplications": [],
            "requestedAccessTokenVersion": null,
            "oauth2PermissionScopes": [
                {
                    "adminConsentDescription": "Allow the application to access Contoso IWA App on behalf of the signed-in user.",
                    "adminConsentDisplayName": "Access Contoso IWA App",
                    "id": "5cda2e1e-d9fd-4f69-b981-48fbc8a16be1",
                    "isEnabled": true,
                    "type": "User",
                    "userConsentDescription": "Allow the application to access Contoso IWA App on your behalf.",
                    "userConsentDisplayName": "Access Contoso IWA App",
                    "value": "user_impersonation"
                }
            ],
            "preAuthorizedApplications": []
        },
        "appRoles": [
            {
                "allowedMemberTypes": [
                    "User"
                ],
                "displayName": "User",
                "id": "18d14569-c3bd-439b-9a66-3a2aee01d14f",
                "isEnabled": true,
                "description": "User",
                "value": null,
                "origin": "Application"
            },
            {
                "allowedMemberTypes": [
                    "User"
                ],
                "displayName": "msiam_access",
                "id": "b9632174-c057-4f7e-951b-be3adc52bfe6",
                "isEnabled": true,
                "description": "msiam_access",
                "value": null,
                "origin": "Application"
            }
        ],
        "info": {
            "logoUrl": null,
            "marketingUrl": null,
            "privacyStatementUrl": null,
            "supportUrl": null,
            "termsOfServiceUrl": null
        },
        "keyCredentials": [],
        "parentalControlSettings": {
            "countriesBlockedForMinors": [],
            "legalAgeGroupRule": "Allow"
        },
        "passwordCredentials": [],
        "publicClient": {
            "redirectUris": []
        },
        "requiredResourceAccess": [],
        "verifiedPublisher": {
            "displayName": null,
            "verifiedPublisherId": null,
            "addedDateTime": null
        },
        "web": {
            "homePageUrl": "https://account.activedirectory.windowsazure.com:444/applications/default.aspx?metadata=customappsso|ISV9.1|primary|z",
            "redirectUris": [],
            "logoutUrl": null
        }
    },
    "servicePrincipal": {
        "id": "a8cac399-cde5-4516-a674-819503c61313",
        "deletedDateTime": null,
        "accountEnabled": true,
        "appId": "32977d3b-ee0e-4614-9f50-f583a07842d2",
        "applicationTemplateId": "8adf8e6e-67b2-4cf2-a259-e3dc5476c621",
        "appDisplayName": "Contoso IWA App",
        "alternativeNames": [],
        "appOwnerOrganizationId": "38d49456-54d4-455d-a8d6-c383c71e0a6d",
        "displayName": "Contoso IWA App",
        "appRoleAssignmentRequired": true,
        "loginUrl": null,
        "logoutUrl": null,
        "homepage": "https://account.activedirectory.windowsazure.com:444/applications/default.aspx?metadata=customappsso|ISV9.1|primary|z",
        "notificationEmailAddresses": [],
        "preferredSingleSignOnMode": null,
        "preferredTokenSigningKeyThumbprint": null,
        "replyUrls": [],
        "servicePrincipalNames": [
            "32977d3b-ee0e-4614-9f50-f583a07842d2"
        ],
        "servicePrincipalType": "Application",
        "tags": [
            "WindowsAzureActiveDirectoryCustomSingleSignOnApplication",
            "WindowsAzureActiveDirectoryIntegratedApp"
        ],
        "tokenEncryptionKeyId": null,
        "samlSingleSignOnSettings": null,
        "addIns": [],
        "appRoles": [
            {
                "allowedMemberTypes": [
                    "User"
                ],
                "displayName": "User",
                "id": "18d14569-c3bd-439b-9a66-3a2aee01d14f",
                "isEnabled": true,
                "description": "User",
                "value": null,
                "origin": "Application"
            },
            {
                "allowedMemberTypes": [
                    "User"
                ],
                "displayName": "msiam_access",
                "id": "b9632174-c057-4f7e-951b-be3adc52bfe6",
                "isEnabled": true,
                "description": "msiam_access",
                "value": null,
                "origin": "Application"
            }
        ],
        "info": {
            "logoUrl": null,
            "marketingUrl": null,
            "privacyStatementUrl": null,
            "supportUrl": null,
            "termsOfServiceUrl": null
        },
        "keyCredentials": [],
        "oauth2PermissionScopes": [
            {
                "adminConsentDescription": "Allow the application to access Contoso IWA App on behalf of the signed-in user.",
                "adminConsentDisplayName": "Access Contoso IWA App",
                "id": "5cda2e1e-d9fd-4f69-b981-48fbc8a16be1",
                "isEnabled": true,
                "type": "User",
                "userConsentDescription": "Allow the application to access Contoso IWA App on your behalf.",
                "userConsentDisplayName": "Access Contoso IWA App",
                "value": "user_impersonation"
            }
        ],
        "passwordCredentials": [],
        "verifiedPublisher": {
            "displayName": null,
            "verifiedPublisherId": null,
            "addedDateTime": null
        }
    }
}

步骤 2:配置应用程序代理

对于在步骤 1 中创建的应用,请配置应用程序的 URI。 假设应用的内部 URL 为 https://contosoiwaapp.com ,外部 URL 的默认域为 https://contosoiwaapp-contoso.msappproxy.net。 将外部 URL 值添加到 identifierUrisWeb>redirectUrisWeb>homePageUrl 属性。

此外,配置 onPremisesPublishing 属性以根据需要设置内部和外部 URL 和其他属性。 此属性仅在 中 beta 可用,在配置 URI 之前无法配置此属性。

步骤 2.1:配置 URI

以下请求使用 identifierUris 属性的 appId 值。 还可以使用与 Microsoft Entra ID 所需的应用程序 ID URI 格式匹配的任何其他标识符。 请求返回 204 No content 响应。

PATCH https://graph.microsoft.com/v1.0/applications/bf21f7e9-9d25-4da2-82ab-7fdd85049f83
Content-type: application/json

{
    "identifierUris": [
        "api://32977d3b-ee0e-4614-9f50-f583a07842d2"
    ],
    "web": {
        "redirectUris": [
            "https://contosoiwaapp-contoso.msappproxy.net"
        ],
        "homePageUrl": "https://contosoiwaapp-contoso.msappproxy.net"
    }
}

步骤 2.2:配置 onPremisesPublishing 属性

请求返回 204 No content 响应。

PATCH https://graph.microsoft.com/beta/applications/bf21f7e9-9d25-4da2-82ab-7fdd85049f83
Content-type: application/json

{
    "onPremisesPublishing": {
        "externalAuthenticationType": "aadPreAuthentication",
        "internalUrl": "https://contosoiwaapp.com",
        "externalUrl": "https://contosoiwaapp-contoso.msappproxy.net",
        "isHttpOnlyCookieEnabled": true,
        "isOnPremPublishingEnabled": true,
        "isPersistentCookieEnabled": true,
        "isSecureCookieEnabled": true,
        "isStateSessionEnabled": true,
        "isTranslateHostHeaderEnabled": true,
        "isTranslateLinksInBodyEnabled": true
    }
}

步骤 3:将连接器组分配给应用程序

步骤 3.1:获取连接器

标识要分配给连接器组的连接器。 记录其 ID

请求

GET https://graph.microsoft.com/beta/onPremisesPublishingProfiles/applicationProxy/connectors

响应

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

{
  "@odata.context": "https://graph.microsoft.com/beta/$metadata#onPremisesPublishingProfiles('applicationProxy')/connectors",
    "@microsoft.graph.tips": "Use $select to choose only the properties your app needs, as this can lead to performance improvements. For example: GET onPremisesPublishingProfiles('<key>')/connectors?$select=externalIp,machineName",
    "value": [
    {
      "id": "d2b1e8e8-8511-49d6-a4ba-323cb083fbb0",
      "machineName": "connectorA.redmond.contoso.com"",
      "externalIp": "131.137.147.164",
      "status": "active"
    },
    {
      "id": "f2cab422-a1c8-4d70-a47e-2cb297a2e051",
      "machineName": "connectorB.contoso.com"",
      "externalIp": "68.0.191.210",
      "status": "active"
    }
  ]
}

步骤 3.2:创建连接器组

为应用程序创建名为 IWA Demo Connector Group 的 connectorGroup。 记录其 ID

请求

POST https://graph.microsoft.com/beta/onPremisesPublishingProfiles/applicationProxy/connectorGroups
Content-type: application/json

{
  "name": "IWA Demo Connector Group"
}

响应

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

{
  "@odata.context": "https://graph.microsoft.com/beta/$metadata#connectorGroups/$entity",
  "id": "3e6f4c35-a04b-4d03-b98a-66fff89b72e6",
  "name": "IWA Demo Connector Group",
  "connectorGroupType": "applicationProxy",
  "region": "eur",
  "isDefault": false
}

步骤 3.3:将连接器分配到 connectorGroup

请求返回 204 No content 响应。

POST https://graph.microsoft.com/beta/onPremisesPublishingProfiles/applicationProxy/connectors/f2cab422-a1c8-4d70-a47e-2cb297a2e051/memberOf/$ref
Content-type: application/json

{
  "@odata.id":"https://graph.microsoft.com/beta/onPremisesPublishingProfiles/applicationProxy/connectorGroups/3e6f4c35-a04b-4d03-b98a-66fff89b72e6"
}

步骤 3.4:将应用程序分配到 connectorGroup

请求返回 204 No content 响应。

PUT https://graph.microsoft.com/beta/applications/bf21f7e9-9d25-4da2-82ab-7fdd85049f83/connectorGroup/$ref
Content-type: application/json

{
  "@odata.id":"https://graph.microsoft.com/beta/onPremisesPublishingProfiles/applicationproxy/connectorGroups/3e6f4c35-a04b-4d03-b98a-66fff89b72e6"
}

步骤 4:配置单一登录 (SSO)

在此步骤中,为应用程序配置 onPremisesPublishing > singleSignOnSettingsonPremisesPublishing > singleSignOnMode 属性。

选项 1:配置基于 IWA 的 SSO

以下请求演示如何为应用程序配置集成 Windows 身份验证 (IWA) 。 请求返回 204 No content 响应。

PATCH https://graph.microsoft.com/beta/applications/bf21f7e9-9d25-4da2-82ab-7fdd85049f83
Content-type: appplication/json

{
  "onPremisesPublishing": {
    "singleSignOnSettings": {
      "kerberosSignOnSettings": {
        "kerberosServicePrincipalName": "HTTP/iwademo.contoso.com",
           "kerberosSignOnMappingAttributeType": "userPrincipalName"
      },
      "singleSignOnMode": "onPremisesKerberos"
    }
  } 
}

选项 2:配置基于标头的 SSO

以下请求演示如何为应用程序配置基于标头的 SSO。 在此模式下, singleSignOnMode 属性的值可以是 aadHeaderBasedpingHeaderBasedoAuthToken。 请求返回 204 No content 响应。

PATCH https://graph.microsoft.com/beta/applications/bf21f7e9-9d25-4da2-82ab-7fdd85049f83
Content-type: appplication/json

{
  "onPremisesPublishing": {
    "singleSignOnSettings": {
      "kerberosSignOnSettings": {},
      "singleSignOnMode": "aadHeaderBased"
    }
  } 
}

步骤 5:将用户分配到应用程序

你想要将用户分配到应用程序。 在步骤 1 中创建的服务主体中,记录 appRoles 属性中定义的默认用户角色的 ID。 此值为 18d14569-c3bd-439b-9a66-3a2aee01d14f

在请求正文中,提供以下值:

  • principalId - 创建的用户帐户的 ID。
  • appRoleId - 从服务主体检索到的默认 User 应用角色的 ID。
  • resourceId - 服务主体的 ID。

请求

POST https://graph.microsoft.com/beta/servicePrincipals/a8cac399-cde5-4516-a674-819503c61313/appRoleAssignments
Content-type: application/json

{
  "principalId": "2fe96d23-5dc6-4f35-8222-0426a8c115c8",
  "principalType": "User",
  "appRoleId":"18d14569-c3bd-439b-9a66-3a2aee01d14f",
  "resourceId":"a8cac399-cde5-4516-a674-819503c61313"
}

响应

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

{
  "@odata.context": "https://graph.microsoft.com/beta/$metadata#appRoleAssignments/$entity",
  "id": "I23pL8ZdNU-CIgQmqMEVyLJ0E6fx0ixEo92az8MnhtU",
  "creationTimestamp": "2020-06-09T00:06:07.5129268Z",
  "appRoleId": "18d14569-c3bd-439b-9a66-3a2aee01d14f",
  "principalDisplayName": "MyTestUser1",
  "principalId": "2fe96d23-5dc6-4f35-8222-0426a8c115c8",
  "principalType": "User",
  "resourceDisplayName": "Contoso IWA App",
  "resourceId": "a8cac399-cde5-4516-a674-819503c61313"
}

步骤 6:测试对应用程序的访问

通过访问浏览器上为应用配置的 externalUrl 来测试应用程序,然后使用测试用户登录。 你应该能够登录到应用并访问该应用程序。

第 7 步:清理资源

在此步骤中,删除已创建且不再需要的资源。

删除用户账户

请求返回 204 No content 响应。

DELETE https://graph.microsoft.com/v1.0/users/4628e7df-dff3-407c-a08f-75f08c0806dc

删除应用程序

删除应用程序时,租户中的服务主体也会被删除。 此请求返回 204 No content 响应。

DELETE https://graph.microsoft.com/v1.0/applications/bf21f7e9-9d25-4da2-82ab-7fdd85049f83

删除连接器组

请求返回 204 No content 响应。

DELETE https://graph.microsoft.com/beta/onPremisesPublishingProfiles/applicationProxy/connectorGroups/3e6f4c35-a04b-4d03-b98a-66fff89b72e6