22

I am using IdentityServer4 with React start project from ASP.NET Core 3.0. preview 4 and it works perfectly until I build the solution and try to run it from cmd prompt using the dotnet command. Everytime I start the application, it tells me that the key type is not specified.

I have tried various guides on generating certificates because I do not have any experience with certificates in .NET. I am mentioning this in case that the issue could be caused by an incorrect way of generating a certificate.

I have also tried to add the key type to the Appsettings.json, but I do not know what the type could be. I have been Google'ing all day for documentation on how to configure IdentityServer4 for deployment, but nobody seems to be having this issue or need any help generating the correct certificate.

I can run the application in Visual Studio, as long as I specify that it's a development environment.

When I switch to production or build the solution and run it from command prompt, the following stacktrace occurs:

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

If anybody can save me from this situation, I would be very grateful.

This is my first post, so if any more information is required, please feel free to ask me.

Antheus_S
  • 370
  • 1
  • 2
  • 12

5 Answers5

12

If you want to use *.pfx

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

And read this thread if you have this error WindowsCryptographicException: Keyset does not exist

internal.cryptography.cryptothrowhelper+windowscryptographicexception keyset does not exist
  • 5
    To future readers, place the `.pfx` file in the root of your project, you can create it [like this](https://stackoverflow.com/a/14267011/812919) and then have it included in your build folder [like this](https://stackoverflow.com/a/44378406/812919). – olfek Oct 05 '19 at 20:36
  • 2
    Where did you learn about this setting? Its super helpful for dev environments and I have not seen it in any official IS documentation. – Dan May 28 '20 at 16:48
6

So I was able to solve my issues using this piece of documentation: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity-api-authorization?view=aspnetcore-3.0#example-deploy-to-azure-websites

I had to enable "Copy if newer" to the appsettings.json properties so that it would get copied to the build folder.

I also added the following to the appsettings.json file:

"IdentityServer": {
"Clients": {
  "Client": {
    "Profile": "IdentityServerSPA"
  }
},
"Key": {
  "Type": "Store",
  "StoreName": "My",
  "StoreLocation": "LocalMachine",
  "Name": "CN=SigningCertificate"
}
}

Now the Key.Type is specified, which means that we can now just add the following to the startup.cs:

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

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

I still do not understand why other people are not experiencing this issue, since I am not able to find any other threads on this issue and the regular way seems to work for everyone else. The only downside to this is that I need to install the certificate on the machine now instead of getting it as file.

Antheus_S
  • 370
  • 1
  • 2
  • 12
  • I tried your answer with docker I got this log `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 Jun 24 '19 at 08:28
  • I am not that familiar with Linux, but it seems like you are unable to access the LocalMachine store. For Linux images, I added the certificate to the CurrentUser store and changed my appsettings for the key description to this: "Key": { "Type": "Store", "StoreName": "My", "StoreLocation": "CurrentUser", "Name": "CN=CodellicSigningCertificate" } – Antheus_S Jun 25 '19 at 09:51
  • Thanks for your support but can you help me to use key type `file`. I have self-signed certificated `.pfx` but I can't find any documentation to add it in the appsettings.json – Shady Mohamed Sherif Jun 25 '19 at 11:11
  • Sorry, since I only use Windows servers, I usually add it to the store with Windows MMC. So I cannot really help you, maybe there are others that add a certificate to the store from within the application. – Antheus_S Jun 25 '19 at 15:12
  • When you say you had to enable "copy if newer," where did you do that? – user Jul 18 '19 at 20:38
  • I clicked on the certificate file in Visual Studio, opened the Properties tab and set it to "copy if newer" for the "Copy to Output Directory" property. – Antheus_S Jul 19 '19 at 19:13
  • `if (!Environment.IsDevelopment()) identityBuilder.AddSigningCredentials();` is unecessary as `identityBuilder.AddApiAuthorization();` already makes a call to `AddSigningCredentials()` – Richard Sep 29 '19 at 05:55
  • If I read my cert's subject using a console app, I get CN=app.mydomainname.com, OU=PositiveSSL, OU=Domain Control Validated. If I use it as-is in Key -> Name setting for web app, I get the error mentioned in question. Is there any workaround? Using cert file works. But it is a security risk for prod. – frosty Nov 26 '19 at 07:06
  • @frosty The subject name I'm getting is "CN=website.com, OU=Domain Control Validated". IS is unable to find a certificate using this. Did you find a workaround? – tmutton May 04 '20 at 21:19
4

Here is how I solved it in Docker for Blazor WebAssembly. My answer is mostly based on this thread. Keep in mind that, although it works, it may not be production-ready, nor safe. I know little about IdentityServer.

appsettings.json:

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

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

FilePath is where you physically placed your certificate (generated in next step of this answer). Password is being configured while generating certificate.

Generating certificate:

Source. This might not be production-ready either.

$ 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

Keep in mind that certificate will expire (-days attribute in 2nd command).

Working with Docker

There are some answers advising to include certificate in build folder or keep it with project source code. I personally don't think it's a good idea. I'm generating certificates manually on my server in separated folder, then I'm creating Docker volume pointing to folder where I placed them.

Piotrek
  • 10,919
  • 18
  • 73
  • 136
2

Beside the accepted answer, In case if someone wants to create their own SigningCredentials using the AsymmetricSecurityKey instead of the 'Key' configuration in appsettings.json, the following can also solve the problem.

  1. First define the RSA params in the xml file or store in the Application Resource file: e.g (working sample),
<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>
  1. Then, we can read the params using the RSA helper method to create the AsymmetricSecurityKey. I have created the following helper class for my project:
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);
        }
    }
  1. Modify the Startup.cs class and use the above helper class to generate the SigningCredentials. e.g.,
// configure IDS
 services.AddIdentityServer(options =>
            {
                // ...

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

Note that if you are wondering about a working example, i have recently used it in a demo project which is up and running and Azure at the moment. Here is the startup file and here is the complete project.

Shahid
  • 17
  • 4
0

When using a .pfx file I got the following error:

Blazor - app.UseIdentityServer(); with .pfx key file - Unexpected character encountered while parsing number

I also had to enable my Azure App Service to access the certificate via Azure Cloud Shell. Complete guide here to avoid copied answers:

https://stackoverflow.com/a/66448397/3850405

Ogglas
  • 62,132
  • 37
  • 328
  • 418