diff --git a/Oqtane.Client/UI/SiteRouter.razor b/Oqtane.Client/UI/SiteRouter.razor index ee09f0aa2..20f536c7a 100644 --- a/Oqtane.Client/UI/SiteRouter.razor +++ b/Oqtane.Client/UI/SiteRouter.razor @@ -157,23 +157,23 @@ editmode = true; // querystring can set edit mode } - // get user - if (PageState == null || PageState.Refresh || refresh || PageState.Alias.SiteId != SiteState.Alias.SiteId) + // verify user is authenticated for current site + var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync(); + if (authState.User.Identity.IsAuthenticated && authState.User.Claims.Any(item => item.Type == "sitekey" && item.Value == SiteState.Alias.SiteKey)) { - var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync(); - // verify user is authenticated for current site - if (authState.User.Identity.IsAuthenticated && authState.User.Claims.Any(item => item.Type == "sitekey" && item.Value == SiteState.Alias.SiteKey)) + if (PageState == null || PageState.Refresh || refresh || PageState.Alias.SiteId != SiteState.Alias.SiteId) { + // get user user = await UserService.GetUserAsync(authState.User.Identity.Name, SiteState.Alias.SiteId); if (user != null) { user.IsAuthenticated = authState.User.Identity.IsAuthenticated; } } - } - else - { - user = PageState.User; + else + { + user = PageState.User; + } } // process any sync events diff --git a/Oqtane.Server/Providers/IdentityRevalidatingAuthenticationStateProvider.cs b/Oqtane.Server/Providers/IdentityRevalidatingAuthenticationStateProvider.cs index 8c059b348..3ec145f9a 100644 --- a/Oqtane.Server/Providers/IdentityRevalidatingAuthenticationStateProvider.cs +++ b/Oqtane.Server/Providers/IdentityRevalidatingAuthenticationStateProvider.cs @@ -4,49 +4,43 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; -using System.Security.Claims; using System.Threading.Tasks; using System.Threading; using System; using Oqtane.Infrastructure; using Oqtane.Extensions; +using Oqtane.Managers; namespace Oqtane.Providers { - internal sealed class IdentityRevalidatingAuthenticationStateProvider( - ILoggerFactory loggerFactory, - IServiceScopeFactory scopeFactory, - IOptions options) - : RevalidatingServerAuthenticationStateProvider(loggerFactory) + public class IdentityRevalidatingAuthenticationStateProvider(ILoggerFactory loggerFactory, IServiceScopeFactory scopeFactory, IOptions options) : RevalidatingServerAuthenticationStateProvider(loggerFactory) { - protected override TimeSpan RevalidationInterval => TimeSpan.FromMinutes(30); - - protected override async Task ValidateAuthenticationStateAsync(AuthenticationState authenticationState, CancellationToken cancellationToken) + // defines how often the authentication state should be asynchronously validated + // note that there is no property within IdentityOptions which allows this to be customized + protected override TimeSpan RevalidationInterval { - await using var scope = scopeFactory.CreateAsyncScope(); - var tenantManager = scope.ServiceProvider.GetRequiredService(); - tenantManager.SetTenant(authenticationState.User.TenantId()); - var userManager = scope.ServiceProvider.GetRequiredService>(); - return await ValidateSecurityStampAsync(userManager, authenticationState.User); + get + { + // suppresses the unused compiler warning for options + var revalidationInterval = TimeSpan.FromMinutes(30); // default Identity value + return (options != null) ? revalidationInterval : revalidationInterval; + } } - private async Task ValidateSecurityStampAsync(UserManager userManager, ClaimsPrincipal principal) + protected override async Task ValidateAuthenticationStateAsync(AuthenticationState authState, CancellationToken cancellationToken) { - var user = await userManager.FindByNameAsync(principal.Identity.Name); - if (user is null) + await using var scope = scopeFactory.CreateAsyncScope(); + var tenantManager = scope.ServiceProvider.GetRequiredService(); + tenantManager.SetTenant(authState.User.TenantId()); + var userManager = scope.ServiceProvider.GetRequiredService(); + var user = userManager.GetUser(authState.User.Identity.Name, authState.User.SiteId()); + if (user == null || user.IsDeleted) { return false; } - else if (!userManager.SupportsUserSecurityStamp) - { - return true; - } else { - var principalStamp = principal.FindFirstValue(options.Value.ClaimsIdentity.SecurityStampClaimType); - var userStamp = await userManager.GetSecurityStampAsync(user); - //return principalStamp == userStamp; // security stamps need to be persisted in principal - they are stored in AspNetUsers - return true; + return true; } } }