【问题标题】:Retrieve the host keys from an azure function app从 azure 函数应用中检索主机密钥
【发布时间】:2021-05-12 04:37:09
【问题描述】:

我正在尝试使用 Azure cli 编写环境脚本。我创建了一些功能应用程序,并希望添加一个主机密钥或至少检索自动创建的默认密钥。天蓝色的 cli 根本不支持这一点。

函数本身似乎有一个 api(它的文档似乎很稀疏),可以让我获取密钥,但是你需要一个密钥才能使用它所以..那里没有帮助。

https://github.com/Azure/azure-webjobs-sdk-script/wiki/Key-management-API

例如:https://example-functions.azurewebsites.net/admin/host/keys?code=somecodeyoualreadyknow

我已经看到了一些使用 webapps scm api 下载包含密钥的 json 文件的其他示例,但是我不确定如何使用此 API 进行身份验证。我有一个服务主体(用户 ID、密码、租户 ID),我希望不必在我的脚本中添加另一个身份验证方案。

【问题讨论】:

    标签: azure azure-functions azure-cli


    【解决方案1】:

    这里是步骤。

    1. 假设您已经拥有 Kudu 部署凭据。 (听起来您已经知道如何做到这一点。您可以通过服务原则等的 ARM 调用来获取它)
    2. 从 kudu 部署凭据中,您可以获得一个 JWT,它允许您调用 Functions 密钥 API。
    3. 通过 Functions API,您可以获得所有密钥(包括您的主密钥)。

    这是一个 powershell 脚本,演示了从 Kudu 部署凭据到功能主密钥的确切调用:

    # You need to start with these:
    $site = "YourSiteName"
    $username='YourDeploymentUserName'
    $password='YourDeploymentPassword'
    
    # Now... 
    $apiBaseUrl = "https://$($site).scm.azurewebsites.net/api"
    $siteBaseUrl = "https://$($site).azurewebsites.net"
    
    # For authenticating to Kudu
    $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username,$password)))
    
    
    # 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
    
    # Call Functions Key API to get the master key 
    $x = Invoke-RestMethod -Uri "$siteBaseUrl/admin/host/systemkeys/_master" -Headers @{Authorization=("Bearer {0}" -f $jwt)} -Method GET
    
    $masterKey = $x.value
    

    【讨论】:

    • 嗨,我有服务主体凭据,但据我了解,它们并不相同。我不知道如何使用我的服务主体凭据获取“kudo”凭据。
    【解决方案2】:

    我只是能够使用此命令在 Azure CLI 中完成这项工作:

    az rest --method post --uri \
    "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Web/sites/$FUNCTION_APP_NAME/host/default/listKeys?api-version=2018-11-01" \
    --query functionKeys.default --output tsv
    

    我意识到这比答案晚了几年,但它可能会对现在正在搜索的人有所帮助。

    【讨论】:

    • 我今天完全在寻找这个。一直在寻找几个小时试图弄清楚如何以 2019 年的方式做到这一点……先生,您是一位绅士和一位学者。谢谢!
    【解决方案3】:

    我不知道如何使用我的服务主体凭据获取“kudu”凭据

    如果 C# 代码是可接受的,我们可以使用 Microsoft.Azure.Management.ResourceManager.FluentMicrosoft.Azure.Management.Fluent 轻松做到这一点。以下是如何获取 kudu 凭据并运行密钥管理 API 的演示。我在本地测试它,它在我这边可以正常工作。

     string clientId = "client id";
     string secret = "secret key";
     string tenant = "tenant id";
     var functionName ="functionName";
     var webFunctionAppName = "functionApp name";
     string resourceGroup = "resource group name";
     var credentials = new AzureCredentials(new ServicePrincipalLoginInformation { ClientId = clientId, ClientSecret = secret}, tenant, AzureEnvironment.AzureGlobalCloud);
     var azure = Azure
              .Configure()
              .Authenticate(credentials)
              .WithDefaultSubscription();
    
     var webFunctionApp = azure.AppServices.FunctionApps.GetByResourceGroup(resourceGroup, webFunctionAppName);
     var ftpUsername = webFunctionApp.GetPublishingProfile().FtpUsername;
     var username = ftpUsername.Split('\\').ToList()[1];
     var password = webFunctionApp.GetPublishingProfile().FtpPassword;
     var base64Auth = Convert.ToBase64String(Encoding.Default.GetBytes($"{username}:{password}"));
     var apiUrl = new Uri($"https://{webFunctionAppName}.scm.azurewebsites.net/api");
     var siteUrl = new Uri($"https://{webFunctionAppName}.azurewebsites.net");
     string JWT;
     using (var client = new HttpClient())
      {
         client.DefaultRequestHeaders.Add("Authorization", $"Basic {base64Auth}");
    
         var result = client.GetAsync($"{apiUrl}/functions/admin/token").Result;
         JWT = result.Content.ReadAsStringAsync().Result.Trim('"'); //get  JWT for call funtion key
       }
     using (var client = new HttpClient())
     {
        client.DefaultRequestHeaders.Add("Authorization", "Bearer " + JWT);
        var key = client.GetAsync($"{siteUrl}/admin/functions/{functionName}/keys").Result.Content.ReadAsStringAsync().Result;
      }
    

    【讨论】:

      【解决方案4】:

      如果您只想获取密钥而不需要自动执行身份验证过程:

      Get-AzResource -Name RESOURCE-NAME | Invoke-AzResourceAction -Action host/default/listkeys -Force
      

      【讨论】:

        【解决方案5】:

        感谢两位的回复。使用您的答案 Mike S 并翻阅 csharp fluent 源代码(感谢 Tom Sun),我最终得到了这个。当然确实需要很多代币!我开始使用的凭据是您将从 az ad sp create-for-rbac -n $name --role contributor 得到的凭据

        $credentials = (ConvertFrom-Json $env:AzureCliLogin)
        
        $tenant = $credentials.tenant
        $clientId = $credentials.appId
        $clientSecret = $credentials.password
        $subscriptionId = "<subscription id>"
        
        $body = @{
            "grant_type"="client_credentials";
            "client_id"=$clientId;
            "client_secret"=$clientSecret;
            "resource"="https://management.azure.com/"
        }
        
        $authInfo = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$tenant/oauth2/token" -Body $body -Method Post -Headers @{"Content-Type"="application/x-www-form-urlencoded"} 
        
        $publishData = Invoke-RestMethod -Uri "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.Web/sites/$name/publishxml?api-version=2016-08-01" -Method Post -Headers @{"Authorization"="Bearer $($authInfo.access_token)"}
        
        $userName = $publishData.publishData.publishProfile[0].userName
        $password = $publishData.publishData.publishProfile[0].userPWD
        
        $apiBaseUrl = "https://$name.scm.azurewebsites.net/api"
        $siteBaseUrl = "https://$name.azurewebsites.net"
        
        # For authenticating to Kudu
        $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username,$password)))    
        
        # 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
        
        # Call Functions Key API to get the master key 
        $x = Invoke-RestMethod -Uri "$siteBaseUrl/admin/host/systemkeys/_master" -Headers @{Authorization=("Bearer {0}" -f $jwt)} -Method GET
        
        $masterKey = $x.value
        

        【讨论】:

          【解决方案6】:

          如果您想在 bash 中执行此操作,请参阅 this gist 了解开始

          【讨论】:

            【解决方案7】:

            确保您拥有最新版本的 Az 模块。

            安装:

            Install-Module -Name Az -Force
            

            更新:

            Update-Module -Name Az
            

            确保在运行上述命令之一后启动一个新的 PowerShell 窗口。

            然后,您可以在设置资源组名称和函数名称变量后运行以下命令:

            $azureFunction = Get-AzFunctionApp -ResourceGroupName $resourceGroupName -Name $azureFunctionName
            $keys = Invoke-AzResourceAction -ResourceId $($azureFunction.Id) -Action "host/default/listKeys" -Force
            $defaultKey = $keys.functionKeys.default
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2017-09-01
              • 2021-02-19
              • 1970-01-01
              • 2022-11-19
              • 1970-01-01
              • 2018-08-20
              相关资源
              最近更新 更多