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

Blazor Server .NET 8 with API auth - AuthState is always false

$
0
0

The issue: AuthState is always false, even after successful API auth and after HttpContext.SignInAsync.

I'm stuck with this as I don't understand why Blazor is not updating the authState.

Before .NET 8, I was using custom AuthProvider to update user:

public class WebAuthStateProvider(IHttpContextAccessor httpContextAccessor)    : AuthenticationStateProvider, IAuthProvider{    private ClaimsPrincipal user = httpContextAccessor.HttpContext?.User ?? new ClaimsPrincipal(new ClaimsIdentity());    public override Task<AuthenticationState> GetAuthenticationStateAsync()    {        return Task.FromResult(new AuthenticationState(user));    }    public async Task SaveUser(IEnumerable<Claim> claims)    {        var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);        user = new(identity);        NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(user)));    }    public async Task Logout()    {        user = new ClaimsPrincipal(new ClaimsIdentity());        NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(user)));    }    public void NotifyUserAuthentication()    {        NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());    }}

Login.razor:

private async Task LoginWithEmail(){    errorMessage = null;    var loginRequest = new LoginRequestModel()    {        Platform = IsWeb ? "web" : "mobile",        Email = email,        Password = password    };    try    {        var baseUrl = IsWeb ? Navigation.BaseUri : "https://mydomain/";        var requestUrl = $"{baseUrl}api/v1/auth/login";        var response = await Http.PostAsJsonAsync(requestUrl, loginRequest);        if (response.StatusCode == HttpStatusCode.Unauthorized)        {            errorMessage = "Invalid email or password.";            return;        }        if (!response.IsSuccessStatusCode)        {            errorMessage = "An error occurred while logging in. Please try again.";            return;        }        var authResponse = await response.Content.ReadFromJsonAsync<AuthResponse>();        if (authResponse != null)        {            var claims = new List<Claim>            {                new(ClaimTypes.Email, authResponse.Email),                new("Avatar", authResponse.Avatar),                new("Id", authResponse.Id),                new("JWT", authResponse.Token),            };            claims.AddRange(authResponse.Roles.Select(role => new Claim(ClaimTypes.Role, role)));            var test = AuthState.User; // always null (isAuthenticated = false)            Navigation.NavigateTo("/feed", true);        }    }    catch    {        errorMessage = "An unexpected error occurred. Please try again later.";    }}

Program.cs:

builder.Services.AddAuthentication(options =>    {        options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;        options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;        options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;    })    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>    {        options.LoginPath = "/identity/login";        options.LogoutPath = "/identity/logout";        options.AccessDeniedPath = "/identity/access-denied";        options.ExpireTimeSpan = TimeSpan.FromDays(7);        options.Cookie.HttpOnly = true;        options.Cookie.SecurePolicy = CookieSecurePolicy.Always;    })    .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>    {        options.TokenValidationParameters = new()        {            ValidateIssuer = true,            ValidateAudience = true,            ValidateLifetime = true,            ValidateIssuerSigningKey = true,            ValidIssuer = builder.Configuration["AuthConfiguration:jwtTokenConfig:issuer"],            ValidAudience = builder.Configuration["AuthConfiguration:jwtTokenConfig:issuer"],            IssuerSigningKey = new SymmetricSecurityKey(                Encoding.UTF8.GetBytes(builder.Configuration["AuthConfiguration:jwtTokenConfig:secret"])            )        };    })    .AddGoogle("Google", options =>    {        options.ClientId = builder.Configuration["Google:ClientId"];        options.ClientSecret = builder.Configuration["Google:ClientSecret"];        options.ClaimActions.MapJsonKey("urn:google:profile", "link");        options.ClaimActions.MapJsonKey("urn:google:image", "picture");        options.CorrelationCookie.SecurePolicy = CookieSecurePolicy.Always;        options.SaveTokens = true;    });builder.Services.AddAuthorization();builder.Services.AddCascadingAuthenticationState();builder.Services.AddHttpContextAccessor();...app.UseAuthentication();app.UseAuthorization();app.UseRouting();

App.Razor - wrapped into CascadingAuthenticationState.

AuthController.cs:

[HttpPost("register")]public async Task<IActionResult> Register([FromBody] RegisterRequestModel requestModel){    if (await userManager.FindByEmailAsync(requestModel.Email) != null)        return Conflict("User with this email already exists.");    var user = new UserEntity    {        UserName = SanitizeUserName(requestModel.Name),        Email = requestModel.Email,        AvatarUrl = "default-avatar.png"    };    var result = await userManager.CreateAsync(user, requestModel.Password);    if (!result.Succeeded)        return BadRequest(result.Errors);    var roles = await userManager.GetRolesAsync(user);    var token = GenerateJwtToken(user, roles);    var claims = new List<Claim>    {        new(ClaimTypes.Email, user.Email),        new("Avatar", user.AvatarUrl),        new("Id", user.Id)    };    claims.AddRange(roles.Select(role => new Claim(ClaimTypes.Role, role)));    var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);    var authProperties = new AuthenticationProperties { IsPersistent = true };    await HttpContext.SignInAsync(        CookieAuthenticationDefaults.AuthenticationScheme,        new(claimsIdentity),        authProperties);    logger.LogInformation($"User registered: {requestModel.Name} {requestModel.Email}");    return Ok(new AuthResponse    {        Token = token,        Email = user.Email,        Avatar = user.AvatarUrl,        Roles = roles.ToList(),        Id = user.Id    });}

Viewing all articles
Browse latest Browse all 4839

Trending Articles



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