i have a Blazor Server application that is relying on a third party Rest API to authenticate users, providing a token to be used with any HTTP call. Blazor side i implemented a custom authentication state provider to manage the user state and everything works fine. Now i need to implement two internal controllers (in the same project, they're needed for some component library i'm using) and this way they are not secured, so i was trying to pass through Cookie based authentication.
I managed to store the cookie in the browser and, as far as i can see, the cookie is being sent in the request towards Razor components. But if the page is marked with [Authroize]
attribute (they all are) i'm just being redirected to the login page, by design.
After checking it carefully i saw that the user Identity is completely lost once i redirect from the Razor page i'm using to access HttpContext to the Blazor component (and so authenticationState.User.Identity.IsAuthenticated
is always false
).
I've been through a lot of posts and documentation but i really can't figure out why. I'm providing some simplified code. Thanks for any tip.
LoginAuth.cshtml
public async Task<IActionResult> OnGetAsync(string u) {
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, u),
};
var claimsIdentity = new ClaimsIdentity(
claims, CookieAuthenticationDefaults.AuthenticationScheme);
var authProperties = new AuthenticationProperties
{
IsPersistent = true,
};
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);
return LocalRedirect("/dashboard");
}
Login.razor
private async Task Authenticate()
{
var result = await authenticationService.GetToken(user);
if (result != null) {
//storing some info inside session storage and updating the auth. state (this should be removed
//with a working Cookie auth i guess)
}
navManager.NavigateTo($"/loginAuth?u={result.Username}",true);
}
Program.cs
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
options.SlidingExpiration = true;
options.LoginPath = "/login";
options.Cookie.HttpOnly = true;
options.Cookie.SameSite = SameSiteMode.Lax;
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
});
I found the problem: i was previously using a CustomAuthenticationStateProvider and i forgot to remove it from the application builder:
builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthenticationStateProvider>();
This is overwriting, as inteded i guess, any other state coming from a different authentication flow.