Retrieve the host keys from an azure function app

后端 未结 6 1693
梦如初夏
梦如初夏 2020-12-01 19:03

I am trying to script an environment using the Azure cli. I have created a few function apps and would like to add a host key or at least retrieve the default one that is cr

相关标签:
6条回答
  • 2020-12-01 19:49

    If you want to do this in bash, see this gist for a start

    0 讨论(0)
  • 2020-12-01 19:50

    If you just want to get the keys and don't need to automate the authentication process:

    Get-AzResource -Name RESOURCE-NAME | Invoke-AzResourceAction -Action host/default/listkeys -Force
    
    0 讨论(0)
  • 2020-12-01 19:56

    I was just able to make this work with the Azure CLI using this command:

    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
    

    I realize this is a couple years late on the answer, but it might help people who are searching now.

    0 讨论(0)
  • 2020-12-01 19:58

    Thanks both for your replies. Using your answer Mike S and rummaging around the csharp fluent source code (thanks Tom Sun) I ended up with this. Sure do need a lot of tokens! The credentials I start with are what you would get back from 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
    
    0 讨论(0)
  • 2020-12-01 20:07

    Here are the steps.

    1. Assuming you already have your Kudu deployment credentials. (it sounds like you already know how to do this. You can get it via an ARM call from your service principle, etc)
    2. From kudu deployment creds, you can get a JWT that lets you call the Functions key API.
    3. From the Functions API, you can get all your keys (including your master).

    Here's a powershell script that demonstrates the exact calls to go from Kudu deployment creds to Function Master key:

    # 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
    
    0 讨论(0)
  • 2020-12-01 20:07

    I do not know how to get "kudu" credentials with my service principal credentials

    If C# code is acceptable, we could use Microsoft.Azure.Management.ResourceManager.Fluent and Microsoft.Azure.Management.Fluent to do that easily. The following is the demo that how to get kudu credentials and run Key management API .I test it locally, it works correctly on my side.

     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;
      }
    

    0 讨论(0)
提交回复
热议问题