5

I have created a new Blazor WebAssembly App with Individual User Accounts, Store user accounts in-app and ASP.NET Core hosted in .NET 5. When deploying my app to Azure App Service I get the following error:

Object reference not set to an instance of an object.at Microsoft.Extensions.DependencyInjection.IdentityServerBuilderConfigurationExtensions

Reading these links I have to provide my own certificate in production for IdentityServer:

Blazor Web Assembly App .Net Core Hosted: publish runtime error

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

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

I then created a .pfx file like this and I have verified that it works and my password is correct.

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

I then placed the .pfx file in my Server projects root folder and marked Copy to Output Directory as Copy Always.

I then updated appsettings.json to look like this:

  "IdentityServer": {
    "Clients": {
      "BlazorTest.Client": {
        "Profile": "IdentityServerSPA"
      }
    },
    "Key": {
      "Type": "File",
      "FilePath": "localhost.pfx",
      "Password": "MySercurePassword123?"
    }
  },

Now the project does not work neither locally or on Azure. It fails on app.UseIdentityServer(); in Startup.cs with the following error:

Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing number: �. Path '', line 1, position 1.'

According to Microsoft docs my certificate should be valid:

A production certificate to use for signing tokens.

  • There are no specific requirements for this certificate; it can be a self-signed certificate or a certificate provisioned through a CA authority.
  • It can be generated through standard tools like PowerShell or OpenSSL.
  • It can be installed into the certificate store on the target machines or deployed as a .pfx file with a strong password.

https://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity-api-authorization?view=aspnetcore-5.0#deploy-to-production

If I load the key like this it works:

"Key": {
  "Type": "Store",
  "StoreName": "My",
  "StoreLocation": "CurrentUser",
  "Name": "CN=blazortest"
}
Ogglas
  • 62,132
  • 37
  • 328
  • 418
  • the error "Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing number: �. Path '', line 1, position 1.'" is typicall when your client can't reach the public discovery endpoint JSON document. are you sure that one is running? (/.well-known/openid-configuration) and it is reachable from the client? – Tore Nestenius Mar 03 '21 at 07:56
  • @ToreNestenius Yes, the exact same code works when using `"Type": "Store"` in `appsettings.json`. – Ogglas Mar 03 '21 at 08:26
  • but in deployment, you have different network topology, are sure sure the Identityserver is reachable inside Azure? If I am not wrong, you have some issues with HTTP vs HTTPS. AppServices terminate HTTPS outside , so your services only get HTTP traffic? – Tore Nestenius Mar 03 '21 at 08:35
  • @ToreNestenius I get the same error locally so I don't think that is the culprit in this case. Locally the app is set to `Enable SSL` and automatically starts with the HTTPS port as usual on localhost. On Azure I got the same error on https://mysite.azurewebsites.net. – Ogglas Mar 03 '21 at 08:55
  • Is the cert selfsigned or a real signed certificate? – Tore Nestenius Mar 03 '21 at 10:09
  • @ToreNestenius Self-signed. Created via Powershell like this: `New-SelfSignedCertificate -DnsName "blazortest" -CertStoreLocation "cert:\CurrentUser\My"` – Ogglas Mar 03 '21 at 10:26
  • You should try to get a real cert, otherwise HTTPS won't connect properly. How can otherwise your AppService in production trust it? – Tore Nestenius Mar 03 '21 at 11:50
  • 1
    @ToreNestenius I don't think that is the issue. It works on localhost and Azure if I pick up the same certificate from `Store` instead of `.pfx` `File`. Looking at what Microsoft says this should have no effect either as stated above: There are no specific requirements for this certificate; it can be a self-signed certificate or a certificate provisioned through a CA authority. It can be generated through standard tools like PowerShell or OpenSSL. It can be installed into the certificate store on the target machines or deployed as a .pfx file with a strong password. – Ogglas Mar 03 '21 at 12:14
  • but for my experience, the App it self gets the traffic as HTTP even if you use HTTPS exernally. That is common issue in Azure. also, do check the log files and I think its more a DNS/HTTPS vs HTTP issue. that the IdentitysErver is not really reachable between services. as a test, you could always try to use https://demo.identityserver.io/ instead, as a identityserver, to see if that works. – Tore Nestenius Mar 03 '21 at 14:07
  • @ToreNestenius If we assume that is the case: How come it works both locally and on Azure with the same certificate and code when the certificate is fetched from the store? That makes no sense in my experience with certificates and HTTPS. :) – Ogglas Mar 03 '21 at 14:14
  • perhaps I don't get exactly where you problem is, I was looking at the "Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing number: �. Path '', line 1, position 1.'" and that is typical a HTTP->HTTPS error. For token signing, then that is a different ballpark and question. Step #1 is to get the discovery document downloaded... I would try to dig deeper and increase the log-level to Debug or Trace in the services , to better troubleshoot it. – Tore Nestenius Mar 03 '21 at 14:33
  • @ToreNestenius Yes I think I will have to do that. Thanks for trying though! – Ogglas Mar 03 '21 at 15:36
  • Feel free to clarify your question a bit more specific details. I also personally prefer to do most of the config in code,instead of appsettings.json because then I know I don't do any stupid typo :-) – Tore Nestenius Mar 03 '21 at 15:52
  • An alternative that I have used successfully is to use Azure Container Instances instead of AppServices, because then you do all the cert stuff your self and then it is easier to debug. – Tore Nestenius Mar 03 '21 at 15:53
  • Similar problem here. When I use a .pfx file, my Blazor app just replies with a 404 Not Found error. Path to .pfx and password are correct. If I change any of them to something wrong, the error changes to HTTP Error 500.30 - ASP.NET Core app failed to start. What is wrong? – candritzky Apr 28 '21 at 11:59

