8

I've created a simple Blazor Web Assembly project hosted inside a .NET Core App using .NET 5.0 RC1 Framework and I added the authorization during the wizard in Visual Studio 2019 Preview. It works perfectly in debug but if I publish it and try to connect to the server I receive a 500 error. Checking the logs the error is:

Microsoft.AspNetCore.Server.Kestrel[13]
      Connection id "0HM37MQFV38CV", Request id "0HM37MQFV38CV:00000003": An unhandled exception was thrown by the application.
      System.NullReferenceException: Object reference not set to an instance of an object.
         at Microsoft.Extensions.DependencyInjection.IdentityServerBuilderConfigurationExtensions.<>c.<AddSigningCredentials>b__10_2(IServiceProvider sp)
         at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
         at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, 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.VisitIEnumerable(IEnumerableCallSite enumerableCallSite, RuntimeResolverContext context)
         at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitNoCache(ServiceCallSite callSite, TArgument argument)
         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.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.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.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.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.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.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
         at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
         at Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions.AuthenticateAsync(HttpContext context, String scheme)
         at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
         at IdentityServer4.Hosting.BaseUrlMiddleware.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Builder.Extensions.MapWhenMiddleware.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
         at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.HandleException(HttpContext context, ExceptionDispatchInfo edi)
         at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
         at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

I think that the problem is related to the Identity Server and the certificate but I don't understand what.

Any ideas?

Thanks.

Giuseppe Terrasi
  • 328
  • 4
  • 14

2 Answers2

6

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

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

I finally solved it like this:

Created a new certificate in Powershell as Administrator:

New-SelfSignedCertificate -DnsName "blazortest" -CertStoreLocation "cert:\CurrentUser\My"

appsettings.json:

  "IdentityServer": {
    "Clients": {
      "BlazorTest.Client": {
        "Profile": "IdentityServerSPA"
      }
    },
    "Key": {
      "Type": "Store",
      "StoreName": "My",
      "StoreLocation": "CurrentUser",
      "Name": "CN=blazortest"
    }
  },

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity-api-authorization?view=aspnetcore-3.0#example-deploy-to-azure-app-service

This worked locally. I then used mmc.exe to export the certificate as a .pfx file and uploaded it via Azure App Service -> TLS/SSL settings.

enter image description here

I then used Azure Cloud Shell to enable access to the certificate like this:

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings WEBSITE_LOAD_CERTIFICATES=<comma-separated-certificate-thumbprints>

https://docs.microsoft.com/en-us/azure/app-service/configure-ssl-certificate-in-code#load-the-certificate-in-code

You can also add the Certificate Thumbprint manually by adding WEBSITE_LOAD_CERTIFICATES to Configuration:

enter image description here

Then it finally worked!

If you get an error from Azure Cloud Shell like:

ResourceGroupNotFound: Resource group '' could not be found.

Make sure you are in the right subscription and set the correct subscription with these commands:

az account show

az account list

az account set --subscription <subscriptionId>

If you host on IIS you need to import the .pfx certificate to the Personal folder for Local Computer and then select Manage Private Keys... and give access to the user running the Application Pool.

enter image description here

Ogglas
  • 38,157
  • 20
  • 203
  • 266
  • Thanks for this useful answer. How do I get it working using shared hosting server with LetsEncrypt certificate. I am publishing application using web deploy and having Plesk control panel to access hosting server. I am getting error "non-JS module files deprecated" after publish. If possible please share LetsEncrypt Key setting. – Brijesh Kumar Tripathi May 12 '21 at 12:34
  • @BrijeshKumarTripathi Thanks! You need an `App Service plan` on at least `B1` to use `Custom domains / SSL`. When you have it use `Let's Encrypt Site Extension` to get automatic updates. https://github.com/sjkp/letsencrypt-siteextension/wiki/How-to-install – Ogglas May 12 '21 at 12:45
  • Thanks for your quick response. I am not hosting it on azure. I am hosting it on another hosting service provider and I have LetsEncrypt certificate for my website. I want to know if I explicitly need to configure it in appsettings.json. My application is a Blazor Webassembly hosted application with Identity and the .NET version is .NET 5. – Brijesh Kumar Tripathi May 12 '21 at 12:54
  • @BrijeshKumarTripathi No problem! Nope - `Let's Encrypt` is only for HTTPS and has nothing to do with `IdentityServer` or your `appsettings.json`. – Ogglas May 12 '21 at 13:13
  • It means I don't have to provide settings in appsettings.json to get LetsEncrypt certificate working in production environment. Please correct me if I am wrong. – Brijesh Kumar Tripathi May 12 '21 at 13:24
  • @BrijeshKumarTripathi Correct, `Let's Encrypt` is on server level for HTTPS. – Ogglas May 12 '21 at 13:28
  • Thanks for your great help, I am getting "crbug/1173575, non-JS module files deprecated." error when trying to run my application after publishing it even in local folder but after applying the "Key" setting as suggested by you it is working fine from local folder publish. I am using same "blazortest" to run my folder publish but please suggest how to run it on server with LetsEncrypt certificate. – Brijesh Kumar Tripathi May 12 '21 at 13:50
1

Ok, I've solved using thi question/answers

In production it is necessary to use a certificate, so I've created a self-signed one and added its path to the appsettings.json.

Giuseppe Terrasi
  • 328
  • 4
  • 14