|
| 1 | +using Microsoft.AspNetCore.Authentication; |
| 2 | +using Microsoft.Extensions.Caching.Hybrid; |
| 3 | +using System; |
| 4 | +using System.Collections.Generic; |
| 5 | +using System.Linq; |
| 6 | +using System.Security.Claims; |
| 7 | +using System.Threading; |
| 8 | +using System.Threading.Tasks; |
| 9 | + |
| 10 | +namespace ClassifiedAds.Infrastructure.Web.ClaimsTransformations; |
| 11 | + |
| 12 | +public class CustomClaimsTransformation : IClaimsTransformation |
| 13 | +{ |
| 14 | + private readonly HybridCache _cache; |
| 15 | + |
| 16 | + public CustomClaimsTransformation(HybridCache cache) |
| 17 | + { |
| 18 | + _cache = cache; |
| 19 | + } |
| 20 | + |
| 21 | + public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal) |
| 22 | + { |
| 23 | + var identity = principal.Identities.FirstOrDefault(x => x.IsAuthenticated); |
| 24 | + if (identity == null) |
| 25 | + { |
| 26 | + return principal; |
| 27 | + } |
| 28 | + |
| 29 | + var userClaim = principal.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier); |
| 30 | + |
| 31 | + if (Guid.TryParse(userClaim?.Value, out var userId)) |
| 32 | + { |
| 33 | + var issuedAt = principal.Claims.FirstOrDefault(x => x.Type == "iat").Value; |
| 34 | + |
| 35 | + var cacheKey = $"permissions/{userId}/{issuedAt}"; |
| 36 | + |
| 37 | + var permissions = await _cache.GetOrCreateAsync(cacheKey, |
| 38 | + async (cancellationToken) => await GetPermissionsAsync(userId, cancellationToken), |
| 39 | + tags: ["permissions", $"permissions/{userId}"]); |
| 40 | + |
| 41 | + var claims = new List<Claim>(); |
| 42 | + claims.AddRange(permissions.Select(p => new Claim("Permission", p))); |
| 43 | + claims.AddRange(principal.Claims); |
| 44 | + |
| 45 | + var newIdentity = new ClaimsIdentity(claims, identity.AuthenticationType); |
| 46 | + return new ClaimsPrincipal(newIdentity); |
| 47 | + } |
| 48 | + |
| 49 | + return principal; |
| 50 | + } |
| 51 | + |
| 52 | + private Task<List<string>> GetPermissionsAsync(Guid userId, CancellationToken cancellationToken) |
| 53 | + { |
| 54 | + // TODO: Get from Db |
| 55 | + var claims = new List<string>(); |
| 56 | + return Task.FromResult(claims); |
| 57 | + } |
| 58 | +} |
0 commit comments