admin管理员组

文章数量:1122826

In Blazor Server 6.0, cookie authentication scheme is used and cookie is being set. However, after cookie expires, navigation to other links in the app - the requests are still being served to the components.

Also, if I open multiple tabs of each component, logout from 1st tab deletes the cookie, but 2nd and 3rd tabs are still active and components are loaded with content.

  • Version: .NET 6.0
  • Template: Blazor Server
  • Authentication scheme: cookies
  • Expiration time: 2 minutes
  • Revalidation interval: 1 minute

This is the code used:

builder.Services.AddAuthentication(options =>
{
    options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
    options.Cookie.IsEssential = true;
    options.Cookie.SameSite = SameSiteMode.Strict;
    options.LoginPath = new PathString("/login");
    options.Cookie.Name = AppSettings.CookieName;
    options.Cookie.HttpOnly = true;
    options.Cookie.SecurePolicy = builder.Environment.IsDevelopment()
        ? CookieSecurePolicy.None
        : CookieSecurePolicy.Always;
   
    options.ExpireTimeSpan = TimeSpan.FromMinutes(2);
    options.SlidingExpiration = false;
    options.AccessDeniedPath = new PathString("/account/denied");
});

During user authentication, setting SessionId to ClaimType.Sid and checking if this value exists for revalidating user.

  1. How to handle this situation to logout the user in subsequent tabs
  2. Cookie expires, but requests are still being served

Custom state provider:

public class CustomAuthenticationStateProvider : RevalidatingServerAuthenticationStateProvider
{
    private readonly IServiceScopeFactory _scopeFactory;      
    private readonly IHttpContextAccessor _httpContextAccessor;
    private readonly TimeSpanSettings _timeSpanSettings;

    public CustomAuthenticationStateProvider(IHttpContextAccessor httpContextAccessor,
                                             IServiceScopeFactory scopeFactory,
                                             ILoggerFactory loggerFactory,
                                             IOptions<TimeSpanSettings> timeSpanSettingsOptions) : base(loggerFactory)
    {
        _scopeFactory = scopeFactory;
        _httpContextAccessor = httpContextAccessor;
        _timeSpanSettings = timeSpanSettingsOptions.Value;
    }

    protected override TimeSpan RevalidationInterval => TimeSpan.FromMinutes(1);

    public override Task<AuthenticationState> GetAuthenticationStateAsync()
    {
        var httpContext = _httpContextAccessor.HttpContext;

        if (httpContext != null && httpContext.User.Identity.IsAuthenticated)
        {
            var identity = new ClaimsIdentity(httpContext.User.Claims, "cookieauth");
            var user = new ClaimsPrincipal(identity);
            return Task.FromResult(new AuthenticationState(user));
        }
        else 
        {
            return Task.FromResult(new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity())));
        }

        throw new NotImplementedException();
    }

    public void NotifyAuthenticationStateChanged()
    {
        NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
    }

    protected override async Task<bool> ValidateAuthenticationStateAsync(AuthenticationState authenticationState, CancellationToken cancellationToken)
    {
        var sessionId = authenticationState.User.Claims.Where(c => c.Type.Equals(ClaimTypes.Sid)).Select(c => c.Value).FirstOrDefault();
                    
        var user = authenticationState.User;

        if (sessionId != null && user.Identity.IsAuthenticated && user != null)
        {
            return true;
        }

        return false;
    }
}

本文标签: Blazor Server NET 60 multiple tabscookie authenticationrevalidating user and logout problemStack Overflow