diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/IIdentitySessionRepository.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/IIdentitySessionRepository.cs index 77bc7cd75..e8a413ffe 100644 --- a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/IIdentitySessionRepository.cs +++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/IIdentitySessionRepository.cs @@ -21,5 +21,5 @@ public interface IIdentitySessionRepository : Volo.Abp.Identity.IIdentitySession Task> GetListAsync(Guid userId, CancellationToken cancellationToken = default); - Task DeleteAllAsync(string sessionId, Guid? exceptSessionId = null, CancellationToken cancellationToken = default); + Task DeleteAllSessionAsync(string sessionId, Guid? exceptSessionId = null, CancellationToken cancellationToken = default); } diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionCacheItemSynchronizer.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionCacheItemSynchronizer.cs index bff98e2c2..9ad838cea 100644 --- a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionCacheItemSynchronizer.cs +++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionCacheItemSynchronizer.cs @@ -1,4 +1,7 @@ -using System; +using LINGYUN.Abp.Identity.Settings; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using System; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Entities.Events; @@ -6,6 +9,8 @@ using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.EventBus; using Volo.Abp.EventBus.Distributed; using Volo.Abp.Identity; +using Volo.Abp.Settings; +using Volo.Abp.Uow; namespace LINGYUN.Abp.Identity.Session; public class IdentitySessionCacheItemSynchronizer : @@ -15,15 +20,21 @@ public class IdentitySessionCacheItemSynchronizer : ILocalEventHandler>, ITransientDependency { + public ILogger Logger { protected get; set; } + protected ISettingProvider SettingProvider { get; } protected IIdentitySessionCache IdentitySessionCache { get; } protected IIdentitySessionStore IdentitySessionStore { get; } public IdentitySessionCacheItemSynchronizer( + ISettingProvider settingProvider, IIdentitySessionCache identitySessionCache, IIdentitySessionStore identitySessionStore) { + SettingProvider = settingProvider; IdentitySessionCache = identitySessionCache; IdentitySessionStore = identitySessionStore; + + Logger = NullLogger.Instance; } public async virtual Task HandleEventAsync(EntityDeletedEto eventData) @@ -31,21 +42,11 @@ public class IdentitySessionCacheItemSynchronizer : await IdentitySessionCache.RemoveAsync(eventData.Entity.SessionId); } + [UnitOfWork] public async virtual Task HandleEventAsync(EntityCreatedEto eventData) { - var identitySessionCacheItem = new IdentitySessionCacheItem( - eventData.Entity.Device, - eventData.Entity.DeviceInfo, - eventData.Entity.UserId, - eventData.Entity.SessionId, - eventData.Entity.ClientId, - eventData.Entity.IpAddresses, - eventData.Entity.SignedIn, - eventData.Entity.LastAccessed); - - await IdentitySessionCache.RefreshAsync( - eventData.Entity.SessionId, - identitySessionCacheItem); + await RefreshSessionCache(eventData.Entity); + await CheckConcurrentLoginStrategy(eventData.Entity); } public async virtual Task HandleEventAsync(IdentitySessionChangeAccessedEvent eventData) @@ -73,4 +74,68 @@ public class IdentitySessionCacheItemSynchronizer : // 用户被删除, 移除所有会话 await IdentitySessionStore.RevokeAllAsync(eventData.Entity.Id); } + + protected async virtual Task RefreshSessionCache(IdentitySessionEto session) + { + var identitySessionCacheItem = new IdentitySessionCacheItem( + session.Device, + session.DeviceInfo, + session.UserId, + session.SessionId, + session.ClientId, + session.IpAddresses, + session.SignedIn, + session.LastAccessed); + + await IdentitySessionCache.RefreshAsync( + session.SessionId, + identitySessionCacheItem); + } + + protected async virtual Task CheckConcurrentLoginStrategy(IdentitySessionEto session) + { + // 创建一个会话后根据策略使其他会话失效 + var strategySet = await SettingProvider.GetOrNullAsync(IdentitySettingNames.Session.ConcurrentLoginStrategy); + + Logger.LogDebug($"The concurrent login strategy is: {strategySet}"); + + if (!strategySet.IsNullOrWhiteSpace() && Enum.TryParse(strategySet, true, out var strategy)) + { + switch (strategy) + { + // 限制用户相同设备 + case ConcurrentLoginStrategy.LogoutFromSameTypeDevicesLimit: + + var sameTypeDevicesCountSet = await SettingProvider.GetAsync(IdentitySettingNames.Session.LogoutFromSameTypeDevicesLimit, 1); + + Logger.LogDebug($"Clear other sessions on the device {session.Device} and save only {sameTypeDevicesCountSet} sessions."); + + await IdentitySessionStore.RevokeWithAsync( + session.UserId, + session.Device, + session.Id, + sameTypeDevicesCountSet); + break; + // 限制登录设备 + case ConcurrentLoginStrategy.LogoutFromSameTypeDevices: + + Logger.LogDebug($"Clear all other sessions on the device {session.Device}."); + + await IdentitySessionStore.RevokeAllAsync( + session.UserId, + session.Device, + session.Id); + break; + // 限制多端登录 + case ConcurrentLoginStrategy.LogoutFromAllDevices: + + Logger.LogDebug($"Clear all other user sessions."); + + await IdentitySessionStore.RevokeAllAsync( + session.UserId, + session.Id); + break; + } + } + } } diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionEntityCreatedEventHandler.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionEntityCreatedEventHandler.cs deleted file mode 100644 index d34cd4a39..000000000 --- a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionEntityCreatedEventHandler.cs +++ /dev/null @@ -1,75 +0,0 @@ -using LINGYUN.Abp.Identity.Settings; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Abstractions; -using System; -using System.Threading.Tasks; -using Volo.Abp.Caching; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Domain.Entities.Events; -using Volo.Abp.EventBus; -using Volo.Abp.Identity; -using Volo.Abp.Settings; - -namespace LINGYUN.Abp.Identity.Session; -public class IdentitySessionEntityCreatedEventHandler : - ILocalEventHandler>, - ITransientDependency -{ - public ILogger Logger { protected get; set; } - - private readonly ISettingProvider _settingProvider; - private readonly IIdentitySessionStore _identitySessionStore; - private readonly IDistributedCache _identitySessionCache; - - public IdentitySessionEntityCreatedEventHandler( - ISettingProvider settingProvider, - IIdentitySessionStore identitySessionStore, - IDistributedCache identitySessionCache) - { - _settingProvider = settingProvider; - _identitySessionStore = identitySessionStore; - _identitySessionCache = identitySessionCache; - - Logger = NullLogger.Instance; - } - - public async virtual Task HandleEventAsync(EntityCreatedEventData eventData) - { - // 创建一个会话后根据策略使其他会话失效 - var strategySet = await _settingProvider.GetOrNullAsync(IdentitySettingNames.Session.ConcurrentLoginStrategy); - - Logger.LogDebug($"The concurrent login strategy is: {strategySet}"); - - if (!strategySet.IsNullOrWhiteSpace() && Enum.TryParse(strategySet, true, out var strategy)) - { - switch (strategy) - { - // 限制用户相同设备 - case ConcurrentLoginStrategy.LogoutFromSameTypeDevicesLimit: - var sameTypeDevicesCountSet = await _settingProvider.GetAsync(IdentitySettingNames.Session.LogoutFromSameTypeDevicesLimit, 1); - Logger.LogDebug($"Clear other sessions on the device {eventData.Entity.Device} and save only {sameTypeDevicesCountSet} sessions."); - await _identitySessionStore.RevokeWithAsync( - eventData.Entity.UserId, - eventData.Entity.Device, - eventData.Entity.Id, - sameTypeDevicesCountSet); - break; - // 限制登录设备 - case ConcurrentLoginStrategy.LogoutFromSameTypeDevices: - Logger.LogDebug($"Clear all other sessions on the device {eventData.Entity.Device}."); - await _identitySessionStore.RevokeAllAsync( - eventData.Entity.UserId, - eventData.Entity.Device, - eventData.Entity.Id); - break; - // 限制多端登录 - case ConcurrentLoginStrategy.LogoutFromAllDevices: - Logger.LogDebug($"Clear all other user sessions."); - await _identitySessionStore.RevokeAllAsync( - eventData.Entity.UserId, - eventData.Entity.Id); - break; - } - } - } -} diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionStore.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionStore.cs index dcf4c5e26..ed127f7d9 100644 --- a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionStore.cs +++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionStore.cs @@ -126,7 +126,7 @@ public class IdentitySessionStore : IIdentitySessionStore, ITransientDependency string sessionId, CancellationToken cancellationToken = default) { - await IdentitySessionRepository.DeleteAllAsync(sessionId, cancellationToken: cancellationToken); + await IdentitySessionRepository.DeleteAllSessionAsync(sessionId, cancellationToken: cancellationToken); } public async virtual Task RevokeAllAsync( @@ -134,7 +134,7 @@ public class IdentitySessionStore : IIdentitySessionStore, ITransientDependency Guid? exceptSessionId = null, CancellationToken cancellationToken = default) { - await IdentitySessionRepository.DeleteAllAsync(userId, exceptSessionId, cancellationToken: cancellationToken); + await IdentitySessionRepository.DeleteAllAsync(userId: userId, exceptSessionId: exceptSessionId, cancellationToken: cancellationToken); } public async virtual Task RevokeAllAsync( diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.EntityFrameworkCore/LINGYUN/Abp/Identity/EntityFrameworkCore/EfCoreIdentitySessionRepository.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.EntityFrameworkCore/LINGYUN/Abp/Identity/EntityFrameworkCore/EfCoreIdentitySessionRepository.cs index c94fbec3f..49e9b0b49 100644 --- a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.EntityFrameworkCore/LINGYUN/Abp/Identity/EntityFrameworkCore/EfCoreIdentitySessionRepository.cs +++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.EntityFrameworkCore/LINGYUN/Abp/Identity/EntityFrameworkCore/EfCoreIdentitySessionRepository.cs @@ -52,7 +52,7 @@ public class EfCoreIdentitySessionRepository : Volo.Abp.Identity.EntityFramework .ToListAsync(GetCancellationToken(cancellationToken)); } - public async virtual Task DeleteAllAsync( + public async virtual Task DeleteAllSessionAsync( string sessionId, Guid? exceptSessionId = null, CancellationToken cancellationToken = default)