asp.net-coreauthenticationblazorwindows-authentication

ASP.NET (Blazor): Trigger windows authentication popup only on a single page


My Blazor webapp (ASP.NET) should consist of pages, that allow anonymous users (url/noauth) and a single page, which needs authentication (url/auth). The authentication mechanism to be used is windows authentication (which includes an automatically triggered popup for logging in, if authentication fails).

Popup: authentication popup

The desired behavior is to

  1. show the noauth page to any user
  2. show the auth page to authenticated users only (e.g. browser inside intranet)
  3. show a popup asking for windows credentials to non-authenticated users requesting auth page

My code:

Auth.razor

@page "/auth"
@attribute [Authorize]

<h3>Auth</h3>
<CascadingAuthenticationState>
    <AuthorizeView>
        <Authorized>
            <p>You are authorized</p>
        </Authorized>
        <NotAuthorized>
            <p>You are not authorized</p>
        </NotAuthorized>
    </AuthorizeView>
</CascadingAuthenticationState>

@code {

}

NoAuth.razor

@page "/noAuth"
@attribute [AllowAnonymous]

<h3>NoAuth</h3>

@code {

}

Program.cs (Version A)

builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
    .AddNegotiate();
builder.Services.AddAuthorization();

This way the authentication check works fine, I am able to view the noauth page and the auth page shows me, that I am not authorized. However I do not have any means of authenticating/logging in (no popup is shown).

Program.cs (Version B)

builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
    .AddNegotiate();
builder.Services.AddAuthorization(options => {
    options.FallbackPolicy = options.DefaultPolicy;
});

This way, when calling the auth page without being logged in I get a popup asking for my windows credentials (desired), however I get the same popup on the noauth page (not desired).

How can I either exclude the noauth page from the popup-showing-mechanism , or trigger the popup for the auth page?


Solution

  • You mentioned Blazor webapp ( in your statement, so I deduce you are now using blazor in .net 8. If we are using .net 8 for authentication, we should use builder.Services.AddCascadingAuthenticationState(); instead of <CascadingAuthenticationState>. We could see the migration guidance here.

    Then the program.cs we have should like this:

    var builder = WebApplication.CreateBuilder(args);
    
    // Add services to the container.
    builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
       .AddNegotiate();
    
    builder.Services.AddAuthorization(options =>
    {
        // By default, all incoming requests will be authorized according to the default policy.
        //options.FallbackPolicy = options.DefaultPolicy;
        //options.AddPolicy("RequireAdminRole", policy => policy.RequireRole("admin"));
    });
    // Add services to the container.
    builder.Services.AddRazorComponents()
        .AddInteractiveServerComponents();
    builder.Services.AddCascadingAuthenticationState();
    

    You might notice that I comment line //options.FallbackPolicy = options.DefaultPolicy; that's because the default policy would make us sign in first before we visit any view, no matter whether we added [AllowAnonymous] attribution.

    Then we could add @attribute [Authorize] to components which requiring authentication, and @attribute [AllowAnonymous] or don't add attribtue to components which doesn't require authentcation.

    For example, my counter.razor and my home.razor

    @page "/counter"
    @using Microsoft.AspNetCore.Authorization
    @rendermode InteractiveServer
    @attribute [Authorize]
    
    <PageTitle>Counter</PageTitle>
    
    <h1>Counter</h1>
    
    
    @page "/"
    <PageTitle>Home</PageTitle>
    

    enter image description here