У меня есть веб-задание, которому нужно создать токен JWT для связи с внешней службой. Следующий код работает, когда я запускаю WebJob на своем локальном компьютере:
public static string SignES256(byte[] p8Certificate, object header, object payload)
{
var headerString = JsonConvert.SerializeObject(header);
var payloadString = JsonConvert.SerializeObject(payload);
CngKey key = CngKey.Import(p8Certificate, CngKeyBlobFormat.Pkcs8PrivateBlob);
using (ECDsaCng dsa = new ECDsaCng(key))
{
dsa.HashAlgorithm = CngAlgorithm.Sha256;
var unsignedJwtData = Base64UrlEncoder.Encode(Encoding.UTF8.GetBytes(headerString)) + "." + Base64UrlEncoder.Encode(Encoding.UTF8.GetBytes(payloadString));
var signature = dsa.SignData(Encoding.UTF8.GetBytes(unsignedJwtData));
return unsignedJwtData + "." + Base64UrlEncoder.Encode(signature);
}
}
Однако при развертывании веб-задания в Azure я получаю следующее исключение:
Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Исключение при выполнении функции: NotificationFunctions.QueueOperation ---> System.Security.Cryptography.CryptographicException: системе не удается найти указанный файл. в System.Security.Cryptography.NCryptNative.ImportKey(поставщик SafeNCryptProviderHandle, Byte[] keyBlob, формат String) в System.Security.Cryptography.CngKey.Import(Byte[] keyBlob, формат CngKeyBlobFormat, поставщик CngProvider)
Он говорит, что не может найти указанный файл, но параметры, которые я передаю, не смотрят на местоположение файла, они находятся в памяти. Из того, что я собрал, может быть какой-то параметр криптографии, который мне нужно включить, чтобы иметь возможность использовать метод CngKey.Import, но я не могу найти какие-либо параметры на портале Azure для настройки, связанные с этим.
Я также пытался использовать JwtSecurityTokenHandler, но, похоже, он не обрабатывает алгоритм хеширования ES256, который мне нужно использовать (хотя в классе JwtAlgorithms он упоминается как ECDSA_SHA256).
Мы ценим любые предложения!
ОБНОВЛЕНИЕ
Похоже, что CngKey.Import на самом деле может пытаться сохранить сертификат где-то, недоступном в Azure. Мне не нужно его хранить, поэтому, если есть лучший способ получить доступ к сертификату в памяти или преобразовать его в сертификат другого типа, который будет проще использовать, это сработает.
ОБНОВЛЕНИЕ 2
Эта проблема может быть связана с параметром IIS Azure Web Apps, который не загружает профиль пользователя, как указано здесь. Я включил это, установив WEBSITE_LOAD_USER_PROFILE = 1 в настройках приложения портала Azure. Я пытался использовать это обновление при запуске кода как через веб-задание, так и через веб-приложение в Azure, но по-прежнему получаю ту же ошибку.