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

Posted

技术标签:

【中文标题】使用 MS Graph SDK - Java 向客户端应用程序添加应用程序权限【英文标题】:Adding application permission to an client application using MS Graph SDK - Java 【发布时间】:2021-12-27 08:29:33 【问题描述】:

我已经注册了一个名为“API”的应用程序,为此我在 Manifest 中添加了两个应用程序角色

"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。我在哪里可以找到资源 ID? -- 这是定义了应用角色的“API”应用程序的对象ID吗?

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

请帮忙。

【问题讨论】:

【参考方案1】:

当您从门户 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。

【讨论】:

这正是我要问的......【参考方案2】:

主体 ID 是 ObjectId,但不是您在门户中看到的实际 ID,而是服务主体的对象 ID,同样,资源 ID 是资源应用的 serviceprincipal 的 objectId。

查看下面提供的信息的区别:

门户:resourceApp:

应用 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

门户:客户端应用程序:

应用 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 为资源应用程序和客户端应用程序查找您知道其 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

【讨论】:

感谢您的解释...很有帮助。 我很高兴它有帮助:) 您可以接受它作为答案(单击答案旁边的复选标记将其从灰色切换为已填充)。这对其他社区成员可能是有益的。谢谢。

以上是关于使用 MS Graph SDK - Java 向客户端应用程序添加应用程序权限的主要内容,如果未能解决你的问题,请参考以下文章

MS Graph Powershell SDK - 无法处理参数“BodyParameter”的参数转换

为啥我使用 Azure Graph SDK 收到 400 Bad Request?

使用证明 jwt 使用 Graph 客户端 Sdk 添加服务主体

尝试使用 Graph API (Facebook C# SDK) 更新 Facebook 事件

MS Graph API:microsoft.graph.createLink 未创建匿名视图链接

MSGraphMailbag - 使用 Microsoft Graph SDK 的 LargeFileUploadTask 上传大文件