77 lines
2.9 KiB
C#
77 lines
2.9 KiB
C#
using System;
|
||
using System.Threading.Tasks;
|
||
using Microsoft.Extensions.Logging;
|
||
using OpenIddict.Abstractions;
|
||
using OpenIddict.Server;
|
||
using static OpenIddict.Server.OpenIddictServerEvents;
|
||
using Volo.Abp.DependencyInjection;
|
||
using Volo.Abp.Identity;
|
||
using Volo.Abp.MultiTenancy;
|
||
using Volo.Abp.Security.Claims;
|
||
using System.Linq;
|
||
|
||
namespace Sozsoft.Platform.Identity;
|
||
|
||
/// <summary>
|
||
/// /connect/revocation çağrısı başarıyla tamamlandığında ilgili kullanıcının
|
||
/// AbpSessions tablosundaki tüm satırlarını siler.
|
||
/// OpenIddict server pipeline'ına eklenir; MVC controller override gerektirmez.
|
||
/// </summary>
|
||
public class PlatformSessionRevocationHandler :
|
||
IOpenIddictServerHandler<HandleRevocationRequestContext>,
|
||
ITransientDependency
|
||
{
|
||
private readonly IIdentitySessionRepository sessionRepo;
|
||
private readonly ICurrentTenant currentTenant;
|
||
private readonly ILogger<PlatformSessionRevocationHandler> logger;
|
||
|
||
public PlatformSessionRevocationHandler(
|
||
IIdentitySessionRepository sessionRepo,
|
||
ICurrentTenant currentTenant,
|
||
ILogger<PlatformSessionRevocationHandler> logger)
|
||
{
|
||
this.sessionRepo = sessionRepo;
|
||
this.currentTenant = currentTenant;
|
||
this.logger = logger;
|
||
}
|
||
|
||
public async ValueTask HandleAsync(HandleRevocationRequestContext context)
|
||
{
|
||
// Hata durumunda (geçersiz token, yetkisiz istek vb.) temizlik yapma.
|
||
if (context.IsRejected) return;
|
||
|
||
var userId = context.GenericTokenPrincipal?.GetClaim(OpenIddictConstants.Claims.Subject);
|
||
if (string.IsNullOrEmpty(userId) || !Guid.TryParse(userId, out var userGuid)) return;
|
||
|
||
// Token'dan tenant ID'yi al.
|
||
var tenantId = ParseTenantId(context.GenericTokenPrincipal?.Claims.FirstOrDefault(c => c.Type == AbpClaimTypes.TenantId)?.Value);
|
||
|
||
try
|
||
{
|
||
// Sadece token'ın ait olduğu tenant'taki oturumları sil.
|
||
using (currentTenant.Change(tenantId))
|
||
{
|
||
var sessions = await sessionRepo.GetListAsync(userId: userGuid);
|
||
foreach (var session in sessions)
|
||
{
|
||
await sessionRepo.DeleteAsync(session);
|
||
|
||
logger.LogInformation(
|
||
"AbpSessions cleanup: TenantId:{TenantId}, UserId:{UserId}, SignedIn:{SignedIn}, Now:{Now}",
|
||
tenantId,
|
||
session.UserId,
|
||
session.SignedIn,
|
||
DateTime.UtcNow);
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// Session temizleme hatası revocation akışını bloklamamalı.
|
||
logger.LogWarning(ex,
|
||
"Token revocation sonrası AbpSessions temizliğinde hata. UserId: {UserId}", userId);
|
||
}
|
||
}
|
||
|
||
private static Guid? ParseTenantId(string value) => !string.IsNullOrWhiteSpace(value) && Guid.TryParse(value, out var id) ? id : null;
|
||
}
|