Files
tiku-backend.net/Tiku.Application/Security/AuthorizationCacheModels.cs
xiong c497a3ca8d
Some checks failed
ci / release-gate (push) Has been cancelled
清理代码
2026-08-03 12:31:39 +08:00

111 lines
4.4 KiB
C#

using Tiku.Application.Auth;
using Tiku.Domain.Identity;
using Tiku.Domain.Tenancy;
namespace Tiku.Application.Security;
public enum AuthorizationCacheMode
{
Disabled,
Shadow,
Active
}
public sealed class AuthorizationCacheOptions
{
public const string SectionName = "Security:AuthorizationCache";
public AuthorizationCacheMode Mode { get; set; } = AuthorizationCacheMode.Disabled;
public int LocalSnapshotSeconds { get; set; } = 60;
public int DistributedStateSeconds { get; set; } = 60;
public int DistributedSnapshotSeconds { get; set; } = 300;
public int JitterPercent { get; set; } = 20;
}
public sealed record CachedSessionSecurityState(
Guid SessionId,
Guid UserId,
AuthRealm Realm,
Guid? TenantId,
string SecurityStamp,
DateTimeOffset ExpiresAt,
bool Revoked);
public sealed record CachedUserSecurityState(Guid UserId, UserStatus Status, string SecurityStamp);
public sealed record CachedTenantSecurityState(Guid TenantId, TenantStatus Status);
public sealed record CachedMembershipSecurityState(Guid TenantId, Guid UserId, MembershipStatus Status);
public sealed record CachedPlatformAccessState(Guid UserId, long AuthorizationVersion, bool Allowed);
public sealed record CachedAuthorizationVersion(AuthRealm Realm, Guid? TenantId, long Version);
public sealed record AccessSecurityCacheLookup(Guid SessionId, Guid UserId, AuthRealm Realm, Guid? TenantId);
public sealed record AccessSecurityCacheState(
CachedSessionSecurityState? Session,
CachedUserSecurityState? User,
CachedTenantSecurityState? Tenant,
CachedMembershipSecurityState? Membership,
CachedPlatformAccessState? PlatformAccess,
CachedAuthorizationVersion? AuthorizationVersion)
{
public bool Complete => Session is not null && User is not null && AuthorizationVersion is not null &&
((Session.Realm == AuthRealm.Platform && PlatformAccess is not null) ||
(Session.Realm == AuthRealm.Tenant && Tenant is not null && Membership is not null));
}
public sealed record CachedAuthorizationSnapshot(long Version, CurrentAccessSnapshot Snapshot);
public interface IAccessSecurityCache
{
bool IsConfigured { get; }
Task<AccessSecurityCacheState?> GetAsync(AccessSecurityCacheLookup lookup,
CancellationToken cancellationToken = default);
Task SetAsync(AccessSecurityCacheState state, CancellationToken cancellationToken = default);
Task InvalidateSessionAsync(Guid sessionId, CancellationToken cancellationToken = default);
Task InvalidateUserAsync(Guid userId, CancellationToken cancellationToken = default);
Task InvalidateTenantAsync(Guid tenantId, CancellationToken cancellationToken = default);
Task InvalidateMembershipAsync(Guid tenantId, Guid userId, CancellationToken cancellationToken = default);
Task SetAuthorizationVersionAsync(AuthRealm realm, Guid? tenantId, long version,
CancellationToken cancellationToken = default);
}
public interface IAuthorizationSnapshotCache
{
Task<CachedAuthorizationSnapshot?> GetAsync(AuthRealm realm, Guid? tenantId, Guid userId,
CancellationToken cancellationToken = default);
Task SetAsync(AuthRealm realm, Guid? tenantId, Guid userId, CachedAuthorizationSnapshot snapshot,
CancellationToken cancellationToken = default);
}
public interface IAuthorizationStateInvalidator
{
Task InvalidateSessionAsync(Guid sessionId, CancellationToken cancellationToken = default);
Task InvalidateUserAsync(Guid userId, CancellationToken cancellationToken = default);
Task InvalidateTenantAsync(Guid tenantId, CancellationToken cancellationToken = default);
Task InvalidateMembershipAsync(Guid tenantId, Guid userId, CancellationToken cancellationToken = default);
Task<long> BumpScopeAsync(AuthRealm realm, Guid? tenantId, CancellationToken cancellationToken = default);
}
public interface IAuthorizationCacheInvalidationProcessor
{
Task<int> ProcessPendingAsync(int batchSize = 100, CancellationToken cancellationToken = default);
}
public interface IRequestAccessValidator
{
Task<AuthSessionValidationResult?> ValidateAsync(
Guid sessionId,
Guid userId,
AuthRealm realm,
Guid? tenantId,
CancellationToken cancellationToken = default);
}
public sealed class AuthorizationSecurityUnavailableException(Exception innerException)
: Exception("Authentication security dependencies are unavailable.", innerException);