Метод Azure.Data.Tables — как перейти от использования общего ключа + Uri к управляемому идентификатору?

У меня есть функция Azure (HTTP-триггер), которая записывает данные в очередь, а также в таблицу хранения. Он работал нормально, но теперь мне нужно переместить все, чтобы использовать управляемые удостоверения.

Я смог изменить триггер HTTP, чтобы использовать переменную env __serviceUri для подключения вместо использования строки подключения. Но теперь мне нужно выяснить, как обновить мою логику, которая записывает в таблицу хранилища.

Вот соответствующий код.
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 и не вижу никаких конструкторов, которые позволяют мне использовать управляемый идентификатор.

Любая помощь будет оценена

РЕДАКТИРОВАТЬ 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);

Ошибок компиляции нет, но таблица хранилища не записывается.
В настоящее время я пытаюсь узнать о создании сообщений/журналов отладки, так как я не могу заставить свою локальную среду отладки работать.

РЕДАКТИРОВАТЬ 2

Наконец-то я настроил свою локальную среду, чтобы я мог отлаживать. Таким образом, логика, которая записывает в мою очередь хранилища, работает, но когда я пытаюсь записать в таблицу хранения, я теперь вижу, в чем заключается полная ошибка. Это ошибка:

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

это то же самое поведение. Очередь хранилища обновляется, но не таблица.

Что касается управляемого идентификатора, теперь он имеет следующие разрешения:

Метод Azure.Data.Tables — как перейти от использования общего ключа + Uri к управляемому идентификатору?

Как насчет этого: docs.microsoft.com/en-us/dotnet/api/…?

Gaurav Mantri 06.05.2022 22:12

@GauravMantri. Прохладно! Я проверю это

dot 06.05.2022 22:22

вы пытаетесь создать таблицу или получить доступ к таблице? для чтения/записи в таблицу нужны разные разрешения: Storage Table Data Contributor или Storage Table Data Reader.

Thomas 09.05.2022 22:14

оба. но у меня есть роль участника данных таблицы хранения в группе ресурсов для управляемого идентификатора. У меня также есть роль участника данных очереди хранения в группе ресурсов ... и, похоже, она работает. Я только что добавил также на уровень учетной записи хранения. но ти не работает.

dot 09.05.2022 22:21

@Thomas, пожалуйста, смотрите редактирование 2

dot 09.05.2022 22:23

распространение заданий может занять несколько минут, и вам, вероятно, также потребуется выйти из системы / снова войти в систему

Thomas 09.05.2022 22:25

Также вы говорите здесь о локальной аутентификации или использовании управляемого удостоверения, я запутался.

Thomas 09.05.2022 22:25

@ Томас, нет проблем. Основной вопрос о том, как писать в таблицу хранилища. Предоставленный вами ответ не работает для меня, но поскольку я не могу отлаживать локально, я не могу предоставить вам полезную информацию о том, почему/что не удается. Все, что я вижу, это то, что таблица НЕ заполняется вверх по течению. У меня есть отдельный вопрос о том, как пройти аутентификацию через vscode.

dot 09.05.2022 22:38

Давайте продолжить обсуждение в чате.

dot 09.05.2022 22:39

@Thomas, у меня работает локальная отладка. См. Изменить 2 сейчас, чтобы узнать о полной ошибке, когда я пытаюсь записать в учетную запись хранения, используя ваш пример кода. Пожалуйста и спасибо!

dot 10.05.2022 16:09

Удалось ли вам заставить письмо работать?

Thomas 10.05.2022 21:57
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
Как установить LAMP Stack 1/2 на Azure Linux VM
Как установить LAMP Stack 1/2 на Azure Linux VM
В дополнение к нашему предыдущему сообщению о намерении Azure прекратить поддержку Azure Database для MySQL в качестве единого сервера после 16...
0
11
49
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам нужно добавить ссылку на эти пакеты:

Вашему функциональному приложению потребуется роль Storage Account Contributor или Contributor на уровне хранилища (если честно, не уверен).

Вот фрагмент того, как может выглядеть ваш код:

var serviceClient = new TableServiceClient(
  new Uri(connection.storageUri), new DefaultAzureCredential());
var tableClient = serviceClient.GetTableClient (connection.tableName);
await tableClient.CreateIfNotExistsAsync();

k постараюсь протестировать в ближайшее время. Когда я переключаюсь на использование управляемых идентификаторов, локально ничего не работает, поэтому сначала нужно выяснить это, прежде чем я смогу это проверить. Я опубликую снова в ближайшее время. Спасибо.

dot 09.05.2022 19:10

Вы используете vs code/visual studio? вы можете войти в свою учетную запись в обоих случаях и заставить ее работать локально

Thomas 09.05.2022 21:51

Я использую vscode. вот все подробности, если поможет: stackoverflow.com/questions/72142747/…

dot 09.05.2022 21:53

Fwiw я также попытался упростить логику подключения, просто чтобы использовать жестко запрограммированные значения, потому что я не могу ничего отлаживать локально ... когда я публикую fn вверх по течению, очередь записывается с использованием управляемого идентификатора, но таблица не работает. У меня нет никаких полезных ошибок, хотя. В любом случае я попытаюсь обновить вопрос здесь с изменениями кода, чтобы информация была по крайней мере полной.

dot 09.05.2022 21:56

пожалуйста, см. Редактировать 1 для последнего кода.

dot 09.05.2022 22:05

пометка как ответ, потому что я думаю, что основная причина проблемы не связана с логикой подключения. Теперь это проблема с разрешениями. Единственное, что мне нужно было сделать, чтобы этот ответ заработал, — добавить мои AZURE_TENANT_ID, AZURE_CLIENT_ID и AZURE_CLIENT_SECRET в файл local.settings.json. Затем я смог подключиться к учетной записи хранения.

dot 10.05.2022 21:01

Другие вопросы по теме