aspnetcore: Cannot provide a value for property 'AuthenticationService' on type 'Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticatorView'. There is no registered service of type 'Microsoft.AspNetCore.Components.WebAssembly.Authentication.IRemoteAuthenticationService`1[Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticationState

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

I have no Idea what is causing this, but no matter what when I try and login, I get redirected to an error page reading:

Cannot provide a value for property 'AuthenticationService' on type 'Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticatorView'. There is no registered service of type 'Microsoft.AspNetCore.Components.WebAssembly.Authentication.IRemoteAuthenticationService1[Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticationState ` Working on blazor hosted project using netcore 8 rc 2. Be happy to provide code or more information, but this is driving me a little crazy.

Expected Behavior

No response

Steps To Reproduce

No response

Exceptions (if any)

No response

.NET Version

No response

Anything else?

No response

About this issue

  • Original URL
  • State: open
  • Created 8 months ago
  • Reactions: 1
  • Comments: 24 (9 by maintainers)

Most upvoted comments

Thanks for the repro @dudley810. It looks like this issue is trying to use types like RemoteAuthenticatorView from Microsoft.AspNetCore.Components.WebAssembly.Authentication in components that can be server rendered. This is not supported.

Since we want to be able to authenticate the user during server-side rendering, it’s better to use cookies rather than JwtBearer and MSAL.js. I opened a PR is at https://github.com/dudley810/dotnet8identityopenid/pull/1 to use AddMicrosoftIdentityWebApp which uses cookies like you would for other server rendered UI stacks (e.g. MVC and Razor pages) instead of AddMicrosoftIdentityWebApi.

Of course, we still need to be able to flow authentication state from the server to the client for client-side rendering. To do this, the PR defines custom AuthenticationStateProvider’s on both the server and client. They utilize PersistentComponentState to serialize and deserialize the authentication state as render modes transition.

If you need the JWT token, you can use OpenIdConnectOptions.SaveTokens and then access it from the HttpContext like so:

var authResult = await context.AuthenticateAsync(); // This is cached if the user already authenticated
var accessToken = authResult.Properties?.GetTokenValue("access_token");

You theoretically could then flow the access token to the client to have it make requests with it directly, but that’s strongly discouraged:

DO NOT send access tokens that were issued to the middle tier to any other party. Access tokens issued to the middle tier are intended for use only by that middle tier.

Security risks of relaying access tokens from a middle-tier resource to a client (instead of the client getting the access tokens themselves) include:

  • Increased risk of token interception over compromised SSL/TLS channels.
  • Inability to satisfy token binding and Conditional Access scenarios requiring claim step-up (for example, MFA, Sign-in Frequency).
  • Incompatibility with admin-configured device-based policies (for example, MDM, location-based policies).

https://learn.microsoft.com/entra/identity-platform/v2-oauth2-on-behalf-of-flow#middle-tier-access-token-request

You can however use this access token from your API controllers and follow the backend for frontend or BFF pattern. https://learn.microsoft.com/en-us/azure/architecture/patterns/backends-for-frontends

I’m getting the same error when using a similar project structure to @dudley810 but with OIDC rather than MSAL. Server-side login is working fine, but when the WASM loads, it redirects to a blank page and get that error in the console. I’ve even tried manually injecting the RemoteAuthService and it still fails to render the authentication component. builder.Services.AddScoped<IRemoteAuthenticationService<RemoteAuthenticationState>, RemoteAuthenticationService<RemoteAuthenticationState, RemoteUserAccount, OidcProviderOptions>>();

I’m at a loss and can’t figure out how to solve this issue.

I created a sample for this issue. https://github.com/dudley810/dotnet8identityopenid. @halter73 and @mkArtakMSFT let us know if there is any other information you need. Seems like @dlgombert and I are having the same issue but not sure how similar his project is to mine.

@halter73 Any reason the PersistentAuthenticationStateProviders are Singletons and not Scoped? Especially given the PersistingComponentState is only persisting on a static key? builder.Services.AddSingleton<AuthenticationStateProvider, PersistentAuthenticationStateProvider>();

Thanks for the repro @dudley810. It looks like this issue is trying to use types like RemoteAuthenticatorView from Microsoft.AspNetCore.Components.WebAssembly.Authentication in components that can be server rendered. This is not supported.

Since we want to be able to authenticate the user during server-side rendering, it’s better to use cookies rather than JwtBearer and MSAL.js. I opened a PR is at dudley810/dotnet8identityopenid#1 to use AddMicrosoftIdentityWebApp which uses cookies like you would for other server rendered UI stacks (e.g. MVC and Razor pages) instead of AddMicrosoftIdentityWebApi.

Of course, we still need to be able to flow authentication state from the server to the client for client-side rendering. To do this, the PR defines custom AuthenticationStateProvider’s on both the server and client. They utilize PersistentComponentState to serialize and deserialize the authentication state as render modes transition.

This explanation is pure gold! Easily the clearest (and most succinct) explanation I’ve seen of the preferred flow for auth when using components that need to support static server-side rendering. Will be great to see this sort of thing in the docs come next week 😃

Thanks @halter73. I implemented your solution with OIDC and it’s now working as expected. Is this something that can be added into the docs?

Yes. That’s what I’m working on as part of #49668 and why had code ready to quickly open a PR at https://github.com/dudley810/dotnet8identityopenid/pull/1. Thanks for pointing out that we need add a “Prerendering with authentication” section back as part of this.

UserInfo, PersistingAuthenticationStateProvider (server), and PersistentAuthenticationStateProvider (client) in https://github.com/dudley810/dotnet8identityopenid/pull/1 are substitutes for RemoteUserAccount, RemoteAuthenticationService, RemoteAuthenticatorView, etc…

The RemoteAuthenticationService is designed to be used exclusively from WebAssembly whereas the PersistentComponentState-based PersistingAuthenticationStateProvider also works while prerendering the component.

Thanks @halter73. I implemented your solution with OIDC and it’s now working as expected. Is this something that can be added into the docs? As part of the .NET 7 docs, there is a section that mentions pre-rendering not being supported with auth. This section has been removed in the .NET 8 version but hasn’t been replaced with anything else. There is also nothing mentioned about InteractiveAuto and auth either that I could find. e.g. In .NET 7 docs: https://learn.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/additional-scenarios?view=aspnetcore-7.0#prerendering-with-authentication

@halter73 - Where can you get the 8.0.100-rtm.23519.30 to install?