using System; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Volo.Abp; using Volo.Abp.DependencyInjection; using Volo.Abp.Identity; using Volo.Abp.MultiTenancy; using Volo.Abp.Security.Claims; using Volo.Abp.Uow; namespace Sozsoft.Platform.Identity; public class PlatformSessionValidationMiddleware : IMiddleware, ITransientDependency { private readonly IIdentitySessionRepository sessionRepository; private readonly ICurrentTenant currentTenant; private readonly IUnitOfWorkManager unitOfWorkManager; public PlatformSessionValidationMiddleware( IIdentitySessionRepository sessionRepository, ICurrentTenant currentTenant, IUnitOfWorkManager unitOfWorkManager) { this.sessionRepository = sessionRepository; this.currentTenant = currentTenant; this.unitOfWorkManager = unitOfWorkManager; } public async Task InvokeAsync(HttpContext context, RequestDelegate next) { if (context.User.Identity?.IsAuthenticated != true) { await next(context); return; } var userIdValue = context.User.FindFirst(AbpClaimTypes.UserId)?.Value; var sessionId = context.User.FindFirst(PlatformClaimTypes.SessionId.Key)?.Value; if (!Guid.TryParse(userIdValue, out var userId) || sessionId.IsNullOrWhiteSpace()) { await next(context); return; } var tenantId = ParseTenantId(context.User.FindFirst(AbpClaimTypes.TenantId)?.Value); using (currentTenant.Change(tenantId)) { using var uow = unitOfWorkManager.Begin(requiresNew: true, isTransactional: false); var sessions = await sessionRepository.GetListAsync(userId: userId); var isCurrentSession = sessions.Any(session => session.SessionId == sessionId); await uow.CompleteAsync(); if (!isCurrentSession) { context.Response.StatusCode = StatusCodes.Status401Unauthorized; return; } } await next(context); } private static Guid? ParseTenantId(string value) { return !string.IsNullOrWhiteSpace(value) && Guid.TryParse(value, out var id) ? id : null; } }