Implementing api key authentication scheme and validation. Added default value in dtos
This commit was merged in pull request #5.
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
using System.Security.Claims;
|
||||
using System.Text.Encodings.Web;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moonlight.Api.Database;
|
||||
using Moonlight.Api.Database.Entities;
|
||||
using Moonlight.Shared;
|
||||
|
||||
namespace Moonlight.Api.Implementations.ApiKeyScheme;
|
||||
|
||||
public class ApiKeySchemeHandler : AuthenticationHandler<ApiKeySchemeOptions>
|
||||
{
|
||||
private readonly DatabaseRepository<ApiKey> ApiKeyRepository;
|
||||
private readonly IMemoryCache MemoryCache;
|
||||
|
||||
public ApiKeySchemeHandler(
|
||||
IOptionsMonitor<ApiKeySchemeOptions> options,
|
||||
ILoggerFactory logger,
|
||||
UrlEncoder encoder,
|
||||
DatabaseRepository<ApiKey> apiKeyRepository,
|
||||
IMemoryCache memoryCache
|
||||
) : base(options, logger, encoder)
|
||||
{
|
||||
ApiKeyRepository = apiKeyRepository;
|
||||
MemoryCache = memoryCache;
|
||||
}
|
||||
|
||||
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||
{
|
||||
var authHeaderValue = Request.Headers.Authorization.FirstOrDefault() ?? null;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(authHeaderValue))
|
||||
return AuthenticateResult.NoResult();
|
||||
|
||||
if (authHeaderValue.Length > 32)
|
||||
return AuthenticateResult.Fail("Invalid api key specified");
|
||||
|
||||
if (!MemoryCache.TryGetValue<ApiKeySession>(authHeaderValue, out var apiKey))
|
||||
{
|
||||
apiKey = await ApiKeyRepository
|
||||
.Query()
|
||||
.Where(x => x.Key == authHeaderValue)
|
||||
.Select(x => new ApiKeySession(x.Permissions))
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (apiKey == null)
|
||||
return AuthenticateResult.Fail("Invalid api key specified");
|
||||
|
||||
MemoryCache.Set(authHeaderValue, apiKey, Options.LookupCacheTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (apiKey == null)
|
||||
return AuthenticateResult.Fail("Invalid api key specified");
|
||||
}
|
||||
|
||||
return AuthenticateResult.Success(new AuthenticationTicket(
|
||||
new ClaimsPrincipal(
|
||||
new ClaimsIdentity(
|
||||
apiKey.Permissions.Select(x => new Claim(Permissions.ClaimType, x)).ToArray()
|
||||
)
|
||||
),
|
||||
Scheme.Name
|
||||
));
|
||||
}
|
||||
|
||||
private record ApiKeySession(string[] Permissions);
|
||||
}
|
||||
Reference in New Issue
Block a user