使用 MS Graph SDK 向客户端应用程序添加应用程序权限 - Java

Adding application permission to an client application using MS Graph SDK - Java

我已经注册了一个名称为“API”的应用程序,为此我在清单中添加了两个 App Role

"appRoles": [
        {
            "allowedMemberTypes": [
                "Application"
            ],
            "description": "Demo Role for application.",
            "displayName": "Demo Role",
            "id": "42ee481e-b4bc-4afa-9499-586bc2a079be",
            "isEnabled": true,
            "lang": null,
            "origin": "Application",
            "value": "demo.role"
        },
        {
            "allowedMemberTypes": [
                "Application"
            ],
            "description": "Test Role for application.",
            "displayName": "Test Role",
            "id": "42ee481e-b4bc-4afa-9499-586bc2a079bd",
            "isEnabled": true,
            "lang": null,
            "origin": "Application",
            "value": "test.role"
        }
    ]

现在我已经注册了另一个名为“客户端应用程序”的应用程序,我想将此应用程序分配到我在应用程序“API”

中定义的两个应用程序角色之上

通过搜索文档,我发现我们分配权限给应用程序服务主体,而不是应用程序对象。

https://docs.microsoft.com/en-us/graph/api/serviceprincipal-post-approleassignedto?view=graph-rest-1.0&tabs=java

这是我在文档中找到的示例代码...

AppRoleAssignment appRoleAssignment = new AppRoleAssignment();
appRoleAssignment.principalId = UUID.fromString("33ad69f9-da99-4bed-acd0-3f24235cb296");
appRoleAssignment.resourceId = UUID.fromString("9028d19c-26a9-4809-8e3f-20ff73e2d75e");
appRoleAssignment.appRoleId = UUID.fromString("ef7437e6-4f94-4a0a-a110-a439eb2aa8f7");

graphClient.servicePrincipals("9028d19c-26a9-4809-8e3f-20ff73e2d75e").appRoleAssignedTo()
    .buildRequest()
    .post(appRoleAssignment);

principalId: 您为其分配应用程序角色的用户、组或客户端 servicePrincipal 的 ID。 -- 我在哪里可以找到 principalId?这是“客户端应用程序”的objectId吗?

resourceId:定义了应用角色的资源servicePrincipal的id。我在哪里可以找到 resourceId? -- 这是定义了应用程序角色的“API”应用程序的对象 ID 吗?

appRoleId: 要分配给用户、组或服务主体的 appRole(在资源服务主体上定义)的 ID。 -- 我找到了应用程序角色 ID——“API”应用程序清单中应用程序角色中提到的 guid。

请协助。

Principal id 是 ObjectId,但不是您在门户中看到的实际对象,而是服务主体的对象 Id,类似地,资源 Id 是资源应用程序的 serviceprincipal 的 objectId。

从下面提供的信息中查看不同之处:

Portal:resourceApp:

App id:51100c0f-xxxx-xxxx-xxxx-xxxxxxxa59, ObjectId:2275ec6c-xxxx-xxxx-xxxx-xxxxxx2b76e

来自 powershell 命令:

$ResourceId= (Get-AzureAdServicePrincipal -Filter "displayName eq 'testapp'").ObjectId

#output :ResourceId: 36929cef-xxxx-xxxx-xxxx-xxxx989dac7

Portal:client app:

App id:329cd48e-xxxx-xxxx-xxxx-xxxxxxxx2b88, objectId:9d5e7540-xxxx-xxxx-xxxx-xxxxxxxxx9e1

$principalId=(Get-AzureAdServicePrincipal -Filter "displayName eq 'client app'").ObjectId

#输出:主体 ID:85a53d22-xxxx-xxxx-xxxx-xxxxx300b2


在应用程序角色分配中,resourceId 是资源应用程序(在您的情况下为 API 应用程序)的 servicePrincipal 的 ID。要通过 graph api 为资源应用程序和客户端 app:see 查找您知道其 appId 的服务主体的 ID,请执行以下请求

GET https://graph.microsoft.com/v1.0/servicePrincipals?$filter=appId eq '{app-id}'

(或)

GET https://graph.microsoft.com/v1.0/servicePrincipals/<App id>
 

 GET https://graph.microsoft.com/beta/serviceprincipals?$filter=startswith(displayName, 'Application-Name')

响应将包含 servicePrincipal 对象的 ID 属性,您可以在创建应用角色分配时使用它。

参考: graph/api/serviceprincipal

当您 create/register 来自门户 UI 的应用程序时,会自动为您创建一个服务主体,但是当您使用 API 调用创建应用程序时,情况并非如此。

当您使用 API 注册应用程序时,您将必须为该应用程序显式创建服务主体...

要创建服务主体,您需要图形客户端和您创建的应用程序的对象 ID(请注意对象 ID 和应用程序客户端 ID 是不同的)- 您可以从门户 UI 查看您的对象 ID。

        Application application = graphClient.applications(objId)
                .buildRequest()
                .get();
        
        ServicePrincipal servicePrincipal = new ServicePrincipal();
        servicePrincipal.appId = application.appId;

        graphClient.servicePrincipals()
            .buildRequest()
            .post(servicePrincipal);

现在您已经为您的应用程序创建了一个服务主体...接下来是找到您可以这样做的 ID...

        ServicePrincipalCollectionPage servicePrincipals = graphClient.servicePrincipals()
                .buildRequest()
                .get();
        
        List<ServicePrincipal> list = servicePrincipals.getCurrentPage();

浏览列表并根据显示名称选择您的应用程序,您也可以找到 ID。

ServicePrincipal.Id --> 这就是你需要的...

并根据您的需要...

principalId 是您创建的客户端应用程序 - 因此您需要该应用程序的 servicePrincipal.Id。

resourceId 是您定义应用程序的应用程序 - 因此您需要该应用程序的 servicePrincipal.Id。