Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(session): fix session cache expiration time #1025

Merged
merged 1 commit into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using Volo.Abp.Auditing;
using Volo.Abp.Domain.Services;
using Volo.Abp.Identity;
using Volo.Abp.Timing;

namespace LINGYUN.Abp.Identity.Session;
public class IdentitySessionManager : DomainService, IIdentitySessionManager
Expand Down Expand Up @@ -76,17 +75,6 @@ await IdentitySessionStore.CreateAsync(

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(
sessionId,
new IdentitySessionCacheItem(
Expand All @@ -98,8 +86,7 @@ await IdentitySessionCache.RefreshAsync(
clientIpAddress,
Clock.Now,
Clock.Now,
deviceInfo.IpRegion,
expiraIn),
deviceInfo.IpRegion),
cancellationToken);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public async virtual Task ContributeAsync(AbpClaimsPrincipalContributorContext c
using (currentTenant.Change(tenantId))
{
var identitySessionChecker = context.GetRequiredService<IIdentitySessionChecker>();
if (!await identitySessionChecker.ValidateSessionAsync(sessionId))
if (!await identitySessionChecker.ValidateSessionAsync(context.ClaimsPrincipal))
{
// 用户会话已过期
context.ClaimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using System;
using System.Security.Claims;
using System.Security.Principal;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
Expand Down Expand Up @@ -40,8 +42,9 @@ public DefaultIdentitySessionChecker(
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())
{
Logger.LogDebug("No user session id found.");
Expand All @@ -67,6 +70,15 @@ public async virtual Task<bool> ValidateSessionAsync(string sessionId, Cancellat
identitySessionCacheItem.LastAccessed = accressedTime;
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}.");
await IdentitySessionCache.RefreshAsync(sessionId, identitySessionCacheItem, cancellationToken);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using System.Threading;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;

namespace LINGYUN.Abp.Identity.Session;
public interface IIdentitySessionChecker
{
Task<bool> ValidateSessionAsync(string sessionId, CancellationToken cancellationToken = default);
Task<bool> ValidateSessionAsync(ClaimsPrincipal claimsPrincipal, CancellationToken cancellationToken = default);
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,9 @@ public UserinfoIdentitySession(
public async virtual ValueTask HandleAsync(OpenIddictServerEvents.HandleUserinfoRequestContext context)
{
var tenantId = context.Principal.FindTenantId();
var sessionId = context.Principal.FindSessionId();
using (CurrentTenant.Change(tenantId))
{
if (sessionId.IsNullOrWhiteSpace() ||
!await IdentitySessionChecker.ValidateSessionAsync(sessionId))
if (!await IdentitySessionChecker.ValidateSessionAsync(context.Principal))
{
// Errors.InvalidToken ---> 401
// Errors.ExpiredToken ---> 400
Expand Down
Loading