diff --git a/DotBased.AspNet.Authority/AuthorityDefaults.cs b/DotBased.AspNet.Authority/AuthorityDefaults.cs index 8a437d6..d5b9b1f 100755 --- a/DotBased.AspNet.Authority/AuthorityDefaults.cs +++ b/DotBased.AspNet.Authority/AuthorityDefaults.cs @@ -4,6 +4,11 @@ public static class AuthorityDefaults { public static class Scheme { + public static class Authority + { + public const string AuthenticationScheme = "Authority.Scheme.Password"; + } + public static class Cookie { public const string Default = "Authority.Scheme.Cookie"; diff --git a/DotBased.AspNet.Authority/AuthorityProviderExtensions.cs b/DotBased.AspNet.Authority/AuthorityProviderExtensions.cs index 5795590..88b3a44 100755 --- a/DotBased.AspNet.Authority/AuthorityProviderExtensions.cs +++ b/DotBased.AspNet.Authority/AuthorityProviderExtensions.cs @@ -41,10 +41,18 @@ public static class AuthorityProviderExtensions builder.Services.Configure(configureOptions); builder.Services.AddScoped(); + //TODO: Register authority default authentication handler + var authBuilder = builder.Services.AddAuthentication(); return authBuilder; } + public static AuthenticationBuilder AddAuthorityLoginScheme(this AuthenticationBuilder builder, string scheme = AuthorityDefaults.Scheme.Authority.AuthenticationScheme) + { + + return builder; + } + public static AuthenticationBuilder AddAuthorityCookie(this AuthenticationBuilder builder, string scheme = AuthorityDefaults.Scheme.Cookie.Default) { builder.AddCookie(options => @@ -69,11 +77,6 @@ public static class AuthorityProviderExtensions return builder; } - public static AuthorityBuilder AddAuthorityRepository(this AuthorityBuilder authorityBuilder) where TRepository : class - { - return authorityBuilder; - } - public static AuthorityBuilder MapAuthorityEndpoints(this AuthorityBuilder builder) { return builder; diff --git a/DotBased.AspNet.Authority/Handlers/AuthorityAuthenticationHandler.cs b/DotBased.AspNet.Authority/Handlers/AuthorityAuthenticationHandler.cs index 3385bc6..f6c9992 100644 --- a/DotBased.AspNet.Authority/Handlers/AuthorityAuthenticationHandler.cs +++ b/DotBased.AspNet.Authority/Handlers/AuthorityAuthenticationHandler.cs @@ -4,7 +4,10 @@ using Microsoft.AspNetCore.Http; namespace DotBased.AspNet.Authority.Handlers; -public class AuthorityAuthenticationHandler : IAuthenticationHandler, IAuthenticationSignInHandler, IAuthenticationSignOutHandler +/// +/// Handles authentication for Authority logins. +/// +public class AuthorityAuthenticationHandler : IAuthenticationSignInHandler { public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context) { diff --git a/DotBased.AspNet.Authority/Models/Options/Auth/AuthorityAuthenticationOptions.cs b/DotBased.AspNet.Authority/Models/Options/Auth/AuthorityAuthenticationOptions.cs index 4b16122..15563a9 100644 --- a/DotBased.AspNet.Authority/Models/Options/Auth/AuthorityAuthenticationOptions.cs +++ b/DotBased.AspNet.Authority/Models/Options/Auth/AuthorityAuthenticationOptions.cs @@ -5,4 +5,19 @@ public class AuthorityAuthenticationOptions public AuthenticationSecurityOptions Security { get; set; } = new AuthenticationSecurityOptions(); public SessionOptions Session { get; set; } = new SessionOptions(); public string DefaultScheme { get; set; } = string.Empty; + public List SchemeMap { get; set; } = []; +} + +public class SchemeInfo +{ + public string Scheme { get; set; } = string.Empty; + public string Identifier { get; set; } = string.Empty; + public SchemeType Type { get; set; } + public string AuthenticationType { get; set; } = string.Empty; +} + +public enum SchemeType +{ + Authentication, + SessionStore } \ No newline at end of file diff --git a/DotBased.AspNet.Authority/Services/AuthorityAuthenticationService.cs b/DotBased.AspNet.Authority/Services/AuthorityAuthenticationService.cs index 7b31945..ab31b60 100644 --- a/DotBased.AspNet.Authority/Services/AuthorityAuthenticationService.cs +++ b/DotBased.AspNet.Authority/Services/AuthorityAuthenticationService.cs @@ -1,20 +1,47 @@ using System.Security.Claims; +using DotBased.AspNet.Authority.Managers; +using DotBased.AspNet.Authority.Models.Options.Auth; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Options; namespace DotBased.AspNet.Authority.Services; -public class AuthorityAuthenticationService(IAuthenticationSchemeProvider schemes, IAuthenticationHandlerProvider handlers, IClaimsTransformation transform) : AuthenticationService(schemes, handlers, transform) +public class AuthorityAuthenticationService(IAuthenticationSchemeProvider schemes, + IAuthenticationHandlerProvider handlers, + IClaimsTransformation transform, + IOptions options, + AuthorityManager manager) : IAuthenticationService { - public override Task SignInAsync(HttpContext context, string scheme, ClaimsPrincipal principal, AuthenticationProperties properties) + public async Task AuthenticateAsync(HttpContext context, string scheme) { - //TODO: Get from query parameters which auth scheme to use or fallback to configured default. - return base.SignInAsync(context, scheme, principal, properties); + throw new NotImplementedException(); } - public override Task SignOutAsync(HttpContext context, string scheme, AuthenticationProperties properties) + public async Task ChallengeAsync(HttpContext context, string scheme, AuthenticationProperties properties) { - //TODO: Figure out which type of auth is used and logout with the scheme. - return base.SignOutAsync(context, scheme, properties); + throw new NotImplementedException(); + } + + public async Task ForbidAsync(HttpContext context, string scheme, AuthenticationProperties properties) + { + throw new NotImplementedException(); + } + + public async Task SignInAsync(HttpContext context, string scheme, ClaimsPrincipal principal, AuthenticationProperties properties) + { + throw new NotImplementedException(); + } + + public async Task SignOutAsync(HttpContext context, string scheme, AuthenticationProperties properties) + { + throw new NotImplementedException(); + } + + public async Task ValidateLoginAsync() + { + + //TODO: Check if user is logged in from external identity provider, if user not exists in authority db create user. + throw new NotImplementedException(); } } \ No newline at end of file diff --git a/TestWebApi/Program.cs b/TestWebApi/Program.cs index 0b917f6..f8c586b 100755 --- a/TestWebApi/Program.cs +++ b/TestWebApi/Program.cs @@ -1,5 +1,6 @@ using DotBased.AspNet.Authority; using DotBased.AspNet.Authority.EFCore; +using DotBased.AspNet.Authority.Models.Options.Auth; using DotBased.Logging; using DotBased.Logging.MEL; using DotBased.Logging.Serilog; @@ -27,7 +28,40 @@ builder.Services.AddControllers(); builder.Services.AddAuthority().AddAuthorityContext(options => { options.UseSqlite("Data Source=dev-authority.db", c => c.MigrationsAssembly("TestWebApi")); -}).AddAuthorityAuth() +}).AddAuthorityAuth(options => +{ + options.DefaultScheme = AuthorityDefaults.Scheme.Authority.AuthenticationScheme; + //TODO: Auto detect auth and session store schemes? + options.SchemeMap = [ + new SchemeInfo + { + Scheme = AuthorityDefaults.Scheme.Authority.AuthenticationScheme, + Identifier = "Authority password login", + Type = SchemeType.Authentication, + AuthenticationType = "Password" + }, + new SchemeInfo + { + Scheme = "OIDC", + Identifier = "Authentik OIDC login", + Type = SchemeType.Authentication, + AuthenticationType = "OpenIdConnect" + }, + new SchemeInfo + { + Scheme = AuthorityDefaults.Scheme.Cookie.Default, + Identifier = "Cookie session", + Type = SchemeType.SessionStore + }, + new SchemeInfo + { + Scheme = AuthorityDefaults.Scheme.Token.Default, + Identifier = "Session token", + Type = SchemeType.SessionStore + } + ]; +}) +.AddAuthorityLoginScheme() .AddAuthorityCookie() .AddAuthorityToken();