Quantcast
Channel: Active questions tagged blazor - Stack Overflow
Viewing all articles
Browse latest Browse all 4055

Authentication in Blazor pages is not persisting. Why?

$
0
0

I've implemented a user authorization in Blazor server using both local DB and Microsoft Azure.

  1. When a user authorizes using Microsoft Azure the authorization is persistent when changing Blazor pages.
  2. When a user authorizes using local DB the authorization is reset (GetAuthorizationState returns null). And my question is why?

I've a custom CustomAuthenticationStateProvider:

public class CustomAuthenticationStateProvider : AuthenticationStateProvider{    private readonly IHttpContextAccessor _httpContextAccessor;    public CustomAuthenticationStateProvider(IHttpContextAccessor httpContextAccessor)    {        _httpContextAccessor = httpContextAccessor;    }    public override Task<AuthenticationState> GetAuthenticationStateAsync()    {        var principal = _httpContextAccessor.HttpContext?.User;        if (principal?.Identity?.IsAuthenticated != true)        {            principal = new ClaimsPrincipal(new ClaimsIdentity());        }        return Task.FromResult(new AuthenticationState(principal));    }    public void MarkUserAsAuthenticated(ClaimsPrincipal user)    {        NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(user)));    }    public void MarkUserAsLoggedOut()    {        var principal = _httpContextAccessor.HttpContext?.User;        NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(principal)));    }}

In my Program.cs i have the azure authentication setup as follow:

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme).AddMicrosoftIdentityWebApp(    options =>    {        options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;        options.AccessDeniedPath = "/accessdenied";        //builder.Configuration.GetSection("AzureAd")        builder.Configuration.Bind("AzureAD", options);        options.Events ??= new OpenIdConnectEvents();        options.Events.OnTokenValidated = async context =>        {            var identity = (ClaimsIdentity)context.Principal.Identity;            var email = identity.Name;            var repository = new UsersRepository(new SqlConnectionFactory(builder.Configuration.GetConnectionString("SuperSecretConnectionString")));            var roles = await repository.GetUserRolesAsync(email);            foreach (var role in roles)            {                identity.AddClaim(new Claim(ClaimTypes.Role, role));            }        };    });

And here is my code that authenticates user when he is logging in using the local DB (email and password)

    public async Task SignInUserAsync(object user){    List<string> roles = await _usersRepository.GetUserRolesAsync(user.Email);    var claims = new List<Claim>    {        new Claim(ClaimTypes.Name, user.Name), // Use the actual name from the user model        new Claim(ClaimTypes.Email, user.Email), // Use the actual email from the user model    };    foreach (var role in roles)    {        var roleClaim = new Claim(ClaimTypes.Role, role);        claims.Add(roleClaim); // Add each role claim    }    var identity = new ClaimsIdentity(claims, /*Explicit*/CookieAuthenticationDefaults.AuthenticationScheme);    var principal = new ClaimsPrincipal(identity);    ((CustomAuthenticationStateProvider)AuthenticationStateProvider).MarkUserAsAuthenticated(principal);}

Thank you for any input!


Viewing all articles
Browse latest Browse all 4055

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>