尝试从 Azure 虚拟机访问时,Azure isMemberOf api 出现 "Insufficient privileges to complete the operation." 错误
Azure isMemberOf api gives "Insufficient privileges to complete the operation." error when trying to access from Azure Virtual Machine
所以我的要求是 Azure 机器上的应用程序 运行 检查登录的特定 Azure 用户是否属于指定的 Azure 组。
我已为所述虚拟机启用托管服务标识。
MSI
我通过调用元数据服务 运行 在本地获取 VM 的令牌,使用以下命令获取 VM 上的图形资源:
curl 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fgraph.windows.net' -H Metadata:true
获得令牌后,我使用新获得的令牌向 isMemberOf 的图表 API 发出 POST 请求:
curl -i -H "Authorization: Bearer <token-value>" -H "Content-Type: application/json" --data '{"groupId":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","memberId":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}' https://graph.windows.net/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/isMemberOf?api-version=1.6
我收到以下回复
{"odata.error":{"code":"Authorization_RequestDenied","message":{"lang":"en","value":"Insufficient privileges to complete the operation."}}}
我已将 VM 所属的资源组分配给 IAM 作为资源的所有者
我是不是遗漏了一些我应该配置的东西,或者我在这里做错了什么?
您正在调用 Azure AD Graph API,而不是 ARM API。
IAM blade 仅授予 ARM API.
的访问权限
您需要手动为服务主体分配必要的权限。
我前阵子写了一篇关于这个的文章:Calling your APIs with Azure AD Managed Service Identity using application permissions。
您将需要:
- 你的 MSI 服务主体 object id(你可以在我的文章中看到如何找到它)
- 目标服务主体 object id(在本例中为 Azure AD Graph API)
- 您要分配的应用程序权限的 ID(您可以使用例如 https://graphexplorer.azurewebsites.net 找到这些,它们在服务主体的 appRoles 下)
获得这些后,您就可以 运行 这个 PowerShell cmdlet(使用 AAD v2 cmdlet):
Connect-AzureAD
New-AzureADServiceAppRoleAssignment -ObjectId msi-sp-id -Id app-permission-id -PrincipalId msi-sp-id -ResourceId aad-graph-sp-id
然后一切都应该工作。
所以我仔细研究了一下,发现微软更喜欢我们开发人员使用 Microsoft Graph 而不是 Azure AD Graph
Microsoft Graph vs Azure AD Graph
我在 Microsoft Graph API 中找到了类似的调用来获取成员信息 User list member of call
此调用需要以下 scope:
Directory.Read.All
Directory.ReadWrite.All
这些是我遵循的步骤:
- 应用程序需要获取令牌才能进行 Microsoft 图形 API 调用。
POST https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/令牌
HEADER
Content-type: application/x-www-form-urlencoded
BODY:
client_id=&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=&grant_type=client_credentials
响应:
{
"token_type": "Bearer",
"expires_in": 3600,
"ext_expires_in": 0,
"access_token": "<token-value>"
}
客户端密码在应用程序注册时生成。
- 应用程序将调用 Microsoft Graph API 来获取
POST https://graph.microsoft.com/v1.0/users/{user-object-id}/checkMemberGroups
HEADERS:授权:不记名{token-value}
Content-Type: application/json
BODY:
{
"groupIds":["xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"]
}
响应:
200 OK - 如果用户属于该组
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(Edm.String)",
"value": [
"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
]
}
404 未找到 - 如果用户不存在
{
"error": {
"code": "Request_ResourceNotFound",
"message": "Resource 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' does not exist or one of its queried reference-property objects are not present.",
"innerError": {
"request-id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"date": "2018-05-23T02:54:47"
}
}
}
这将有助于应用程序识别 Azure 用户是否属于分配的组。
所以我的要求是 Azure 机器上的应用程序 运行 检查登录的特定 Azure 用户是否属于指定的 Azure 组。
我已为所述虚拟机启用托管服务标识。 MSI
我通过调用元数据服务 运行 在本地获取 VM 的令牌,使用以下命令获取 VM 上的图形资源:
curl 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fgraph.windows.net' -H Metadata:true
获得令牌后,我使用新获得的令牌向 isMemberOf 的图表 API 发出 POST 请求:
curl -i -H "Authorization: Bearer <token-value>" -H "Content-Type: application/json" --data '{"groupId":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","memberId":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}' https://graph.windows.net/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/isMemberOf?api-version=1.6
我收到以下回复
{"odata.error":{"code":"Authorization_RequestDenied","message":{"lang":"en","value":"Insufficient privileges to complete the operation."}}}
我已将 VM 所属的资源组分配给 IAM 作为资源的所有者
我是不是遗漏了一些我应该配置的东西,或者我在这里做错了什么?
您正在调用 Azure AD Graph API,而不是 ARM API。 IAM blade 仅授予 ARM API.
的访问权限您需要手动为服务主体分配必要的权限。
我前阵子写了一篇关于这个的文章:Calling your APIs with Azure AD Managed Service Identity using application permissions。
您将需要:
- 你的 MSI 服务主体 object id(你可以在我的文章中看到如何找到它)
- 目标服务主体 object id(在本例中为 Azure AD Graph API)
- 您要分配的应用程序权限的 ID(您可以使用例如 https://graphexplorer.azurewebsites.net 找到这些,它们在服务主体的 appRoles 下)
获得这些后,您就可以 运行 这个 PowerShell cmdlet(使用 AAD v2 cmdlet):
Connect-AzureAD
New-AzureADServiceAppRoleAssignment -ObjectId msi-sp-id -Id app-permission-id -PrincipalId msi-sp-id -ResourceId aad-graph-sp-id
然后一切都应该工作。
所以我仔细研究了一下,发现微软更喜欢我们开发人员使用 Microsoft Graph 而不是 Azure AD Graph Microsoft Graph vs Azure AD Graph
我在 Microsoft Graph API 中找到了类似的调用来获取成员信息 User list member of call 此调用需要以下 scope:
Directory.Read.All
Directory.ReadWrite.All
这些是我遵循的步骤:
- 应用程序需要获取令牌才能进行 Microsoft 图形 API 调用。
POST https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/令牌
HEADER Content-type: application/x-www-form-urlencoded
BODY: client_id=&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=&grant_type=client_credentials
响应:
{
"token_type": "Bearer",
"expires_in": 3600,
"ext_expires_in": 0,
"access_token": "<token-value>"
}
客户端密码在应用程序注册时生成。
- 应用程序将调用 Microsoft Graph API 来获取
POST https://graph.microsoft.com/v1.0/users/{user-object-id}/checkMemberGroups
HEADERS:授权:不记名{token-value} Content-Type: application/json
BODY:
{
"groupIds":["xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"]
}
响应:
200 OK - 如果用户属于该组
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(Edm.String)",
"value": [
"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
]
}
404 未找到 - 如果用户不存在
{
"error": {
"code": "Request_ResourceNotFound",
"message": "Resource 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' does not exist or one of its queried reference-property objects are not present.",
"innerError": {
"request-id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"date": "2018-05-23T02:54:47"
}
}
}
这将有助于应用程序识别 Azure 用户是否属于分配的组。