using AspNetCore.Authentication.ApiKey; using Microsoft.EntityFrameworkCore; using NejCommon.Models; using NejCommon.Utils; using ZiggyCreatures.Caching.Fusion; namespace NejCommon.Services; public partial class ApiKeyProvider : IApiKeyProvider, IScopedService { private readonly ILogger _logger; private readonly IFusionCache _cache; public async Task ProvideAsync(string key) { using var activity = Telemetry.Start("ApiKeyProvider.ProvideAsync"); return await _cache.GetOrSetAsync($"ApiKeyProvider.ProvideAsync.{key}", async entry => { // write your validation implementation here and return an instance of a valid ApiKey or retun null for an invalid key. var lookup = ApiKey.ComputeLookupHash(key); var apiKey = await GetApiKeySet().FirstOrDefaultAsync(x => x.LookupHash.SequenceEqual(lookup)); if (apiKey == null) { return null; } if (!apiKey.VerifyStrongHash(key)) { return null; } if (apiKey.Revoked) { return null; } apiKey.Key = key; // return await _apiKeyRepository.GetApiKeyAsync(key); return apiKey; }, new FusionCacheEntryOptions() { Duration = TimeSpan.FromMinutes(1), IsFailSafeEnabled = true, FailSafeMaxDuration = TimeSpan.FromMinutes(5), }); } public static string GenerateKey() => "nej-" + NanoidDotNet.Nanoid.Generate(size: 256); }