Browse Source

fix(session): fix session cache expiration time

pull/1025/head
colin 1 year ago
parent
commit
8dd9437b9e
  1. 15
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionManager.cs
  2. 2
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Session.AspNetCore/LINGYUN/Abp/Identity/Session/AspNetCore/AbpIdentitySessionDynamicClaimsPrincipalContributor.cs
  3. 14
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Session/LINGYUN/Abp/Identity/Session/DefaultIdentitySessionChecker.cs
  4. 5
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Session/LINGYUN/Abp/Identity/Session/IIdentitySessionChecker.cs
  5. 0
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Session/System/Security/Principal/AbpClaimsIdentityExpiraInExtensions.cs
  6. 4
      aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.AspNetCore.Session/LINGYUN/Abp/OpenIddict/AspNetCore/Session/UserinfoIdentitySession.cs

15
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionManager.cs

@ -7,7 +7,6 @@ using System.Threading.Tasks;
using Volo.Abp.Auditing; using Volo.Abp.Auditing;
using Volo.Abp.Domain.Services; using Volo.Abp.Domain.Services;
using Volo.Abp.Identity; using Volo.Abp.Identity;
using Volo.Abp.Timing;
namespace LINGYUN.Abp.Identity.Session; namespace LINGYUN.Abp.Identity.Session;
public class IdentitySessionManager : DomainService, IIdentitySessionManager public class IdentitySessionManager : DomainService, IIdentitySessionManager
@ -76,17 +75,6 @@ public class IdentitySessionManager : DomainService, IIdentitySessionManager
await IdentityDynamicClaimsPrincipalContributorCache.ClearAsync(userId.Value, tenantId); await IdentityDynamicClaimsPrincipalContributorCache.ClearAsync(userId.Value, tenantId);
// 2024-10-10 从令牌中取颁布时间与过期时间计算时间戳,作为默认缓存过期时间
double? expiraIn = null;
var expirainTime = claimsPrincipal.FindExpirainTime();
var issuedTime = claimsPrincipal.FindIssuedTime();
if (expirainTime.HasValue && issuedTime.HasValue)
{
expiraIn = DateTimeOffset.FromUnixTimeMilliseconds(expirainTime.Value)
.Subtract(DateTimeOffset.FromUnixTimeMilliseconds(issuedTime.Value))
.TotalMicroseconds;
}
await IdentitySessionCache.RefreshAsync( await IdentitySessionCache.RefreshAsync(
sessionId, sessionId,
new IdentitySessionCacheItem( new IdentitySessionCacheItem(
@ -98,8 +86,7 @@ public class IdentitySessionManager : DomainService, IIdentitySessionManager
clientIpAddress, clientIpAddress,
Clock.Now, Clock.Now,
Clock.Now, Clock.Now,
deviceInfo.IpRegion, deviceInfo.IpRegion),
expiraIn),
cancellationToken); cancellationToken);
} }
} }

2
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Session.AspNetCore/LINGYUN/Abp/Identity/Session/AspNetCore/AbpIdentitySessionDynamicClaimsPrincipalContributor.cs

