我已经在Azure中设置了两个App Services。 “父母”和“孩子”都公开了API端点。
我希望所有子终结点终结点都需要通过托管身份和AAD进行身份验证,并且希望所有父终结点终结点都允许匿名。但是,在Azure中,我想将父应用程序服务设置为具有调用子应用程序服务的权限。因此,只能通过使用父级端点(或者如果您拥有用户帐户的权限直接使用子级)来访问子级端点。
在Azure门户中:
身份验证/授权
身份
访问控制(IAM)
使用上述所有设置:
在不使用客户ID /秘密/密钥/等的情况下,我认为托管身份背后的想法是,鉴于上述所有情况,将所有内容都扔出窗外,父母应该可以给孩子打电话吗?如果是这样,我有什么错误设置吗?
答案 0 :(得分:0)
- 给父母打电话-> GetChild,返回“ 401-您无权查看此目录或页面”
正如我所想的那样,不使用客户端ID /秘密/密钥/等 鉴于身份,托管身份的背后是将所有内容扔到窗外 以上所有,父母应该可以给孩子打电话吗?如果是的话 我设置错了吗?
我在当前设置中注意到两件事。
1。使用托管身份获取令牌以从“父母”调用“子级”服务终结点
受管身份仅向您的应用程序服务提供一个身份(没有管理/维护应用程序秘密或密钥的麻烦)。然后,可以使用此身份获取不同Azure资源的令牌。
但是,使用此身份并获取相关资源的令牌仍然是您的应用程序的责任。在这种情况下,相关资源将是您的“子级” API。我认为这可能是您现在所缺少的部分。
Microsoft文档的相关文档-How to use managed identities for App Service and Azure Functions > Obtaining 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 Key Vault的令牌。对于您的情况,您将https://vault.azure.net
替换为“子”服务的identifierUri。默认情况下,通常通常将其设置为https://<yourappservicename>.azurewebsites.net
,但是您可以通过转到Azure AD应用程序,然后找到相关的应用程序注册>清单来找到它的价值。您还可以将applicationId用于目标应用程序(即“子”)来获取令牌。
如果您不使用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点中的步骤操作,您应该可以从“父母”调用“儿童”服务。
现在,从父级到子级的呼叫正常工作后,您可能希望将对“子级”应用程序服务的访问限制为仅“父级”或一些有效的应用程序。这是实现此目的的两种方法。
这两种方法均在此处的Microsoft文档中进行了说明-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-使用访问控制列表
当“子级” API收到令牌时,它可以对令牌进行解码,并从appid
和iss
声明中提取客户端的应用程序ID。然后,它将应用程序与其维护的访问控制列表(ACL)进行比较。
根据您的要求,API可能只向特定客户端授予全部权限的子集或所有权限。
方法2-使用应用程序权限或角色
配置子API应用程序以公开一组应用程序权限(或角色)。
此方法更具说明性,因为您定义了一个应用程序许可权,该许可权需要分配给可以调用您的child-api
的任何应用程序。
导航到Azure Active Directory>应用程序注册> child-api
应用程序的应用程序注册>清单
使用json这样添加新的应用角色。
"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”的角色,否则可以拒绝带有未授权异常的调用。