DistributedCacheTicketStore.cs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. using Microsoft.AspNetCore.Authentication;
  2. using Microsoft.AspNetCore.Authentication.Cookies;
  3. using Microsoft.Extensions.Caching.Distributed;
  4. namespace Infrastructure.Extensions;
  5. public sealed class DistributedCacheTicketStore : ITicketStore
  6. {
  7. private readonly IDistributedCache _cache;
  8. private readonly TicketSerializer _serializer = TicketSerializer.Default;
  9. private readonly string _keyPrefix;
  10. public DistributedCacheTicketStore(IDistributedCache cache, string keyPrefix = "AuthTicket:")
  11. {
  12. _cache = cache;
  13. _keyPrefix = keyPrefix;
  14. }
  15. private string BuildKey(string key) => _keyPrefix + key;
  16. private static DistributedCacheEntryOptions BuildEntryOptions(AuthenticationTicket ticket)
  17. {
  18. // CookieAuthenticationHandler usually sets ExpiresUtc.
  19. var expires = ticket.Properties.ExpiresUtc;
  20. if (expires.HasValue)
  21. {
  22. return new DistributedCacheEntryOptions
  23. {
  24. AbsoluteExpiration = expires.Value
  25. };
  26. }
  27. // Fallback if ExpiresUtc is null.
  28. return new DistributedCacheEntryOptions
  29. {
  30. AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(8)
  31. };
  32. }
  33. public async Task<string> StoreAsync(AuthenticationTicket ticket)
  34. {
  35. var key = Guid.NewGuid().ToString("N");
  36. await RenewAsync(key, ticket);
  37. return key;
  38. }
  39. public async Task RenewAsync(string key, AuthenticationTicket ticket)
  40. {
  41. var data = _serializer.Serialize(ticket);
  42. var options = BuildEntryOptions(ticket);
  43. await _cache.SetAsync(BuildKey(key), data, options);
  44. }
  45. public async Task<AuthenticationTicket?> RetrieveAsync(string key)
  46. {
  47. var data = await _cache.GetAsync(BuildKey(key));
  48. return data is null ? null : _serializer.Deserialize(data);
  49. }
  50. public Task RemoveAsync(string key) => _cache.RemoveAsync(BuildKey(key));
  51. }