53 lines
1.6 KiB
C#
53 lines
1.6 KiB
C#
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<ApiKeyProvider> _logger;
|
|
private readonly IFusionCache _cache;
|
|
|
|
public async Task<IApiKey?> 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);
|
|
} |