在生产环境中IdentityServer4无法工作

22
我在使用IdentityServer4和React启动项目时,使用的是ASP.NET Core 3.0预览版4。一切正常,直到我构建解决方案并在命令提示符中使用dotnet命令运行应用程序时,它告诉我未指定密钥类型。
我尝试过各种生成证书的指南,因为我在.NET中没有任何关于证书的经验。我提到这点是因为问题可能是由于生成证书的不正确方式引起的。
我还尝试将密钥类型添加到Appsettings.json中,但我不知道类型是什么。我已经通过谷歌搜索了整天,寻找有关如何配置IdentityServer4以进行部署的文档,但是似乎没有人遇到此问题,也没有任何帮助生成正确证书的需求。
只要我指定它是开发环境,我就可以在Visual Studio中运行应用程序。
当我切换到生产环境或者构建解决方案并从命令提示符中运行时,会出现以下的堆栈跟踪:
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
      User profile is available. Using 'C:\Users\username\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
info: IdentityServer4.Startup[0]
      Starting IdentityServer4 version 3.0.0.0
info: Microsoft.Extensions.DependencyInjection.ConfigureApiResources[0]
      Configuring local API resource 'Codellic.WebAPI'.
Application startup exception: System.InvalidOperationException: Key type not specified.
   at Microsoft.AspNetCore.ApiAuthorization.IdentityServer.ConfigureSigningCredentials.LoadKey()
   at Microsoft.AspNetCore.ApiAuthorization.IdentityServer.ConfigureSigningCredentials.Configure(ApiAuthorizationOptions options)
   at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
   at Microsoft.Extensions.Options.OptionsManager`1.<>c__DisplayClass5_0.<Get>b__0()
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.get_Value()
   at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
   at Microsoft.Extensions.Options.OptionsManager`1.Get(String name)
   at Microsoft.Extensions.Options.OptionsManager`1.get_Value()
   at Microsoft.Extensions.DependencyInjection.IdentityServerBuilderConfigurationExtensions.<>c.<AddClients>b__7_1(IServiceProvider sp)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite scopedCallSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.AspNetCore.Builder.IdentityServerApplicationBuilderExtensions.TestService(IServiceProvider serviceProvider, Type service, ILogger logger, String message, Boolean doThrow)
   at Microsoft.AspNetCore.Builder.IdentityServerApplicationBuilderExtensions.Validate(IApplicationBuilder app)
   at Microsoft.AspNetCore.Builder.IdentityServerApplicationBuilderExtensions.UseIdentityServer(IApplicationBuilder app)
   at Codellic.Startup.Configure(IApplicationBuilder app) in A:\ProjectFolder\Startup.cs:line 79
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Hosting.Internal.ConventionBasedStartup.Configure(IApplicationBuilder app)
   at Microsoft.AspNetCore.Mvc.Filters.MiddlewareFilterBuilderStartupFilter.<>c__DisplayClass0_0.<Configure>g__MiddlewareFilterBuilder|0(IApplicationBuilder builder)
   at Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder app)
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
crit: Microsoft.AspNetCore.Hosting.Internal.WebHost[6]
      Application startup exception
System.InvalidOperationException: Key type not specified.
   at Microsoft.AspNetCore.ApiAuthorization.IdentityServer.ConfigureSigningCredentials.LoadKey()
   at Microsoft.AspNetCore.ApiAuthorization.IdentityServer.ConfigureSigningCredentials.Configure(ApiAuthorizationOptions options)
   at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
   at Microsoft.Extensions.Options.OptionsManager`1.<>c__DisplayClass5_0.<Get>b__0()
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.get_Value()
   at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
   at Microsoft.Extensions.Options.OptionsManager`1.Get(String name)
   at Microsoft.Extensions.Options.OptionsManager`1.get_Value()
   at Microsoft.Extensions.DependencyInjection.IdentityServerBuilderConfigurationExtensions.<>c.<AddClients>b__7_1(IServiceProvider sp)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite scopedCallSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.AspNetCore.Builder.IdentityServerApplicationBuilderExtensions.TestService(IServiceProvider serviceProvider, Type service, ILogger logger, String message, Boolean doThrow)
   at Microsoft.AspNetCore.Builder.IdentityServerApplicationBuilderExtensions.Validate(IApplicationBuilder app)
   at Microsoft.AspNetCore.Builder.IdentityServerApplicationBuilderExtensions.UseIdentityServer(IApplicationBuilder app)
   at Codellic.Startup.Configure(IApplicationBuilder app) in A:\ProjectFolder\Startup.cs:line 79
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Hosting.Internal.ConventionBasedStartup.Configure(IApplicationBuilder app)
   at Microsoft.AspNetCore.Mvc.Filters.MiddlewareFilterBuilderStartupFilter.<>c__DisplayClass0_0.<Configure>g__MiddlewareFilterBuilder|0(IApplicationBuilder builder)
   at Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder app)
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()

