I have built an OpenID Connect specification compliant Identity Provider authentication server. It is deployed and working well as an IP against relying parties, etc. My goal now is to create a Blazor WebAssembly Progressive Web App (or Single Page App depending on your preferred nomenclature) that uses my server for authentication.
Luckily for me Microsoft has officially released support for this scenario. So I built a simple reference implementation primarily following the guidance found here: https://learn.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/standalone-with-authentication-library?view=aspnetcore-7.0&source=recommendations&tabs=visual-studio.
Between having control over the server-side and the wonderful Developer Tools built into browsers (Chrome, Edge, etc.) I have quite a lot of helpful visibility into the system for troubleshooting.
However, I reached a point where I see my server returning a valid JWT from the token endpoint and the Blazor client fails almost silently, simply telling me "There was an error signing in".
I have tried everything I've been able to find to get some clues. I've attempted to enable additional logging, I've attempted to trace into the code. I've tried all the suggestions found on these pages:
And more. I'm pulling my hair out on this. Does anyone have any wisdom to offer on how to troubleshoot / debug into this mass of C# interoping with obfuscated JavaScript?
Well, I ended up finding a solution, so I thought I'd share. The approach I took was to replace the auto-generated, obfuscated AuthenticationService.js file provided by Microsoft with a copy that is under my control, which I then instrumented with all the logging I needed.
This is essentially an aproach I had already tried using a heavy-weight process described in one of the links I included in the question above. What I figured out is that I didn't need to plug in a complicated "client assets" solution, I could simply drop the already formed JavaScript file into my project. Here are the steps for what I did:
<script src="_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js"></script>
<!--<script src="_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js"></script>-->
<script src="src/AuthenticationService.js"></script>
Your PWA is now using exactly the same JavaScript that it was before, but it is now under your control.
For what it's worth, by adding lots of logging, I traced my specific problem to a quark with Microsoft's implementation that causes it to not know where to look for the returned token. The fix was simple. In my Blazor project Program.cs file I added the line options.ProviderOptions.ResponseMode = "query";
to my configuration. Now it looks something like this:
builder.Services.AddOidcAuthentication(options => {
// Configure our OIDC Identity Provider (for more information, see https://aka.ms/blazor-standalone-auth)
options.ProviderOptions.Authority = "{AUTHORITY_URL}";
options.ProviderOptions.ClientId = "{OIDC_CLIENT_ID}";
options.ProviderOptions.ResponseMode = "query";
. . .