从 Azure 函数应用程序检索主机密钥
Retrieve the host keys from an azure function app
我正在尝试使用 Azure cli 编写环境脚本。我已经创建了一些函数应用程序,并想添加一个主机密钥或至少检索自动创建的默认密钥。 azure 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 进行身份验证.我有一个服务主体(用户标识、密码、租户标识),我希望不必向我的脚本添加另一个身份验证方案。
步骤如下。
- 假设您已经拥有 Kudu 部署凭据。 (听起来您已经知道如何执行此操作。您可以通过服务原则等通过 ARM 调用来获取它)
- 从 kudu 部署凭证中,您可以获得一个 JWT,它可以让您调用 Functions 键 API。
- 从函数API,你可以获得你所有的钥匙(包括你的主人)。
这是一个 powershell 脚本,它演示了从 Kudu 部署凭据到 Function Master 密钥的确切调用:
# 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
I do not know how to get "kudu" credentials with my service principal credentials
如果 C# 代码可以接受,我们可以使用 Microsoft.Azure.Management.ResourceManager.Fluent and Microsoft.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;
}
感谢两位的回复。使用您的答案 Mike S 并翻遍 csharp 流畅的源代码(感谢 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
如果您想在 bash 中执行此操作,请先参阅 this gist
我刚刚能够使用此命令将其与 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
我意识到这个答案晚了几年,但它可能对现在正在搜索的人有所帮助。
如果您只想获取密钥而不需要自动执行身份验证过程:
Get-AzResource -Name RESOURCE-NAME | Invoke-AzResourceAction -Action host/default/listkeys -Force
确保您拥有最新版本的 Az 模块。
安装:
Install-Module -Name Az -Force
或
更新:
Update-Module -Name Az
确保在 运行 执行上述命令之一后启动新的 PowerShell window。
然后您可以在设置资源组名称和函数名称变量后运行执行以下操作:
$azureFunction = Get-AzFunctionApp -ResourceGroupName $resourceGroupName -Name $azureFunctionName
$keys = Invoke-AzResourceAction -ResourceId $($azureFunction.Id) -Action "host/default/listKeys" -Force
$defaultKey = $keys.functionKeys.default
我正在尝试使用 Azure cli 编写环境脚本。我已经创建了一些函数应用程序,并想添加一个主机密钥或至少检索自动创建的默认密钥。 azure 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 进行身份验证.我有一个服务主体(用户标识、密码、租户标识),我希望不必向我的脚本添加另一个身份验证方案。
步骤如下。
- 假设您已经拥有 Kudu 部署凭据。 (听起来您已经知道如何执行此操作。您可以通过服务原则等通过 ARM 调用来获取它)
- 从 kudu 部署凭证中,您可以获得一个 JWT,它可以让您调用 Functions 键 API。
- 从函数API,你可以获得你所有的钥匙(包括你的主人)。
这是一个 powershell 脚本,它演示了从 Kudu 部署凭据到 Function Master 密钥的确切调用:
# 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
I do not know how to get "kudu" credentials with my service principal credentials
如果 C# 代码可以接受,我们可以使用 Microsoft.Azure.Management.ResourceManager.Fluent and Microsoft.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;
}
感谢两位的回复。使用您的答案 Mike S 并翻遍 csharp 流畅的源代码(感谢 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
如果您想在 bash 中执行此操作,请先参阅 this gist
我刚刚能够使用此命令将其与 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
我意识到这个答案晚了几年,但它可能对现在正在搜索的人有所帮助。
如果您只想获取密钥而不需要自动执行身份验证过程:
Get-AzResource -Name RESOURCE-NAME | Invoke-AzResourceAction -Action host/default/listkeys -Force
确保您拥有最新版本的 Az 模块。
安装:
Install-Module -Name Az -Force
或
更新:
Update-Module -Name Az
确保在 运行 执行上述命令之一后启动新的 PowerShell window。
然后您可以在设置资源组名称和函数名称变量后运行执行以下操作:
$azureFunction = Get-AzFunctionApp -ResourceGroupName $resourceGroupName -Name $azureFunctionName
$keys = Invoke-AzResourceAction -ResourceId $($azureFunction.Id) -Action "host/default/listKeys" -Force
$defaultKey = $keys.functionKeys.default