#c# #azure-functions #msal
Вопрос:
У меня есть функция, запускаемая HTTP (.NET 3.1 TLS, работающая не из zip-пакета), которая подключается к моему личному OneDrive и удаляет файлы. Чтобы свести к минимуму запросы на проверку подлинности, я использовал этот подход для сериализации кэша токенов: https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-net-token-cache-serialization?tabs=custom#simple-token-cache-serialization-msal-only
На локальном хосте это отлично работает, но при запуске функции в Azure это не так хорошо — файл кэша довольно часто теряется. Я включил Path.GetTemporaryPath()
. Не уверен, какое место лучше всего подходит для этой цели. Однако кэш, похоже, привязан к компьютеру, создавшему файл: когда я использую файл кэша, созданный на моем локальном хосте и загруженный в Azure, использование такого файла показывает ошибки при получении сведений об учетной записи / перечислении.
Есть идеи, как это исправить с минимальными затратами? Мое приложение использует только один токен: для моего личного OneDrive.
Комментарии:
1. Я мало что знаю об этой теме, но в целом нам нравится, когда люди предоставляют полный список всех деталей исключения, предпочтительно с кодом, в котором оно запускается. Кроме того, переполнение стека, как правило, не будет фильтровать ответы по стоимости, так как стоимость чего-либо зависит от ряда факторов.
2. Используйте надежные функции и сохраняйте токен в надежном объекте
3. Спасибо, это может быть хорошим вариантом. Я также только что понял, что код из ссылки шифрует файл с помощью docs.microsoft.com/en-us/dotnet/api/… . Поэтому я постараюсь не шифровать его , потому что это ограничивает расшифровку одним профилем/машиной. Тогда я могу попытаться сохранить » байт[]» как прочную сущность.
4. Я протестировал его , и длительное состояние не сильно помогло 🙁 После более или менее одного часа бездействия состояние класса было очищено, и мне нужно было снова пройти аутентификацию ;-( Я попробую большой двоичный объект хранилища Azure..
5. Вы работаете в среде без сервера. Каждый вызов вашей функции потенциально выполняется на другой виртуальной машине, в результате чего любое локально сохраненное состояние теряется. Для постоянного хранилища вам следует переключиться на хранилище azure или какое-либо другое хранилище длительного хранения, например базу данных или хранилище функций длительного хранения.
Ответ №1:
Окончательное решение заключается в:
- удалите
ProtectedData
из кода из примера помощника по сериализации пользовательских токенов, поскольку он шифрует файл с текущим профилем или машиной - сохраните
args.TokenCache.DeserializeMsalV
большой двоичный объект хранилища Azure и прочитайте его позже.
Поэтому я внес изменения в код с https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-net-token-cache-serialization?tabs=custom#simple-token-cache-serialization-msal-only к следующему:
Включает сериализацию:
string cstring = System.Environment.GetEnvironmentVariable("AzureWebJobsStorage");
string containerName = System.Environment.GetEnvironmentVariable("TokenCacheStorageContainer");
try { bcc = new BlobContainerClient(cstring, containerName); } catch { }
if (!bcc.Exists())
{
bcc = (new BlobServiceClient(cstring)).CreateBlobContainerAsync(containerName).GetAwaiter().GetResult();
}
tokenCache.SetBeforeAccess(BeforeAccessNotification);
tokenCache.SetAfterAccess(AfterAccessNotification);
Перед зачислением:
lock (FileLock)
{
var blob = bcc.GetBlobClient("msalcache.bin3");
if (blob.Exists())
{
var stream = new MemoryStream();
blob.DownloadToAsync(stream).GetAwaiter().GetResult();
args.TokenCache.DeserializeMsalV3(stream.ToArray());
}
}
После зачисления:
if (args.HasStateChanged)
{
lock (FileLock)
{
// reflect changesgs in the persistent store
(bcc.GetBlobClient("msalcache.bin3")).UploadAsync(new MemoryStream(args.TokenCache.SerializeMsalV3()),true).GetAwaiter().GetResult();
}
}