Unhandled Exception: System.InvalidOperationException: Key type not specified.
   at Microsoft.AspNetCore.ApiAuthorization.IdentityServer.ConfigureSigningCredentials.LoadKey()
   at Microsoft.AspNetCore.ApiAuthorization.IdentityServer.ConfigureSigningCredentials.Configure(ApiAuthorizationOptions options)
   at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
   at Microsoft.Extensions.Options.OptionsManager`1.<>c__DisplayClass5_0.<Get>b__0()
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.get_Value()
   at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
   at Microsoft.Extensions.Options.OptionsManager`1.Get(String name)
   at Microsoft.Extensions.Options.OptionsManager`1.get_Value()
   at Microsoft.Extensions.DependencyInjection.IdentityServerBuilderConfigurationExtensions.<>c.<AddClients>b__7_1(IServiceProvider sp)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite scopedCallSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.AspNetCore.Builder.IdentityServerApplicationBuilderExtensions.TestService(IServiceProvider serviceProvider, Type service, ILogger logger, String message, Boolean doThrow)
   at Microsoft.AspNetCore.Builder.IdentityServerApplicationBuilderExtensions.Validate(IApplicationBuilder app)
   at Microsoft.AspNetCore.Builder.IdentityServerApplicationBuilderExtensions.UseIdentityServer(IApplicationBuilder app)
   at Codellic.Startup.Configure(IApplicationBuilder app) in A:\ProjectFolder\Startup.cs:line 79
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Hosting.Internal.ConventionBasedStartup.Configure(IApplicationBuilder app)
   at Microsoft.AspNetCore.Mvc.Filters.MiddlewareFilterBuilderStartupFilter.<>c__DisplayClass0_0.<Configure>g__MiddlewareFilterBuilder|0(IApplicationBuilder builder)
   at Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder app)
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.StartAsync(CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String startupMessage)
   at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String startupMessage)
   at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token)
   at Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host)
   at Codellic.Program.Main(String[] args) in A:\ProjectFolder\Program.cs:line 16

如果有人能够帮我脱离这个困境,我将非常感激。

这是我的第一篇帖子,如果需要更多信息,请随时询问我。


1
请发布您用于添加签名凭据的代码。 - Vidmantas Blazevicius
我已经发布了一个答案,解释了我是如何解决这个问题的。再次感谢您的帮助。 :-) - Antheus_S
5个回答

12

如果您想使用*.pfx

"Key": {
  "Type": "File",
  "FilePath": "certificate.pfx",
  "Password": "password:!"
}

如果你遇到了这个错误,请阅读此线程 WindowsCryptographicException: Keyset does not exist

internal.cryptography.cryptothrowhelper+windowscryptographicexception keyset does not exist

5
给未来的读者,将.pfx文件放在您的项目根目录中,您可以按照这里的方式创建它,然后将其包含在您的构建文件夹中,例如这样 - olfek
2
你从哪里了解到这个设置的?它对于开发环境非常有帮助,我在任何官方的 IS 文档中都没有看到过。 - Dan

6
所以我成功解决了我的问题,使用了这份文档:https://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity-api-authorization?view=aspnetcore-3.0#example-deploy-to-azure-websites 我需要在 appsettings.json 属性中启用 "Copy if newer",以便它能够被复制到构建文件夹中。
我还在 appsettings.json 文件中添加了以下内容:
"IdentityServer": {
"Clients": {
  "Client": {
    "Profile": "IdentityServerSPA"
  }
},
"Key": {
  "Type": "Store",
  "StoreName": "My",
  "StoreLocation": "LocalMachine",
  "Name": "CN=SigningCertificate"
}
}

现在指定了Key.Type,这意味着我们现在只需将以下内容添加到startup.cs中:

// Configure IdentityServer4
var identityBuilder = services.AddIdentityServer();
identityBuilder.AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

if (!Environment.IsDevelopment())
     identityBuilder.AddSigningCredentials();

我仍然不明白为什么其他人没有遇到这个问题,因为我找不到任何关于这个问题的其他帖子,而且常规方法似乎对其他人都有效。唯一的缺点是现在我需要在机器上安装证书,而不是将其作为文件获取。


我尝试使用Docker运行您的答案,但是我得到了以下日志:Application startup exception: System.Security.Cryptography.CryptographicException: Unix LocalMachine X509Store is limited to the Root and CertificateAuthority stores. ---> System.PlatformNotSupportedException: Unix LocalMachine X509Store is limited to the Root and CertificateAuthority stores. - Shady Mohamed Sherif
当你说你必须启用“仅在更新时复制”时,你是在哪里进行的操作? - user
if (!Environment.IsDevelopment()) identityBuilder.AddSigningCredentials(); is unecessary as identityBuilder.AddApiAuthorization<ApplicationUser, ApplicationDbContext>(); already makes a call to AddSigningCredentials() - Richard
如果我在控制台应用程序中读取我的证书主题,我会得到CN=app.mydomainname.com,OU=PositiveSSL,OU=Domain Control Validated。如果我将其原封不动地用作Web应用程序中的Key -> Name设置,我会得到问题中提到的错误。有什么解决方法吗?使用证书文件可以解决问题。但是对于生产环境来说,这是一种安全风险。 - frosty
@frosty,我得到的主题名称是“CN=website.com, OU=Domain Control Validated”。IS无法使用此找到证书。你找到了解决方法吗? - tmutton
显示剩余4条评论

4
这是我在Docker for Blazor WebAssembly中解决它的方法。我的答案主要基于this thread。请注意,尽管它可以工作,但可能不适用于生产环境,也不安全。我对IdentityServer的了解很少。

appsettings.json:

"IdentityServer": {
    //[...]

    "Key": {
      "Type": "File",
      "FilePath": "/path_to_certificate_here/server.pfx",
      "Password": "password_specified_later"
    }
  }

FilePath 是您实际放置证书的位置(在本答案的下一步中生成)。Password 在生成证书时进行配置。

生成证书:

。这也可能不是生产就绪的。

$ openssl genrsa 2048 > server_private.pem
$ openssl req -x509 -days 1000 -new -key server_private.pem -out server_public.pem
$ openssl pkcs12 -export -in server_public.pem -inkey server_private.pem -out server.pfx

请记住,证书将会在第二个命令中的 -days 属性过期。

使用Docker

有一些答案建议将证书包含在 build 文件夹中或与项目源代码一起保存。我个人认为这不是一个好主意。我在我的服务器上手动生成证书,并在分离的文件夹中创建 Docker 卷,然后将其指向放置证书的文件夹。

2
除了已接受的答案外,如果有人想使用AsymmetricSecurityKey创建自己的SigningCredentials,而不是在appsettings.json中使用“Key”配置,则以下内容也可以解决问题。
  1. 首先在xml文件中定义RSA参数或存储在应用程序资源文件中:例如(工作示例),
<RSAKeyValue>
    <Modulus>9+hZCiZrVpqe1t+Q4HOfzrmmkNkNPurX3btOva9Hdx1lIKV7ndeVGCq71plXhW78krXdcDSSeOEVf8W51/Qq0ai8Rg9P1XIcedVgIj7MiHZ+k/rcnq1Y9yg6d1DHXtlAJLasvhCc3o+9inXh2DAzllIxyy4FabS51dRyWDBMA2LS8kS3o5UdcVQYoY+B/9d8qVHmlbQNuao3NL/UqVo6UKnGidSjTQMyPkPJEmpul9C3Cn8Tm7zqKidk2A/obU5bmBFfivhPGoFnahYMs635LpitEPdJGQCfzcmLyE9y23cPyPzowkB/zsONCgWoxglst95vKRWgyXgBXAiSbKtaFQ==</Modulus>
    <Exponent>AQAB</Exponent>
    <P>/dJVFnxsOJsSZpeK698QH7x/j9UeLlYrWuRsC6BTyPs/YE+aWiZpRkjz6uZcgkCeNVwxU8IdGukyrt87dcgrwuE/QM02ZqINZ65rGXR2/GA9WwmMD+Sf89q10emNURtquP2hF7mE8j224rsNv7+c7VPJmQ5VaXbDyeTYdea4pm8=</P>
    <Q>+gkFmWWeWgh1LWJVzzxX0nr8ebQWwut/ca9dnyQf2QeSmVnc+BpFSTJoaUp4TmCkVrDOxVszvUHA7jOQrUHxmHUJ5QCxM/hVN34iVKj5Ic3vZJAMeqc2bsmeFwlKRrXMNSHiju5bQnWymO72Y7T9Ldkqvjke43adto25eEH+Kbs=</Q>
    <DP>y1N5a9jiDHpUxDAzTf3TecjTWtH7Kl1Gv7npv2qAk6iIvUsnN347qNz54DsG8iR3WAFxVkpSbGNQgXs7s39VZvhvZia9pHu+R0cWbj64rjUeEVZVh8m6RGr4aZ4w4T8YP/aU3F9122OKpJf5TJhfSlJrVRuBWkmUT5/tsozPcCs=</DP>
    <DQ>PcSIy5JdAiTgvatzQ1TG5UpYoMAqd1CyFSWbXTsRWw4R2yxl+CyVPTXksU4iVkptjrTy/7I+H9zkinPWo9aMlnsjTJ1VKV+JvcG9PWjY0s8K+q7TRmGUgt3v3gT/gmRa5C1QyLp9dPeafUlbONp3SSJC+ucliE+/Ol/cl6bF4Q0=</DQ>
    <InverseQ>zNXj2pFcx1w+pZqzGCbAwlWDUDd2BtK9t5dTYMTHMCXUCizb0Jiai9cdH6kstoqM4TkL8KTEl3sA6RCm5qpgBPMAT18F6VPzXFUErDtkOGwIuifid3L+CBQ1fjoBZqdC8LfAen3LT5wVn0p6lMouWoAX/NRJnjQGsO/LOHQVJjk=</InverseQ>
    <D>1CJujtDxaNpGsXf9cRN/3FXgwnH5c61hqsttRcOHU9ZDgvwYG6kuW8+1jJ0K15NxbdlR84IJFIcG7p8zuCenvGC3Ovw/RFaxJ0//Q06ZluxOxDIWN3H+fwBdh1wIPpGI4eGvT7THh2tYtfLJn0Uf37HWChcHarzLiL6SWgR6ByoKUEFTAbqbrB8mJJbaev83aNGopdjfc4+MntAGaWkpSvMuzY8Mm5CQ9lc5HQ/6a9Cb2O+fSi8P92FHwPWNIqP7pE7BmZeB3WB52K3fhpDHpkS0n0DjrchHLgMLo788IDlglLS+a/OaUX1xAMZMXrLzA/vtE5YJPHvFNAHh7oSCwQ==</D>
</RSAKeyValue>

然后,我们可以使用RSA辅助方法读取参数,创建AsymmetricSecurityKey。我为我的项目创建了以下辅助类:
using System.Security.Cryptography;
public static class MyKeyStore
    {
        public static AsymmetricSecurityKey Key;

        static MyKeyStore()
        {
            var props = RSA.Create();
            props.FromXmlString(Resources.RsaProps);
            Key = new RsaSecurityKey(props);
        }
    }

修改 Startup.cs 类,并使用上述辅助类生成 SigningCredentials。例如:
// configure IDS
 services.AddIdentityServer(options =>
            {
                // ...

            }).AddApiAuthorization<ApplicationUser, ApplicationDbContext>
            (options => { options.SigningCredential = new SigningCredentials(MyKeyStore.Key, SecurityAlgorithms.RsaSha512);});


请注意,如果您想了解一个工作示例,我最近在一个演示项目中使用了它,该项目目前正在Azure上运行。这里是启动文件,这里是完整的项目。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接