【发布时间】:2017-04-11 15:16:45
【问题描述】:
我有一个需要创建 JWT 令牌以与外部服务通信的 WebJob。当我在本地计算机上运行 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);
}
}
但是,当我将 WebJob 部署到 Azure 时,出现以下异常:
Microsoft.Azure.WebJobs.Host.FunctionInvocationException:执行函数时出现异常:NotificationFunctions.QueueOperation ---> System.Security.Cryptography.CryptographicException:系统找不到指定的文件。在 System.Security.Cryptography.NCryptNative.ImportKey(SafeNCryptProviderHandle provider, Byte[] keyBlob, String format) at System.Security.Cryptography.CngKey.Import(Byte[] keyBlob, CngKeyBlobFormat format, CngProvider provider)
它说找不到指定的文件,但是我传入的参数不是在查看文件位置,而是在内存中。根据我收集到的信息,我可能需要启用某种加密设置才能使用 CngKey.Import 方法,但我在 Azure 门户中找不到与此相关的任何设置。
我也尝试过使用 JwtSecurityTokenHandler,但它似乎无法处理我需要使用的 ES256 哈希算法(即使它在 JwtAlgorithms 类中被引用为 ECDSA_SHA256)。
任何建议将不胜感激!
更新
似乎 CngKey.Import 实际上可能试图将证书存储在 Azure 上无法访问的某个位置。我不需要存储它,所以如果有更好的方法来访问内存中的证书或将其转换为更容易使用的不同类型的证书。
更新 2
此问题可能与 Azure Web Apps IIS 设置未加载用户配置文件有关,如 here 所述。我通过在 Azure 门户应用程序设置中设置 WEBSITE_LOAD_USER_PROFILE = 1 来启用此功能。我在通过 Azure 中的 WebJob 和 Web 应用程序运行代码时尝试了此更新,但我仍然收到相同的错误。
【问题讨论】:
-
如果您尝试在您的开发机器上本地运行它是否会显示相同的错误?
-
不,在我的机器上本地运行它作为 WebJob 工作正常,没有抛出异常。
-
您的证书是从哪里导入的?我的意思是在 Azure 上
-
证书是一个 Pkcs8 文件,我目前在我的 web.config 中只是一个 base64 字符串(也许不是最好的地方)并将它加载到一个字节数组中。它是传递给方法的“p8Certificate”变量。
标签: azure azure-webjobs