WindowsCryptographicException:在 Azure 中发布应用程序时拒绝访问

问题描述

我有一个基于 Aridka OpenIddict 示例的非常简单的 Web 应用程序,当涉及到授权控制器和启动类时,它几乎是它的副本,在返回的资源类型方面存在一些差异,但是令牌机制与示例完全相同。

该应用程序在我的开发环境中运行良好(数据库在 Azure 中,但该应用程序在我的机器上运行)。但是,我已将它发布到 Azure 只是为了查看它在云提供商中托管后是否仍然有效,并且它实际上返回了错误并且没有启动。这是堆栈跟踪:

Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Access is denied.
   at Internal.Cryptography.Pal.StorePal.FromSystemStore(String storeName,StoreLocation storeLocation,OpenFlags openFlags)
   at System.Security.Cryptography.X509Certificates.X509Store.Open(OpenFlags flags)
   at Microsoft.Extensions.DependencyInjection.OpenIddictServerBuilder.AddDevelopmentEncryptionCertificate(X500distinguishedname subject)
   at Microsoft.Extensions.DependencyInjection.OpenIddictServerBuilder.AddDevelopmentEncryptionCertificate()
   at MyApp.Api.Startup.<>c.<ConfigureServices>b__4_4(OpenIddictServerBuilder options) in C:\Users\edm\OneDrive\MyAp\1\1\MyApp.Api\Startup.cs:line 75
   at Microsoft.Extensions.DependencyInjection.OpenIddictServerExtensions.AddServer(OpenIddictBuilder builder,Action`1 configuration)
   at MyApp.Api.Startup.ConfigureServices(IServiceCollection services) in C:\Users\edm\OneDrive\MyApp\1\1\MyApp.Api\Startup.cs:line 54
   at System.RuntimeMethodHandle.InvokeMethod(Object target,Object[] arguments,Signature sig,Boolean constructor,Boolean wrapExceptions)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj,BindingFlags invokeAttr,Binder binder,Object[] parameters,CultureInfo culture)
   at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.InvokeCore(Object instance,IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.<>c__displayClass9_0.<Invoke>g__Startup|0(IServiceCollection serviceCollection)
   at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.Invoke(Object instance,IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.<>c__displayClass8_0.<Build>b__0(IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.GenericWebHostBuilder.UseStartup(Type startupType,HostBuilderContext context,IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.GenericWebHostBuilder.<>c__displayClass12_0.<UseStartup>b__0(HostBuilderContext context,IServiceCollection services)
   at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
   at Microsoft.Extensions.Hosting.HostBuilder.Build()
   at MyApp.Api.Program.Main(String[] args) in C:\Users\edm\OneDrive\MyApp\1\1\MyApp.Api\Program.cs:line 16

我非常感谢任何帮助。我是 OpenId 的新手,所以如果这是一个太基本的问题并且我应该先阅读其他资源,请不要犹豫分享参考资料。

谢谢!

埃德

解决方法

  1. 在门户上添加应用程序设置 WEBSITE_LOAD_USER_PROFILE=1

    如果不行,试试第二种方法。

  2. 向您的网络应用添加证书。

    Upload certificate to App Service

,

非常感谢所有参考资料。我继续调查。在[我之前分享的链接][1] 中,OpenIddict 的主要贡献者 Kevin Chalet 明确提到在证书方面不要使用示例代码,并建议创建我们自己的。

多亏了 Pluralsight 的 Troy Hunt 课程,我学会了如何使用 Powershell 创建自签名证书。有趣的是,杰森在他的评论中指出了我的同一个方向(@杰森,非常感谢,我还不能给你点赞,因为我没有足够的声望/积分,但我会在被允许的情况下)。

这里是怎么做的,供参考:

PS> New-SelfSignedCertificate -certstorelocation cert:\localmachine\my -dnsname example.mysite.com

执行此操作时,它将输出指纹和我们证书的主题。

PS> $pwd = ConvertTo-SecureString -String "WHATEVERPASSWORDYOUWANT" -Force -AsPlainText

您定义 $pwd 变量,我们将使用此命令导出证书:

PS> Export-PfxCertificate -cert cert:\localMachine\my\THE_THUMBPRINT_YOU_GOT_EARLIER -FilePath "YOUR_PATH\cert.pfx" -Password $pwd

然后我可以按照 Jason 上面的回答将该证书上传到应用服务,然后在我的代码中我必须通过更改默认值来更改我的 Startup 类

options.AddDevelopmentEncryptionCertificate().AddDevelopmentSigningCertificate();

options.AddEncryptionCertificate("THE_THUMBPRINT_YOU_GOT_EARLIER").AddSigningCertificate("THE_THUMBPRINT_YOU_GOT_EARLIER");

最后要做的是将此应用程序设置添加到 Azure 应用程序:

WEBSITE_LOAD_CERTIFICATES 以上面的指纹作为值。

注意:为了能够将私有证书 (pfx) 上传到 Azure,您的应用服务计划中至少需要有基本层。

谢谢大家 [1]:https://github.com/openiddict/openiddict-core/issues/976