Blazor WebAssembly - Exception in AuthenticationService.js

282 views Asked by At

I am implementing OICD authentication into a blazor hosted application using OpenIddict and the default identity UI. Upon starting my application I receive the following error in AuthenticationService.js:

Unhandled exception rendering component: Cannot read properties of undefined (reading 'getUser') TypeError: Cannot read properties of undefined (reading 'getUser') at c.getUser (https://localhost:7111/_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js:2:289968) at https://localhost:7111/_framework/blazor.webassembly.js:1:3337 at new Promise () at Object.beginInvokeJSFromDotNet (https://localhost:7111/_framework/blazor.webassembly.js:1:3311) at Object.Gt [as invokeJSFromDotNet] (https://localhost:7111/_framework/blazor.webassembly.js:1:62569) at Object.Ii (https://localhost:7111/_framework/dotnet.7.0.9.spglg51993.js:5:71974) at _mono_wasm_invoke_js_blazor (https://localhost:7111/_framework/dotnet.7.0.9.spglg51993.js:14:103886) at wasm://wasm/0099327a:wasm-function[313]:0x1d6b6 at wasm://wasm/0099327a:wasm-function[283]:0x1cae4 at wasm://wasm/0099327a:wasm-function[221]:0xe1d4 Microsoft.JSInterop.JSException: Cannot read properties of undefined (reading 'getUser') TypeError: Cannot read properties of undefined (reading 'getUser') at c.getUser (https://localhost:7111/_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js:2:289968) at https://localhost:7111/_framework/blazor.webassembly.js:1:3337 at new Promise () at Object.beginInvokeJSFromDotNet (https://localhost:7111/_framework/blazor.webassembly.js:1:3311) at Object.Gt [as invokeJSFromDotNet] (https://localhost:7111/_framework/blazor.webassembly.js:1:62569) at Object.Ii (https://localhost:7111/_framework/dotnet.7.0.9.spglg51993.js:5:71974) at _mono_wasm_invoke_js_blazor (https://localhost:7111/_framework/dotnet.7.0.9.spglg51993.js:14:103886) at wasm://wasm/0099327a:wasm-function[313]:0x1d6b6 at wasm://wasm/0099327a:wasm-function[283]:0x1cae4 at wasm://wasm/0099327a:wasm-function[221]:0xe1d4 at Microsoft.JSInterop.JSRuntime.d__161[[Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteUserAccount, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].MoveNext() at Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticationService3.d__28[[Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticationState, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteUserAccount, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Microsoft.AspNetCore.Components.WebAssembly.Authentication.OidcProviderOptions, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].MoveNext() at Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticationService3.<GetUser>d__27[[Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticationState, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteUserAccount, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Microsoft.AspNetCore.Components.WebAssembly.Authentication.OidcProviderOptions, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].MoveNext() at Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticationService3.d__19[[Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticationState, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteUserAccount, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Microsoft.AspNetCore.Components.WebAssembly.Authentication.OidcProviderOptions, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].MoveNext() at Microsoft.AspNetCore.Components.Authorization.AuthorizeViewCore.OnParametersSetAsync() at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task) at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync() at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)

  1. I checked up the configuration of OpenIddict multiple times (made sure that the ClientId matches in each configuration)
  2. I checked all my nuget packages and dependencies, so that the correct versions are installed.
  3. I checked my local .NET sdk installations.
  4. I tried downgrading my Microsoft.AspNetCore.Components.WebAssembly nuget package (and all other dependent microsoft packages) that is utilizing the AuthenticationService.js file.
  5. I checked older projects which are using Openiddict for authorization and made sure that I'm not missing something.
  6. I made sure that my AuthorizationController is set up correctly, but the code doesn't even reach it because the error message is thrown before.

I create my openiddict manager like the following in my server project:

        var client = await manager.FindByClientIdAsync("blazorhosted-webclient", cancellationToken);
        // Configure OpenIddict for authentication
        if (client is null)
        {
            await manager.CreateAsync(new OpenIddictApplicationDescriptor
            {
                ClientId = "blazorhosted-webclient",
                ConsentType = OpenIddictConstants.ConsentTypes.Explicit,
                DisplayName = "MetaProcessor",
                Type = OpenIddictConstants.ClientTypes.Public,
                PostLogoutRedirectUris =
                {
                    new Uri($"{baseURL}/authentication/logout-callback")
                },
                RedirectUris =
                {
                    new Uri($"{baseURL}/authentication/login-callback")
                },
                Permissions =
                {
                    OpenIddictConstants.Permissions.Endpoints.Authorization,
                    OpenIddictConstants.Permissions.Endpoints.Logout,
                    OpenIddictConstants.Permissions.Endpoints.Token,
                    OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode,
                    OpenIddictConstants.Permissions.GrantTypes.RefreshToken,
                    OpenIddictConstants.Permissions.ResponseTypes.Code,
                    OpenIddictConstants.Permissions.Scopes.Email,
                    OpenIddictConstants.Permissions.Scopes.Profile,
                    OpenIddictConstants.Permissions.Scopes.Roles
                },
                Requirements =
                {
                    OpenIddictConstants.Requirements.Features.ProofKeyForCodeExchange
                }
            }, cancellationToken);
        }

And register it in my client project like this:

    builder.Services.AddHttpClient("BlazorHosted.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
    .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();

// Supply HttpClient instances that include access tokens when making requests to the server project
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("BlazorHosted.ServerAPI"));

Log.Logger.Information("Adding oidc authentication for {ClientName} with base address {BaseAddress}", nameof(BlazorHosted.Client), builder.HostEnvironment.BaseAddress);

builder.Services.AddOidcAuthentication(options =>
{
    options.ProviderOptions.ClientId = "blazorhosted-webclient";
    options.ProviderOptions.Authority = $"{builder.HostEnvironment.BaseAddress}";
    options.ProviderOptions.ResponseType = "code";
    // options.ProviderOptions.Authority = "id_token token";
    // Note: response_mode=fragment is the best option for a SPA. Unfortunately, the Blazor WASM
    // authentication stack is impacted by a bug that prevents it from correctly extracting
    // authorization error responses (e.g error=access_denied responses) from the URL fragment.
    // For more information about this bug, visit https://github.com/dotnet/aspnetcore/issues/28344.
    options.ProviderOptions.ResponseMode = "query";
    // options.AuthenticationPaths.RemoteRegisterPath = $"{builder.HostEnvironment.BaseAddress}Identity/Account/Register";
    // options.AuthenticationPaths.LogInCallbackPath = $"{builder.HostEnvironment.BaseAddress}/Identity/Account/Login";
    // options.AuthenticationPaths.LogInPath = $"{builder.HostEnvironment.BaseAddress}/Identity/Account/Login";
});

Edit 1

I found a project template for blazor hosted which already includes the openid connect configuration. I started using that and started from scratch. I got no problems so far, it seems that this error was related to my openid connect configuration, or something else I got wrong.

0

There are 0 answers