使用托管标识在Azure中使用应用程序服务到应用程序服务身份验证 [英] App service to app service auth in Azure using Managed Identity
问题描述
我在Azure中设置了两个应用程序服务。"Parent"和"Child"都公开API终结点。
- 子级具有终结点""Get""。
- 父级具有终结点"Get"和"GetChild"(使用HttpClient在子级上调用"Get")。
在Azure门户中:
Authentication/Authorization
- 我已在两个应用程序服务上启用了‘应用程序服务身份验证’。
- 子项设置为"使用AAD登录"。
- 父级设置为"允许匿名请求"。
- 两者都在"身份验证提供程序"下配置了AAD。
身份
- 将两个应用程序服务设置为‘On’
访问控制(IAM)
- 子角色分配为父级,类型="App Service or Function App",Role="Contributer"
使用以上所有设置:
- 调用Child->Get,需要登录
- 调用Parent->Get,返回200 OK的预期响应
- 调用Parent->GetChild,返回"401-您没有查看此目录或页面的权限"
如果不使用客户端ID/Secrets/Keys/等,因为我认为托管身份背后的想法是将所有这些都抛诸脑后,考虑到以上所有情况,父母是否应该能够调用Child?如果是这样的话,我的设置有什么错误?
推荐答案
- 调用父级->;GetChild,返回&401-您没有查看此目录或页面的权限
没有使用客户端ID/机密/密钥/等,正如我所想的那样 托管身份的背后是将所有这些都抛诸脑后,给定 以上这一切,家长应该可以给孩子打电话吗?如果是这样的话, 我的设置有误吗?
关于当前设置,我注意到两件事。
1.使用托管身份从";父";
调用服务终结点的令牌托管身份仅为您的应用程序服务提供身份(无需管理/维护应用程序机密或密钥)。然后,此标识可用于获取不同Azure资源的令牌。
但使用此身份并获取相关资源的令牌仍是您的App的责任。在这种情况下,相关资源将是您的";Child&qot;API。我认为这可能是您现在缺少的部分。
Microsoft Docs相关文档-How to use managed identities for App Service and Azure Functions > Obtain tokens for Azure resources
using Microsoft.Azure.Services.AppAuthentication;
using Microsoft.Azure.KeyVault;
// ...
var azureServiceTokenProvider = new AzureServiceTokenProvider();
string accessToken = await azureServiceTokenProvider.GetAccessTokenAsync("https://vault.azure.net");
// change this to use identifierUri for your child app service.
// I have used the default value but in case you've used a different value, find it by going to Azure AD applications > your app registration > manifest
string accessToken = await azureServiceTokenProvider.GetAccessTokenAsync("https://<yourchildappservice>.azurewebsites.net");
此C#/.NET示例使用Microsoft.Azure.Services.AppAuthentication
Nuget包并获取Azure密钥库的令牌。在您的案例中,您需要将https://vault.azure.net
替换为您的";Child";服务的标识符URI。默认情况下,它通常设置为https://<yourappservicename>.azurewebsites.net
,但你可以通过转到Azure AD应用程序,然后找到相关的应用程序注册清单来找到它的值。您还可以使用目标应用程序的应用程序ID(即";Child";)来获取令牌。
如果您不使用C#/.NET,上面的同一个Microsoft Docs链接还提供了如何从任何平台使用托管身份和基于REST的调用获取令牌的指导。Using REST Protocol
这里有一篇博客文章,它也很好地介绍了-Call Azure AD protected website using Managed Service Identity (MSI)
2.Azure RBAC角色分配与您可能要使用的Azure AD角色不同
我看到您已从IAM将参与者角色分配给父应用服务的标识。此角色分配适用于Azure RBAC并帮助授予管理资源的权限,但Azure AD角色声明的工作方式不同。
如果您希望为父应用程序分配角色,则可以在子应用程序中选中该角色,然后才允许调用。有一种不同的设置方法。
我首先要指出的是,这种基于角色的设置是针对一些高级场景的,实际上并不是强制性的。按照上述第1点中的步骤操作后,您应该能够从";Parent";调用";子服务。 现在,一旦从Parent到Child的调用起作用,您可能希望将对Child应用程序服务的访问权限限制为仅&p;Parent&q;或几个有效的应用程序。以下是实现这一目标的两种方法。这两种方法都在Microsoft Docs上进行了说明-Microsoft identity platform and the OAuth 2.0 client credentials flow
关联SO帖子和博客
Is there a way to secure an Azure Function that will only be called from a specific Azure Logic App?
https://joonasw.net/view/calling-your-apis-with-aad-msi-using-app-permissions
方法1-使用访问控制列表
当您的";Child";API收到令牌时,它可以对令牌进行解码,并从appid
和iss
声明中提取客户端的应用程序ID。然后将应用程序与其维护的访问控制列表(ACL)进行比较。
根据您的要求,API可能只将部分完全权限或所有权限授予特定客户端。
方法2-使用应用程序权限或角色
配置子API应用程序以公开一组应用程序权限(或角色)。
此方法更具声明性,因为您定义了一个应用程序权限,该权限需要分配给可以调用child-api
的任何应用程序。
导航到您的child-api
应用程序清单的Azure Active Directory应用程序注册
"appRoles": [
{
"allowedMemberTypes": [
"Application"
],
"displayName": "Can invoke my API",
"id": "fc803414-3c61-4ebc-a5e5-cd1675c14bbb",
"isEnabled": true,
"description": "Apps that have this role have the ability to invoke my child API",
"value": "MyAPIValidClient"
}]
将应用权限分配给您的前端应用
New-AzureADServiceAppRoleAssignment -ObjectId <parentApp.ObjectId> -PrincipalId <parentApp.ObjectId> -Id "fc803414-3c61-4ebc-a5e5-cd1675c14bbb" -ResourceId <childApp.ObjectId>
现在,在您的子API收到的auth令牌中,您可以检查角色声明集合是否必须包含名为";MyAPIValidClient";的角色,否则您可以使用未经授权的异常拒绝调用。
这篇关于使用托管标识在Azure中使用应用程序服务到应用程序服务身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!