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).
The desired behavior is to
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?
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>