当Azure Functions设置为只读时,如何创建Azure Function和Function Key

3
摘要:我正在Visual Studio中直接编写一个函数,这样设计会在门户中产生只读函数管理。我的问题是如何轻松地为所述的Webhook创建一个函数密钥? 上下文:我试图将通用Webhook连接到事件网格。这个过程让我需要触发SubscriptionValidationEvent,这反过来又要求我的Webhook在URL上提供“代码”,我假设这是一个函数密钥。
还有,在我被投票否决之前,我非常清楚这里已经有多个变体的问题被问到和回答了。我尝试了所有这些解决方案,但由于某种原因,使用Kudu凭据针对文档不良的Keys API编写PowerShell的解决方案似乎都不能为我工作。
我希望有人知道用CLI或者更容易的方法来解决这个问题,甚至是手动创建一个functionName.json文件并将其放入secrets目录中。
最后,虽然使用预发布的EventGrid绑定很诱人,但我目前无法在我的环境中推送预发布代码。

你需要一些使用Kudu API生成密钥的示例代码吗?这是我目前在生产中找到并使用的唯一可靠选项。 - Thomas
你是否可以在门户中创建“读/写”函数?你也可以从应用程序设置中进行此操作。https://learn.microsoft.com/en-us/azure/azure-functions/functions-app-settings#functionappeditmode - Vladislav
@Thomas 好的,请。不过我还没有让这里的PowerShell示例工作起来。 - ThatCreole
@Vladislav 我也尝试过那样做。但是当你这样做时,门户会显示“您的应用程序当前处于读/写模式,因为您已将编辑模式设置为读/写,尽管已生成function.json。对function.json所做的更改将不会被Functions运行时采纳。” - ThatCreole
1个回答

5

我在这里找到了一篇有关如何使用Powershell管理Azure Functions密钥的有趣文章:

还有官方文档(很难找到这个维基):

以下是要点:

  1. 获取发布凭据
  2. 生成Kudu API授权令牌
  3. 调用Kudu /api/functions/admin/token以获取可与Functions Key API一起使用的JWT
  4. 然后您可以做任何想做的事情

这是我的现有脚本:

    Param(
    [string] [Parameter(Mandatory=$true)] $resourceGroupName,
    [string] [Parameter(Mandatory=$true)] $functionappName,
    [string] [Parameter(Mandatory=$true)] $keyname,
    [string] [Parameter()] $slot
)

if (![string]::IsNullOrWhiteSpace($slot)){
    $apiBaseUrl = "https://$functionappName-$slot.scm.azurewebsites.net/api"
    $siteBaseUrl = "https://$functionappName-$slot.azurewebsites.net"
    $resourceType = "Microsoft.Web/sites/slots/config"
    $resourceName = "$functionappName/$slot/publishingcredentials"
}
else {
    $apiBaseUrl = "https://$functionappName.scm.azurewebsites.net/api"
    $siteBaseUrl = "https://$functionappName.azurewebsites.net"
    $resourceType = "Microsoft.Web/sites/config"
    $resourceName = "$functionappName/publishingcredentials"
}

Write-Host "Get the publishing credentials"
$publishingCredentials = Invoke-AzureRmResourceAction -ResourceGroupName $resourceGroupName -ResourceType $resourceType -ResourceName $resourceName -Action list -ApiVersion 2015-08-01 -Force

Write-Host "Generate the Kudu API Authorisation Token"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $publishingCredentials.Properties.PublishingUserName, $publishingCredentials.Properties.PublishingPassword)))

Write-Host "Call Kudu /api/functions/admin/token to get a JWT that can be used with the Functions Key API"
$jwt = Invoke-RestMethod -Uri "$apiBaseUrl/functions/admin/token" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method GET

Write-Host "Creates or updates an host key at the specified resource with an auto generated key"
$mynewkey = (Invoke-RestMethod -Uri "$siteBaseUrl/admin/host/keys/$keyname" -Headers @{Authorization=("Bearer {0}" -f $jwt)} -Method Post).value

编辑

新创建的函数应用默认使用TLS 1.2,因此您需要在PowerShell脚本顶部添加以下行:

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

谢谢Thomas。这让我离解决问题非常接近了。 我认为我卡在了尝试针对部署槽运行此代码的事实上。 我已经修改了上面的代码以使$resourceType =“Microsoft.Web/sites/slots/config”并且 $resourceName =“$functionappName/<myslot>/publishingcredentials”。 这至少允许我获得合法的JWT。然而,在此位置进行POST生成新密钥$siteBaseUrl/admin/host/keys/$keyname似乎是错误的。 我确定其中有一个槽路径,但它并不明显。 - ThatCreole
是的,你可能需要修改这个位置$siteBaseUrl/admin/host/keys/$keyname来包含插槽。我不太确定如何做到这一点,现在我会查看一下。 - Thomas
@ThatCreole,我刚刚尝试了修改resourceType和resourceName,现在我可以在门户上看到我的新密钥。 - Thomas
等等,你用了哪个路径?! - ThatCreole
抱歉回复晚了,我已更新我的脚本以处理插槽。 - Thomas
你的脚本和我的基本相同,但最后一部分(POST以生成密钥)失败了。经过我一番调试,发现它被EasyAuth启用的事实所困扰。为了不浪费时间去弄清楚我需要什么其他令牌,我暂时禁用了身份验证,运行了它,得到了密钥,然后再次启用了身份验证。最终解决了我的问题。谢谢! - ThatCreole

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接