[WIP] Reworking authentication service

This commit is contained in:
max 2025-04-28 17:11:46 +02:00
parent d69359e937
commit e22b7790dd
2 changed files with 70 additions and 11 deletions

View File

@ -5,6 +5,11 @@ public class AuthorityAuthenticationOptions
public AuthenticationSecurityOptions Security { get; set; } = new AuthenticationSecurityOptions(); public AuthenticationSecurityOptions Security { get; set; } = new AuthenticationSecurityOptions();
public SessionOptions Session { get; set; } = new SessionOptions(); public SessionOptions Session { get; set; } = new SessionOptions();
public string DefaultScheme { get; set; } = string.Empty; public string DefaultScheme { get; set; } = string.Empty;
public string DefaultAuthenticateScheme { get; set; } = string.Empty;
public string DefaultChallengeScheme { get; set; } = string.Empty;
public string DefaultForbidScheme { get; set; } = string.Empty;
public string DefaultSignInScheme { get; set; } = string.Empty;
public string DefaultSignOutScheme { get; set; } = string.Empty;
public List<SchemeInfo> SchemeMap { get; set; } = []; public List<SchemeInfo> SchemeMap { get; set; } = [];
} }

View File

@ -1,47 +1,101 @@
using System.Security.Claims; using System.Security.Claims;
using DotBased.AspNet.Authority.Managers;
using DotBased.AspNet.Authority.Models.Options.Auth; using DotBased.AspNet.Authority.Models.Options.Auth;
using DotBased.Logging;
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
namespace DotBased.AspNet.Authority.Services; namespace DotBased.AspNet.Authority.Services;
public class AuthorityAuthenticationService(IAuthenticationSchemeProvider schemes, public class AuthorityAuthenticationService(
IAuthenticationHandlerProvider handlers, IAuthenticationHandlerProvider handlers,
IClaimsTransformation transform, IClaimsTransformation transform,
IOptions<AuthorityAuthenticationOptions> options, IOptions<AuthorityAuthenticationOptions> options) : IAuthenticationService
AuthorityManager manager) : IAuthenticationService
{ {
private readonly ILogger _logger = LogService.RegisterLogger(typeof(AuthorityAuthenticationService));
private readonly AuthorityAuthenticationOptions _options = options.Value;
public async Task<AuthenticateResult> AuthenticateAsync(HttpContext context, string scheme) public async Task<AuthenticateResult> AuthenticateAsync(HttpContext context, string scheme)
{ {
throw new NotImplementedException(); _logger.Debug("Authenticate with scheme: {Scheme}", scheme);
var authenticationHandler = await GetAuthenticationHandler(context, scheme, _options.DefaultAuthenticateScheme);
var authResult = await authenticationHandler.AuthenticateAsync();
return authResult is { Succeeded: true }
? AuthenticateResult.Success(
new AuthenticationTicket(await transform.TransformAsync(authResult.Principal), authResult.Properties, authResult.Ticket.AuthenticationScheme)) :
AuthenticateResult.Fail("Failed to authenticate");
} }
public async Task ChallengeAsync(HttpContext context, string scheme, AuthenticationProperties properties) public async Task ChallengeAsync(HttpContext context, string scheme, AuthenticationProperties properties)
{ {
throw new NotImplementedException(); _logger.Debug("Challenging with scheme: {Scheme}", scheme);
var authenticationHandler = await GetAuthenticationHandler(context, scheme, _options.DefaultChallengeScheme);
await authenticationHandler.ChallengeAsync(properties);
} }
public async Task ForbidAsync(HttpContext context, string scheme, AuthenticationProperties properties) public async Task ForbidAsync(HttpContext context, string scheme, AuthenticationProperties properties)
{ {
throw new NotImplementedException(); _logger.Debug("Forbid with scheme: {Scheme}", scheme);
var authenticationHandler = await GetAuthenticationHandler(context, scheme, _options.DefaultForbidScheme);
await authenticationHandler.ForbidAsync(properties);
} }
public async Task SignInAsync(HttpContext context, string scheme, ClaimsPrincipal principal, AuthenticationProperties properties) public async Task SignInAsync(HttpContext context, string scheme, ClaimsPrincipal principal, AuthenticationProperties properties)
{ {
throw new NotImplementedException(); _logger.Debug("SignIn with scheme: {Scheme}", scheme);
var authenticationHandler = await GetAuthenticationHandler(context, scheme, _options.DefaultSignInScheme);
if (authenticationHandler is not IAuthenticationSignInHandler signInHandler)
{
throw new InvalidOperationException("Authentication handler is not a IAuthenticationSignInHandler.");
}
await signInHandler.SignInAsync(principal, properties);
} }
public async Task SignOutAsync(HttpContext context, string scheme, AuthenticationProperties properties) public async Task SignOutAsync(HttpContext context, string scheme, AuthenticationProperties properties)
{ {
throw new NotImplementedException(); _logger.Debug("SignOut with scheme: {Scheme}", scheme);
var authenticationHandler = await GetAuthenticationHandler(context, scheme, _options.DefaultSignOutScheme);
if (authenticationHandler is not IAuthenticationSignOutHandler signOutHandler)
{
throw new InvalidOperationException("Authentication handler is not a IAuthenticationSignOutHandler.");
}
await signOutHandler.SignOutAsync(properties);
} }
public async Task ValidateLoginAsync() /*public async Task ValidateLoginAsync()
{ {
//TODO: Check if user is logged in from external identity provider, if user not exists in authority db create user. //TODO: Check if user is logged in from external identity provider, if user not exists in authority db create user.
throw new NotImplementedException(); throw new NotImplementedException();
}*/
private async Task<IAuthenticationHandler> GetAuthenticationHandler(HttpContext context, string scheme, string defaultScheme)
{
if (string.IsNullOrWhiteSpace(scheme))
{
scheme = defaultScheme;
if (string.IsNullOrWhiteSpace(scheme))
{
scheme = _options.DefaultScheme;
if (string.IsNullOrWhiteSpace(scheme))
{
throw new InvalidOperationException("Failed to get default scheme. No scheme specified.");
}
}
}
var authenticationHandler = await handlers.GetHandlerAsync(context, scheme);
if (authenticationHandler == null)
{
_logger.Warning("Failed to load handler for scheme: {Scheme}", scheme);
throw new InvalidOperationException($"No authentication handlers registered to the scheme '{scheme}'");
}
return authenticationHandler;
} }
} }