我正在使用SendGrid bindings在Azure Functions中发送电子邮件。作为该电子邮件内容的一部分,我想在Azure Functions实例中包括指向HTTP methods之一的链接以获取更多信息。我的所有HTTP函数都由AuthorizationLevel.Function
保护。
我已经看到了scraping the keys from ARM and Kudu in PowerShell(和this one)的解决方案以及output the keys with just ARM的解决方案,但是它们都依赖于我的Azure Functions不具备的功能:对ARM的权限(Azure资源管理)API。
我还发现Key management APIs for the Azure Functions host完全可以在本地运行,但是我不知道在部署Azure功能后如何克服401 Unauthorized
的问题。我可以使用_master
功能键手动克服它,但是我又回到了不知道如何在运行时获取该键的地方。
问题是这样的:是否有可能在运行时从Azure Function Host获取Azure Function的密钥?我非常希望不需要ARM权限来做到这一点。
答案 0 :(得分:2)
尝试以下两个步骤:
获取主机主密钥:
GET https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourcegroupName}/providers/Microsoft.Web/sites/{functionApp}/functions/admin/masterkey?api-version=2016-08-01
获取功能键:
GET https://{functionApp}.azurewebsites.net/admin/functions/{functionName}/keys?code={masterKeyFromStep1}
第2步的响应:
{
"keys": [
{
"name": "default",
"value": "xxxxxxxxxxxxxxxxxxxxxx"
}
],
"links": [
{
"rel": "self",
"href": "https://myFncApp.azurewebsites.net/admin/functions/myFunction/keys"
}
]
}
更新:
请注意,第1步要求使用以下格式的授权标头:
Authorization: Bearer bearerToken
可以从Azure Active Directory(AAD)获得bearerToken字符串的地方,请参见示例的以下代码片段:
private string AccessToken(string clientID)
{
string redirectUri = "https://login.live.com/oauth20_desktop.srf";
authContext = new AuthenticationContext("https://login.windows.net/common/oauth2/authorize", TokenCache.DefaultShared);
var ar = authContext.AcquireTokenAsync("https://management.azure.com/", clientID, new Uri(redirectUri), new PlatformParameters(PromptBehavior.SelectAccount)).Result;
return ar.AccessToken;
}
请注意, clientID 是您在AAD中注册的应用程序的quid,具有对 Windows Azure Service Management API 的API访问权限。
答案 1 :(得分:1)
Powershell方式:
exports.FilelamdaFunctionHandler = async function(event, context){
try {
let contentType = event.headers['Content-Type']
console.log('content type is--' + contentType)
contentType = contentType.split("/")[1]
let type = (contentType == 'plain') ? ".txt" : ".csv"
const params = {
Body: event.body,
Bucket: bucketName + "/" + event.pathParameters.hospital,
Key: event.pathParameters.hospital + type,
ContentType: "*"
};
const results = await s3.putObject(params).promise();
console.log('resultss --' + JSON.stringify(results);
} catch(error) {
console.log('errors in promise' + error)
console.log('e--' + error.toString())
console.log('errorororooror' + JSON.stringify(error));
const response = {
'statusCode':500,
'body':"error"
}
return response;
}
console.log('second')
const response = {
'statusCode':200,
'body':"sucess"
}
return response;
}
答案 2 :(得分:0)
要在使用ARM模板的CI管道中执行此操作,您需要确保密钥库和启动功能在同一资源组中。
将以下内容作为ARM模板运行,确保以增量的身份运行。这将从指定的函数中获取密钥,并将其放入所需的密钥库中。
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"functionAppName":: {
"type": "string",
"metadata": {
"description": "The name of the function app that you wish to get the key from."
}
},
"functionName": {
"type": "string",
"metadata": {
"description": "The name of the function that you wish to get the key from."
}
},
"keyVaultName": {
"type": "string",
"metadata": {
"description": "The name of the key vault you wish to put the key in."
}
}
},
"variables": {
"functionAppName": "[parameters('functionAppName')]",
"keyVaultName": "[parameters('keyVaultName')]",
"functionName": "[parameters('functionName')]"
},
"resources": [
{
"type": "Microsoft.KeyVault/vaults/secrets",
"name": "[concat(variables('keyVaultName'),'/', variables('functionAppName'))]",
"apiVersion": "2015-06-01",
"properties": {
"contentType": "text/plain",
"value": "[listsecrets(resourceId('Microsoft.Web/sites/functions', variables('functionAppName'), variables('functionName'),'2015-08-01').key]"
},
"dependsOn": []
}
]
}
答案 3 :(得分:0)
Nuget: Microsoft.Azure.Management.Fluent API 现在可以管理密钥:
using Microsoft.Azure.Management.AppService.Fluent;
var functionApp = AzureInstance.AppServices.FunctionApps.GetByResourceGroup(resourceGroupName, functionAppName);
foreach (var function in functionApp.ListFunctions())
{
var functionName = function.Name.Split('/')[1];
var functionKeys = functionApp.ListFunctionKeys(functionName);
functionKeys.TryGetValue(keyName, out string functionKey);
dict.Add(functionName, functionKey);
}
您还可以设置新键: (将null作为自动生成的密钥的秘密传递)
foreach (var function in functionApp.ListFunctions())
{
var functionName = function.Name.Split('/')[1];
var nameValue = functionApp.AddFunctionKey(functionName, keyName,null);
}
注意事项:要在生产环境中使用此功能,FunctionApp标识必须具有Function App的RBAC所有者角色。这是在访问控制(IAM)刀片服务器上设置的。
答案 4 :(得分:0)
您可以使用Kudu通过HTTP获取主键和功能键:
示例(在Powershell中):
$RSGROUP="mygroup"
$WEBAPPNAME="myfunctionsapp"
$function="myfunction"
$DeploymentUrl = Get-AzWebAppContainerContinuousDeploymentUrl -ResourceGroupName $RSGROUP -Name $WEBAPPNAME
$userpass = $DeploymentUrl.split("@")[0].Replace("https://","")
$kuduCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($userpass))
$jwt = Invoke-RestMethod -Uri "https://$WEBAPPNAME.scm.azurewebsites.net/api/functions/admin/token" -Headers @{Authorization=("Basic {0}" -f $kuduCreds)} -Method GET
$masterkey=(Invoke-RestMethod "https://$WEBAPPNAME.azurewebsites.net/admin/host/systemkeys/_master" -Headers @{Authorization="Bearer $jwt"}).value
$functionkey=(Invoke-RestMethod "https://$WEBAPPNAME.azurewebsites.net/admin/functions/$function/keys" -Headers @{Authorization="Bearer $jwt"}).keys[0].value
echo $masterkey
echo $functionkey