powershell - 在 Azure 函数中使用托管标识访问 Graph API
问题描述
简短版本
我想避免使用用户名/密码/秘密/key valults/等。通过在 Azure Functions 上运行的 PowerShell 脚本中使用托管标识。
它似乎失败了:
Import-Module Microsoft.Graph.Authentication
Connect-MgGraph -Scopes 'Reports.Read.All', 'Group.ReadWrite.All'
背景
我已经从一个安全的应用程序作为应用程序访问 Microsoft Graph,并且设置似乎很好。
我在 Azure 函数上启用了系统标识并授予 Microsoft Graph 权限,当我检查企业应用程序时,权限似乎很好。我在 GraphAggregatorService (00000003-0000-0000-c000-000000000000) 中找到了托管标识。
当我以我的身份从 VScode 调试时,脚本运行良好。
当 Azure Functions 运行代码时,会发生以下情况:
WARNING: Interactive authentication is not supported in this session,
falling back to DeviceCode. Future versions will not automatically fallback to DeviceCode.
然后
ERROR: Could not find file 'C:\home\site\wwwroot\.graph'.
Exception : Type : System.IO.FileNotFoundException
Message : Could not find file 'C:\home\site\wwwroot\.graph'.
FileName : C:\home\site\wwwroot\.graph TargetSite :
Name : MoveNext DeclaringType : Microsoft.Graph.PowerShell.Authentication.Cmdlets.ConnectMgGraph+<ProcessRecordAsync>d__52, Microsoft.Graph.Authentication, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
...<cut>
Line : Connect-MgGraph -Scopes 'Reports.Read.All', 'Group.ReadWrite.All' PositionMessage : At C:\home\site\wwwroot\TestPowerShellTimer\run.ps1:15 char:1 + Connect-MgGraph -Scopes 'Reports.Read.All', 'Group.ReadWrite.All'
...<cut>
代码
# Input bindings are passed in via param block.
param($Timer)
Import-Module Microsoft.Graph.Authentication
Connect-MgGraph -Scopes 'Reports.Read.All', 'Group.ReadWrite.All'
$reportJson = Invoke-GraphRequest -Uri 'https://graph.microsoft.com/beta/reports/credentialUserRegistrationDetails?$top=5000' -Method GET
为什么
我可以使用 Connect-MsOnline(对 msonline 做同样的事情),但代码使用的完成时间要长得多。
我
正在遍历我们的用户以查看他们是否设置了 MFA,并将它们添加到安全组中。不,没有办法使用 azure 广告动态组 afaik 做到这一点。但是,如果有人对实现此目标的其他方法有建议,请随时提及...
我的想法
显然,我遗漏了一些东西或完全误解了一些东西。
错误消息“C:\home\site\wwwroot.graph”的部分,我无法弄清楚。在这一点上,谷歌不是我的朋友。
我想我必须以某种方式指示 AzF 使用托管标识:
Import-Module Microsoft.Graph.Authentication
Connect-MgGraph -Scopes -TenantId -ClientId
但我不知道怎么做。我意识到我已经猜到了,然后是时候寻求帮助了。
如何通过 Microsoft.Graph.Authentication 模块在 Azure Functions 中使用托管标识?
解决方案
由于您使用的是已连接到 Azure 的系统标识,因此您可以生成访问令牌并将其传递给Connect-MGGraph -AccessToken
这是我大约一两年前制作的一个功能,正是为了达到这个目的。(我需要任何经过身份验证的用户能够根据他们当前连接的身份获得任何 Azure 端点的令牌,而无需任何其他形式的凭据验证)
function Get-AzToken {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[String]
$ResourceUri,
[Switch]$AsHeader
)
$Context = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile.DefaultContext
$Token = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, $ResourceUri).AccessToken
if ($AsHeader) {
return @{Headers = @{Authorization = "Bearer $Token" } }
}
return $Token
}
$Token = Get-AzToken -ResourceUri 'https://graph.microsoft.com/'
Connect-MgGraph -AccessToken $Token
请注意,要使其正常工作,在您的 Azure 函数profile.ps1
中,您应该Connect-AzAccount -Identity
取消注释该行。
Profile.ps1片段
if ($env:MSI_SECRET) {
Disable-AzContextAutosave -Scope Process | Out-Null
Connect-AzAccount -Identity
}
如果启用 Azure AD 身份验证,此方法将用于获取任何 Azure 终结点(包括您自己的函数)的令牌。
奖金
如果 Azure 函数受 Azure AD 身份验证保护,那么您将如何使用它来调用 Azure 函数。
# This work assuming you connecteded through Connect-AzAccount at some point.
# ResourceUri is the ClientID of your application.
$Headers = Get-AzToken -ResourceUri '3953d051-c61f-43c5-8848-487a921aae31' -AsHeader
$base = 'https://YourFunctionUrl.azurewebsites.net/api'
Invoke-RestMethod -Method Get -Uri "$base/MyApiEndpoint" @Headers
推荐阅读
- mysql - 从远程主机连接到 mysql 数据库
- javascript - 我可以在 pouchdb upsert 中将变量作为键传递吗
- python - Python中没有通用的对象序列化方法(到json)?
- apache-spark - 使用 reduceByKey 会抛出 int object is not subscriptable 错误
- c++ - 在 C++ 中调用 map 的任何函数之前转换键
- sql - 依靠 Rails Active Record 中的嵌套模型
- javascript - jQuery不一致的相对路径
- ios - 无法将作为自定义视图实现的 UILabel 的文本颜色设置为 UIBarButtonItem
- python - sharepoint 服务器是否接受 http 标头中的“范围”请求?
- python-3.x - terraform 部署的 EC2 上的 Python 应用程序无法访问机密