@ -24,7 +24,7 @@ public class AbpIdentitySessionDynamicClaimsPrincipalContributor : IAbpDynamicCl
using (currentTenant.Change(tenantId)) using (currentTenant.Change(tenantId))
{ {
var identitySessionChecker = context.GetRequiredService<IIdentitySessionChecker>(); var identitySessionChecker = context.GetRequiredService<IIdentitySessionChecker>();
if (!await identitySessionChecker.ValidateSessionAsync(sessionId)) if (!await identitySessionChecker.ValidateSessionAsync(context.ClaimsPrincipal))
{ {
// 用户会话已过期 // 用户会话已过期
context.ClaimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity()); context.ClaimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity());

14
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Session/LINGYUN/Abp/Identity/Session/DefaultIdentitySessionChecker.cs

@ -2,6 +2,8 @@
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System; using System;
using System.Security.Claims;
using System.Security.Principal;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
@ -40,8 +42,9 @@ public class DefaultIdentitySessionChecker : IIdentitySessionChecker, ITransient
Logger = NullLogger<DefaultIdentitySessionChecker>.Instance; Logger = NullLogger<DefaultIdentitySessionChecker>.Instance;
} }
public async virtual Task<bool> ValidateSessionAsync(string sessionId, CancellationToken cancellationToken = default) public async virtual Task<bool> ValidateSessionAsync(ClaimsPrincipal claimsPrincipal, CancellationToken cancellationToken = default)
{ {
var sessionId = claimsPrincipal.FindSessionId();
if (sessionId.IsNullOrWhiteSpace()) if (sessionId.IsNullOrWhiteSpace())
{ {
Logger.LogDebug("No user session id found."); Logger.LogDebug("No user session id found.");
@ -67,6 +70,15 @@ public class DefaultIdentitySessionChecker : IIdentitySessionChecker, ITransient
identitySessionCacheItem.LastAccessed = accressedTime; identitySessionCacheItem.LastAccessed = accressedTime;
identitySessionCacheItem.IpAddresses = DeviceInfoProvider.ClientIpAddress; identitySessionCacheItem.IpAddresses = DeviceInfoProvider.ClientIpAddress;
// 2024-10-10 从令牌中取颁布时间与过期时间计算时间戳,作为默认缓存过期时间
var expirainTime = claimsPrincipal.FindExpirainTime();
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
if (expirainTime.HasValue)
{
// 2024-10-25 应计算剩余过期时间
identitySessionCacheItem.ExpiraIn = (expirainTime.Value - timestamp) * 1000;
}
Logger.LogDebug($"Refresh the user access info in the cache from {sessionId}."); Logger.LogDebug($"Refresh the user access info in the cache from {sessionId}.");
await IdentitySessionCache.RefreshAsync(sessionId, identitySessionCacheItem, cancellationToken); await IdentitySessionCache.RefreshAsync(sessionId, identitySessionCacheItem, cancellationToken);
} }

5
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Session/LINGYUN/Abp/Identity/Session/IIdentitySessionChecker.cs

@ -1,8 +1,9 @@
using System.Threading; using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace LINGYUN.Abp.Identity.Session; namespace LINGYUN.Abp.Identity.Session;
public interface IIdentitySessionChecker public interface IIdentitySessionChecker
{ {
Task<bool> ValidateSessionAsync(string sessionId, CancellationToken cancellationToken = default); Task<bool> ValidateSessionAsync(ClaimsPrincipal claimsPrincipal, CancellationToken cancellationToken = default);
} }

0
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/System/Security/Principal/AbpClaimsIdentityExpiraInExtensions.cs → aspnet-core/modules/identity/LINGYUN.Abp.Identity.Session/System/Security/Principal/AbpClaimsIdentityExpiraInExtensions.cs

4
aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.AspNetCore.Session/LINGYUN/Abp/OpenIddict/AspNetCore/Session/UserinfoIdentitySession.cs

@ -35,11 +35,9 @@ public class UserinfoIdentitySession : IOpenIddictServerHandler<OpenIddictServer
public async virtual ValueTask HandleAsync(OpenIddictServerEvents.HandleUserinfoRequestContext context) public async virtual ValueTask HandleAsync(OpenIddictServerEvents.HandleUserinfoRequestContext context)
{ {
var tenantId = context.Principal.FindTenantId(); var tenantId = context.Principal.FindTenantId();
var sessionId = context.Principal.FindSessionId();
using (CurrentTenant.Change(tenantId)) using (CurrentTenant.Change(tenantId))
{ {
if (sessionId.IsNullOrWhiteSpace() || if (!await IdentitySessionChecker.ValidateSessionAsync(context.Principal))
!await IdentitySessionChecker.ValidateSessionAsync(sessionId))
{ {
// Errors.InvalidToken ---> 401 // Errors.InvalidToken ---> 401
// Errors.ExpiredToken ---> 400 // Errors.ExpiredToken ---> 400

Loading…
Cancel
Save