通过 Graph 为资源创建 OAuth2PermissionGrant

Create OAuth2PermissionGrant for Resources via Graph

我的方案是通过 AAD Graph 创建应用程序和 spn。这相当容易(通过基于浏览器的同意重定向),我现在想做的是立即同意 spn(就像您可以在门户中做的那样)。代码本身很简单:

var g = new OAuth2PermissionGrant();
g.ClientId = thePrincipal.ObjectId;
g.ConsentType = "AllPrincipals";
g.PrincipalId = null;
g.ResourceId = ##resourceId##;
g.ExpiryTime = DateTime.Now.AddYears(10);
g.Scope = "User.Read";
await client.Oauth2PermissionGrants.AddOAuth2PermissionGrantAsync(g);

现在我没弄清楚的部分是##resourceId##。这应该是 resourceId - 在代码示例中,它应该是 Windows Azure Active Directory。如何获取以下所需资源访问权限 (00000002-0000-0000-c000-000000000000) 的 resourceId:

RequiredResourceAccess =
    new [] {
        new RequiredResourceAccess() {
                ResourceAppId = "00000002-0000-0000-c000-000000000000",
                    ResourceAccess = new [] {
                        new ResourceAccess() {
                            Id = new Guid("311a71cc-e848-46a1-bdf8-97ff7156d8e6"), // sign in and read profile (delegated perm)
                                Type = "Scope"
                        },

查找 ResourceAppId -> resourceId (app to spn) 是我所缺少的。例如 AAD、Graph、manage.office.com 等

根据 documentation for the OAuth2PermissionGrant entityOAuth2PermissionGrantresourceId 字段是 objectId 资源的 ServicePrincipal 对象:

Specifies the objectId of the resource service principal to which access has been granted.

因此,从您在其中创建 OAuth2PemrissionGrant 的租户,您需要检索与资源应用程序对应的 ServicePrincipal 对象你想授予该对象的权限,并从该对象中读取 objectId 属性.

如果您有资源应用程序的 AppId,您可以通过以下方式检索相应的 ServicePrincipal 对象(如果存在):

GET https://graph.windows.net/{tenant}/servicePrincipals
        ?$filter=appId eq '{app-id-guid}'
        &api-version=1.6

使用 Microsoft.Azure.ActiveDirectory.GraphClient(我认为这是您在代码中使用的),您可以使用:

graphClient.ServicePrincipals.Where(sp => sp.AppId == "{app-id-guid}")

如果您必须识别资源应用程序的不是 Guid 应用程序 ID,而是一个(有点)友好的标识符 URI(例如“https://graph.microsoft.com”),您可以检索匹配的 ServicePrincipal 对象通过过滤 servicePrincipalNames.

使用 Azure AD Graph:

GET https://graph.windows.net/{tenant}/servicePrincipals
        ?$filter=servicePrincipalNames/any(n:n eq 'https://graph.microsoft.com'))
        &api-version=1.6

与Microsoft.Azure.ActiveDirectory.GraphClient:

graphClient.ServicePrincipals
    .Where(sp => sp.ServicePrincipalNames.Any(n => n == "https://graph.microsoft.com"))