Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blazor .net 8 Own Authentication

In the Blazor (server side) I use AuthenticationStateProvider to set the authentication details in the session and restore it. Everything works perfecly with AuthorizeView but when I want to use Authorize attribute I am getting following error.

 InvalidOperationException: Unable to find the required 'IAuthenticationService' service. Please add all the required services by calling 'IServiceCollection.AddAuthentication' in the application startup code.

When I add builder.Services.AddAuthenticationCore(); I am getting the next error.

InvalidOperationException: No authenticationScheme was specified, and there was no DefaultChallengeScheme found. The default schemes can be set using either AddAuthentication(string defaultScheme) or AddAuthentication(Action<AuthenticationOptions> configureOptions).

I do not want to use builder.Services.AddAuthentication as it forces to me use authentication handler (like AddCookie()).

I want to use AuthenticationStateProvider for authentication handling. Is there any ready solution for that ?

like image 991
Masteroxify Avatar asked May 21 '26 00:05

Masteroxify


2 Answers

I also had came across this issue when moving my Blazor Server App to .NET 8. So after many hours scratching my head I found a solution that I hope helps someone else down the track.

The way around it was for me to create a custom AuthenticationHandler that essentially returns an authorised claim for every new request. It seems that the ASP Core part of Blazor requires an initial claims authentication method on the connection of each new HTTP request but after that, Blazor only uses AuthenticationStateProvider to check if you can access components/pages with the [Authorize] attribute. So if you just automatically authorise all initial connections then spin your own AuthenticationStateProvider you get the required custom authentication for your application.

So what I did was create my own auth handler class:

public class CustomAuthenticationHandler(IOptionsMonitor<CustomAuthOptions> options, ILoggerFactory logger, UrlEncoder encoder,IHttpContextAccessor httpContextAccessor)
    : AuthenticationHandler<CustomAuthOptions>(options, logger, encoder) 
    {

    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        return AuthenticateResult.Success(new AuthenticationTicket(new ClaimsPrincipal(new GenericIdentity("CustomIdentity")), "CustomAuthenticationScheme"));
    }
}

public class CustomAuthOptions : AuthenticationSchemeOptions
{
    // Add any custom options here if needed in the future
}

Then add it as the the default Authentication Scheme in program.cs

builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = "CustomScheme";
    options.DefaultChallengeScheme    = "CustomScheme";
})
.AddScheme<CustomAuthOptions, CustomAuthenticationHandler>("CustomScheme", options => { });

This gets around the error and lets you use your custom authentication via AuthenticationStateProvider. And even though the code "authorises" all initial connections it does not allow access to any pages/components marked with the [Authorize] attribute as that only uses the AuthenticationStateProvider now.

Just for completelness, I add my custom AuthenticationStateProvider into program.cs as such:

builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthenticationProvider>();

Which in my case checks if a token has been set for the current user's circuit to say they are logged in - which happens on the login page. So far all my testing is working as expected with users only being able to access my secure pages when logged in correctly.

Again, hopefully that helps someone else out.

like image 95
Nathan Avatar answered May 26 '26 21:05

Nathan


I cannot comment on your question because of the "popularity contest" that is the reputation, great policies guys, keep them up!

Anywho, the only thing I found is this issue on the asp.net github: https://github.com/dotnet/aspnetcore/issues/52326

The gist of it is that updating your project to use .NET 8.0 Program.cs munges things up. I think this must be a bug in the framework, because the same program with the old NET 7.0 Program.cs styled startup works correctly, even when the Target Framework is then updated.

I tracked the issue to the Authorization Services being added automatically, but when I reverted the code to calling AddRouting and AddAuthentication (without AddAuthorization), the error was:

InvalidOperationException: Endpoint / (/) contains authorization metadata, but a middleware was not found that supports authorization. Configure your application startup by adding app.UseAuthorization() in the application startup code. If there are calls to app.UseRouting() and app.UseEndpoints(...), the call to app.UseAuthorization() must go between them.

Again, this did not happen on .NET 7.0, so I reckon until the framework is more mature, we'll have to wait or cope with custom authentication being demoted to a 2nd class citizen (and keep the Program.cs as is).

like image 43
MoltenCore Avatar answered May 26 '26 22:05

MoltenCore



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!