diff options
Diffstat (limited to 'src/server/Utilities/BasicAuthenticationHandler.cs')
| -rw-r--r-- | src/server/Utilities/BasicAuthenticationHandler.cs | 58 |
1 files changed, 44 insertions, 14 deletions
diff --git a/src/server/Utilities/BasicAuthenticationHandler.cs b/src/server/Utilities/BasicAuthenticationHandler.cs index 7961b82..c4124e8 100644 --- a/src/server/Utilities/BasicAuthenticationHandler.cs +++ b/src/server/Utilities/BasicAuthenticationHandler.cs @@ -8,10 +8,21 @@ namespace IOL.BookmarkThing.Server.Utilities; public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions> { private readonly AppDbContext _context; + private readonly IConfiguration _configuration; + private readonly ILogger<BasicAuthenticationHandler> _logger; - public BasicAuthenticationHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, AppDbContext context) : + public BasicAuthenticationHandler( + IOptionsMonitor<AuthenticationSchemeOptions> options, + ILoggerFactory logger, + UrlEncoder encoder, + ISystemClock clock, + AppDbContext context, + IConfiguration configuration + ) : base(options, logger, encoder, clock) { _context = context; + _configuration = configuration; + _logger = logger.CreateLogger<BasicAuthenticationHandler>(); } protected override Task<AuthenticateResult> HandleAuthenticateAsync() { @@ -23,26 +34,45 @@ public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSc return Task.FromResult(AuthenticateResult.Fail("Missing Authorization Header")); try { + var token_entropy = _configuration.GetValue<string>("TOKEN_ENTROPY"); + if (token_entropy.IsNullOrWhiteSpace()) { + _logger.LogWarning("No token entropy is available in env:TOKEN_ENTROPY, Basic auth is disabled"); + return Task.FromResult(AuthenticateResult.Fail("Invalid Authorization Header")); + } + var authHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]); if (authHeader.Parameter == null) return Task.FromResult(AuthenticateResult.Fail("Invalid Authorization Header")); var credentialBytes = Convert.FromBase64String(authHeader.Parameter); - var token_is_guid = Guid.TryParse(Encoding.UTF8.GetString(credentialBytes), out var token_id); - if (token_is_guid) { - var token = _context.AccessTokens.Include(c => c.User).SingleOrDefault(c => c.Id == token_id); - if (token == default) { - return Task.FromResult(AuthenticateResult.Fail("Invalid Authorization Header")); - } + var decrypted_string = Encoding.UTF8.GetString(credentialBytes).DecryptWithAes(token_entropy); + var token_is_guid = Guid.TryParse(decrypted_string, out var token_id); - var claims = token.User.DefaultClaims(); - var identity = new ClaimsIdentity(claims, Scheme.Name); - var principal = new ClaimsPrincipal(identity); - var ticket = new AuthenticationTicket(principal, Scheme.Name); + if (!token_is_guid) { + return Task.FromResult(AuthenticateResult.Fail("Invalid Authorization Header")); + } - return Task.FromResult(AuthenticateResult.Success(ticket)); + var token = _context.AccessTokens.Include(c => c.User).SingleOrDefault(c => c.Id == token_id); + if (token == default) { + return Task.FromResult(AuthenticateResult.Fail("Invalid Authorization Header: Not Found")); } - return Task.FromResult(AuthenticateResult.Fail("Invalid Authorization Header")); - } catch { + if (token.HasExpired) { + return Task.FromResult(AuthenticateResult.Fail("Invalid Authorization Header: Expired")); + } + + var permissions = new List<Claim>() { + new(Constants.TOKEN_ALLOW_READ, token.AllowRead.ToString()), + new(Constants.TOKEN_ALLOW_UPDATE, token.AllowUpdate.ToString()), + new(Constants.TOKEN_ALLOW_CREATE, token.AllowCreate.ToString()), + new(Constants.TOKEN_ALLOW_DELETE, token.AllowDelete.ToString()), + }; + var claims = token.User.DefaultClaims().Concat(permissions); + var identity = new ClaimsIdentity(claims, Constants.BASIC_AUTH_SCHEME); + var principal = new ClaimsPrincipal(identity); + var ticket = new AuthenticationTicket(principal, Constants.BASIC_AUTH_SCHEME); + + return Task.FromResult(AuthenticateResult.Success(ticket)); + } catch (Exception e) { + _logger.LogError(e, $"An exception occured when challenging {Constants.BASIC_AUTH_SCHEME}"); return Task.FromResult(AuthenticateResult.Fail("Invalid Authorization Header")); } } |