3 Answers3

3

I was able to fix this problem by removing the entry for IdentityServer in appsettings.Development.json.

Remove the following lines from appsettings.Development.json:

"IdentityServer": {
     "Key": {
       "Type": "Development"
     }
   } 
Chris Berlin
  • 744
  • 6
  • 15
0

Try to upload the certificate into Azure App Service TLS/SSL Settings. Then change the Type into "Store", StoreName into "My", StoreLocation to "CurrentUser" and Name into "CN=".

Then restart the app service.

For my version, I created a self signed certificate with the help of these articles:

Here is the complete step I did (there might be some faster way but this is the raw steps i did):

  1. Open Powershell (as Admin)
  2. execute the $cert = New-SelfSignedCertificate -Subject MyAppName. You can replace the MyAppName with your own, but you need to remember it until the end of the process
  3. execute the command $cert | Format-List -Property * (not sure if this is needed)
  4. I searched the generated certificate in Manage user certificates.
  5. It turned out that I can't export it to file because it is not trusted so I moved it to the Trusted Root Certification > Certificates folder.
  6. Then when I open the certificate, the Copy To File.. in Detail tab became available so I did. (I export the file as base64 Cer file)
  7. I open the App Service Resource via Azure Portal.
  8. Navigate to TLS/SSL Settings
  9. Uploaded the .cer file in the Public Key Certificates (.cer) tab with the name MyAppName (same as what I put in the powershell command -Subject)
  10. In the appsettings.json of your app, make sure that you have the following settings:
"IdentityServer": {
  "Key": {
    "Type": "Store",
    "StoreName": "My",
    "StoreLocation": "CurrentUser",
    "Name": "CN=MyAppName"
  }
}
  1. Finally, I restarted the App Service.
VJPPaz
  • 917
  • 7
  • 21
0

For Blazor hosting with a generic provider, a development type key may still issue signing keys that change with every program restart.

A .PFX file is not an option for generic hosting because the identity server tries to persist the private key to Windows Store - not an option under shared hosting, as well as no option to directly place into Windows Store and retrieve from there.

If there is a database available, the key storage provider Microsoft.AspNetCore.DataProtection.EntityFrameworkCore is not difficult to implement. Follow the steps at Entity Framework Core Key Storage to integrate with the application.

Mike
  • 1,276
  • 4
  • 16
  • 27