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__16
1[[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.RemoteAuthenticationService
3.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.RemoteAuthenticationService
3.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)
- I checked up the configuration of OpenIddict multiple times (made sure that the ClientId matches in each configuration)
- I checked all my nuget packages and dependencies, so that the correct versions are installed.
- I checked my local .NET sdk installations.
- I tried downgrading my
Microsoft.AspNetCore.Components.WebAssembly
nuget package (and all other dependent microsoft packages) that is utilizing the AuthenticationService.js file. - I checked older projects which are using Openiddict for authorization and made sure that I'm not missing something.
- 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.