Azure.Data.Tables 方法 - 如何从使用共享密钥 + Uri 更改为托管 ID?
Azure.Data.Tables method - how to change from using shared key + Uri to managed Id?
我有一个 Azure 函数(HTTP 触发器)可以写入队列,也可以写入存储 table。
它一直运行良好,但现在我需要将所有内容移至使用托管身份。
我能够将 HTTP 触发器更改为使用 __serviceUri 环境变量进行连接,而不是使用连接字符串。但现在我需要弄清楚如何更新写入存储 table.
的逻辑
这是相关代码。
HTTP 触发器
[FunctionName("Createwidget")]
public async Task<IActionResult> Createwidget(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "toys/widgets")] HttpRequest req,
[Queue("widgets"), StorageAccount("ExtStorageQueue")] ICollector<string> messageQueue,
ILogger log)
{
widgetResponse response = new widgetResponse();
var content = await new StreamReader(req.Body).ReadToEndAsync();
log.LogInformation($"Received following payload: {content}");
var widgetRequest = JsonConvert.DeserializeObject<widget>(content);
if (widgetRequest.name != null){
messageQueue.Add(JsonConvert.SerializeObject(widgetRequest));
// this is where I need to update the code
response = await storage.ProvisioningRequest(widgetRequest, req.HttpContext.Items["MS_AzureFunctionsRequestID"].ToString(), "enqueued");
}
else {
response.status = "Error: Invalid Request";
response.requestId=null;
}
return new OkObjectResult(JsonConvert.SerializeObject(response));
}
这是来自 storage.ProvisioningRequest()
的片段
GetStorageAccountConnectionData
var serviceClient = new TableServiceClient(
new Uri(connection.storageUri),
new TableSharedKeyCredential(connection.storageAccountName, connection.storageAccountKey));
var tableClient = serviceClient.GetTableClient(connection.tableName);
await tableClient.CreateIfNotExistsAsync();
这是我创建连接的方式:
private void GetStorageAccountManagedIDConnection()
{
var azureWebJobsStorage = Environment.GetEnvironmentVariable("AzureWebJobsStorage");
String[] accountDetailsArray = azureWebJobsStorage.Split(";");
String[] accountNameArray = accountDetailsArray[1].Split("=");
connection.storageAccountName = accountNameArray[1];
var storageAccount= Environment.GetEnvironmentVariable("ExtStorageQueue");
String[] storageAccountDetailsArray = storageAccount.Split(";");
String[] accountKeyDetailsArray = storageAccountDetailsArray[2].Split("AccountKey=");
string storageKey = accountKeyDetailsArray[1];
connection.tableName = Environment.GetEnvironmentVariable("squeueTable");
connection.storageUri = $"https://{connection.storageAccountName}.table.core.windows.net/{connection.tableName}";
connection.storageAccountKey = storageKey;
}
这是我的 local.settings.json 文件的样子:
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=mystorageAccountName;EndpointSuffix=core.windows.net;AccountKey=supersecretKey/asdf+asdf==",
"squeueTable": "provisionedWidgets",
"ExtStorageQueue__serviceUri": "https://mystorageAccountName.queue.core.windows.net",
},
"ConnectionStrings": {}
}
有办法吗?我一直在阅读 https://docs.microsoft.com/en-us/dotnet/api/azure.data.tables.tableclient?view=azure-dotnet#constructors,但我没有看到任何允许我使用托管 ID
的构造函数
任何帮助将不胜感激
编辑 1
这是创建连接配置数据的简化方法:
private void GetStorageAccountConnectionData()
{
//TODO: remove hardcoded values and extract from local.settings.json instead. For testing purposes only to see how serivceUri works.
connection.storageAccountName = "mystorageaccountname";
connection.tableName = Environment.GetEnvironmentVariable("StorageTableName");
connection.storageTableUri = $"https://{connection.storageAccountName}.table.core.windows.net/{connection.tableName}";
connection.storageQueueUri = $"https://{connection.storageAccountName}.queue.core.windows.net/";
}
这是使用它的逻辑:
GetStorageAccountConnectionData();
var serviceClient = new TableServiceClient(new Uri(connection.storageTableUri), new DefaultAzureCredential());
var tableClient = serviceClient.GetTableClient(connection.tableName);
TableEntity origEntity = tableClient.GetEntity<TableEntity>(
ENQUEUED_PARTITION,
notification.requestId);
没有编译错误,但未写入存储table。
我目前正在尝试查看有关创建调试消息/日志的信息,因为我无法让我的本地调试环境正常工作
编辑 2
我终于设置了本地环境,以便进行调试。所以写入我的存储队列的逻辑是有效的,但是当我尝试写入存储 table 时,我现在可以看到完整的错误是什么。这是错误:
Failed to create storage record:Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. ure.
RequestId:asdf-0002-asdf-6574-asdf
Time:2022-05-10T13:45:24.6319496Z
Status: 403 (Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.)
ErrorCode: AuthenticationFailed
Content:
{"odata.error":{"code":"AuthenticationFailed","message":{"lang":"en-US","value":"Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including
is formed correctly including the signature.\nRequestId:9f775fd8-0002-002c-6574-648209000000\nTime:2022-05-10T13:45:24.6319496Z"}}}
Headers:
Server: Microsoft-HTTPAPI/2.0
x-ms-request-id: asdf-asdf-asdf-asdf
x-ms-error-code: REDACTED
Date: Tue, 10 May 2022 13:45:23 GMT
Content-Length: 299
Content-Type: application/json
还要明确一点,当我在云中测试时也会发生同样的行为。所以不管我叫
POST https://myfunctionapp.azurewebsites.net/widgets/workspaces
或
POST http://localhost:7071/widgets/workspaces
这是相同的行为。存储队列已更新,但 table.
未更新
就托管 ID 而言,它现在具有以下权限:
您需要添加对这些包的引用:
您的功能应用程序将需要 Storage Account Contributor
或 Contributor
存储级别的角色(说实话不确定)。
下面是您的代码的一个片段:
var serviceClient = new TableServiceClient(
new Uri(connection.storageUri), new DefaultAzureCredential());
var tableClient = serviceClient.GetTableClient (connection.tableName);
await tableClient.CreateIfNotExistsAsync();
我有一个 Azure 函数(HTTP 触发器)可以写入队列,也可以写入存储 table。 它一直运行良好,但现在我需要将所有内容移至使用托管身份。
我能够将 HTTP 触发器更改为使用 __serviceUri 环境变量进行连接,而不是使用连接字符串。但现在我需要弄清楚如何更新写入存储 table.
的逻辑这是相关代码。
HTTP 触发器
[FunctionName("Createwidget")]
public async Task<IActionResult> Createwidget(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "toys/widgets")] HttpRequest req,
[Queue("widgets"), StorageAccount("ExtStorageQueue")] ICollector<string> messageQueue,
ILogger log)
{
widgetResponse response = new widgetResponse();
var content = await new StreamReader(req.Body).ReadToEndAsync();
log.LogInformation($"Received following payload: {content}");
var widgetRequest = JsonConvert.DeserializeObject<widget>(content);
if (widgetRequest.name != null){
messageQueue.Add(JsonConvert.SerializeObject(widgetRequest));
// this is where I need to update the code
response = await storage.ProvisioningRequest(widgetRequest, req.HttpContext.Items["MS_AzureFunctionsRequestID"].ToString(), "enqueued");
}
else {
response.status = "Error: Invalid Request";
response.requestId=null;
}
return new OkObjectResult(JsonConvert.SerializeObject(response));
}
这是来自 storage.ProvisioningRequest()
的片段GetStorageAccountConnectionData
var serviceClient = new TableServiceClient(
new Uri(connection.storageUri),
new TableSharedKeyCredential(connection.storageAccountName, connection.storageAccountKey));
var tableClient = serviceClient.GetTableClient(connection.tableName);
await tableClient.CreateIfNotExistsAsync();
这是我创建连接的方式:
private void GetStorageAccountManagedIDConnection()
{
var azureWebJobsStorage = Environment.GetEnvironmentVariable("AzureWebJobsStorage");
String[] accountDetailsArray = azureWebJobsStorage.Split(";");
String[] accountNameArray = accountDetailsArray[1].Split("=");
connection.storageAccountName = accountNameArray[1];
var storageAccount= Environment.GetEnvironmentVariable("ExtStorageQueue");
String[] storageAccountDetailsArray = storageAccount.Split(";");
String[] accountKeyDetailsArray = storageAccountDetailsArray[2].Split("AccountKey=");
string storageKey = accountKeyDetailsArray[1];
connection.tableName = Environment.GetEnvironmentVariable("squeueTable");
connection.storageUri = $"https://{connection.storageAccountName}.table.core.windows.net/{connection.tableName}";
connection.storageAccountKey = storageKey;
}
这是我的 local.settings.json 文件的样子:
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=mystorageAccountName;EndpointSuffix=core.windows.net;AccountKey=supersecretKey/asdf+asdf==",
"squeueTable": "provisionedWidgets",
"ExtStorageQueue__serviceUri": "https://mystorageAccountName.queue.core.windows.net",
},
"ConnectionStrings": {}
}
有办法吗?我一直在阅读 https://docs.microsoft.com/en-us/dotnet/api/azure.data.tables.tableclient?view=azure-dotnet#constructors,但我没有看到任何允许我使用托管 ID
的构造函数任何帮助将不胜感激
编辑 1
这是创建连接配置数据的简化方法:
private void GetStorageAccountConnectionData()
{
//TODO: remove hardcoded values and extract from local.settings.json instead. For testing purposes only to see how serivceUri works.
connection.storageAccountName = "mystorageaccountname";
connection.tableName = Environment.GetEnvironmentVariable("StorageTableName");
connection.storageTableUri = $"https://{connection.storageAccountName}.table.core.windows.net/{connection.tableName}";
connection.storageQueueUri = $"https://{connection.storageAccountName}.queue.core.windows.net/";
}
这是使用它的逻辑:
GetStorageAccountConnectionData();
var serviceClient = new TableServiceClient(new Uri(connection.storageTableUri), new DefaultAzureCredential());
var tableClient = serviceClient.GetTableClient(connection.tableName);
TableEntity origEntity = tableClient.GetEntity<TableEntity>(
ENQUEUED_PARTITION,
notification.requestId);
没有编译错误,但未写入存储table。
我目前正在尝试查看有关创建调试消息/日志的信息,因为我无法让我的本地调试环境正常工作
编辑 2
我终于设置了本地环境,以便进行调试。所以写入我的存储队列的逻辑是有效的,但是当我尝试写入存储 table 时,我现在可以看到完整的错误是什么。这是错误:
Failed to create storage record:Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. ure.
RequestId:asdf-0002-asdf-6574-asdf
Time:2022-05-10T13:45:24.6319496Z
Status: 403 (Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.)
ErrorCode: AuthenticationFailed
Content:
{"odata.error":{"code":"AuthenticationFailed","message":{"lang":"en-US","value":"Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including
is formed correctly including the signature.\nRequestId:9f775fd8-0002-002c-6574-648209000000\nTime:2022-05-10T13:45:24.6319496Z"}}}
Headers:
Server: Microsoft-HTTPAPI/2.0
x-ms-request-id: asdf-asdf-asdf-asdf
x-ms-error-code: REDACTED
Date: Tue, 10 May 2022 13:45:23 GMT
Content-Length: 299
Content-Type: application/json
还要明确一点,当我在云中测试时也会发生同样的行为。所以不管我叫
POST https://myfunctionapp.azurewebsites.net/widgets/workspaces
或
POST http://localhost:7071/widgets/workspaces
这是相同的行为。存储队列已更新,但 table.
未更新就托管 ID 而言,它现在具有以下权限:
您需要添加对这些包的引用:
您的功能应用程序将需要 Storage Account Contributor
或 Contributor
存储级别的角色(说实话不确定)。
下面是您的代码的一个片段:
var serviceClient = new TableServiceClient(
new Uri(connection.storageUri), new DefaultAzureCredential());
var tableClient = serviceClient.GetTableClient (connection.tableName);
await tableClient.CreateIfNotExistsAsync();