From 069369e365852f2f3373aed55aac1f39f1ceacb8 Mon Sep 17 00:00:00 2001 From: George Drak Date: Thu, 8 Feb 2024 18:26:22 +0500 Subject: [PATCH] fix(auth): add auth middlewares only once, use fallbackPolicy instead of custom middleware --- .../IWebApplicationModule.cs | 7 +-- .../WebApplicationBuilderExtensions.cs | 19 +++++--- src/Sitko.Core.Auth/AuthModule.cs | 35 +++++--------- .../AuthorizationMiddleware.cs | 46 ------------------- src/Sitko.Core.Identity/IdentityModule.cs | 10 +--- 5 files changed, 28 insertions(+), 89 deletions(-) delete mode 100644 src/Sitko.Core.Auth/AuthorizationMiddleware.cs diff --git a/src/Sitko.Core.App.Web/IWebApplicationModule.cs b/src/Sitko.Core.App.Web/IWebApplicationModule.cs index 2ee17730d..c8953d711 100644 --- a/src/Sitko.Core.App.Web/IWebApplicationModule.cs +++ b/src/Sitko.Core.App.Web/IWebApplicationModule.cs @@ -24,11 +24,6 @@ void ConfigureAfterUseRouting(IApplicationContext applicationContext, IApplicationBuilder appBuilder) { } - - void ConfigureAuthMiddleware(IApplicationContext applicationContext, - IApplicationBuilder appBuilder) - { - } } public interface IWebApplicationModule : IWebApplicationModule, IApplicationModule @@ -39,3 +34,5 @@ void ConfigureWebHost(IApplicationContext applicationContext, ConfigureWebHostBu { } } + +public interface IAuthApplicationModule : IWebApplicationModule; diff --git a/src/Sitko.Core.App.Web/WebApplicationBuilderExtensions.cs b/src/Sitko.Core.App.Web/WebApplicationBuilderExtensions.cs index c6fa4442c..efa1ae5f3 100644 --- a/src/Sitko.Core.App.Web/WebApplicationBuilderExtensions.cs +++ b/src/Sitko.Core.App.Web/WebApplicationBuilderExtensions.cs @@ -66,24 +66,31 @@ public static WebApplication MapSitkoCore(this WebApplication webApplication) } } - if (webOptions.EnableMvc) - { - webApplication.MapControllers(); - } - var webModules = ModulesHelper.GetEnabledModuleRegistrations(applicationContext, applicationModuleRegistrations) .Select(r => r.GetInstance()) .OfType() .ToList(); + + var authModules = webModules.OfType().ToList(); + if (authModules.Count != 0) + { + webApplication.UseAuthentication(); + webApplication.UseAuthorization(); + } + foreach (var webModule in webModules) { webModule.ConfigureBeforeUseRouting(applicationContext, webApplication); webModule.ConfigureAfterUseRouting(applicationContext, webApplication); - webModule.ConfigureAuthMiddleware(applicationContext, webApplication); webModule.ConfigureEndpoints(applicationContext, webApplication, webApplication); } + if (webOptions.EnableMvc) + { + webApplication.MapControllers(); + } + return webApplication; } } diff --git a/src/Sitko.Core.Auth/AuthModule.cs b/src/Sitko.Core.Auth/AuthModule.cs index e552fc2cc..a7424b201 100644 --- a/src/Sitko.Core.Auth/AuthModule.cs +++ b/src/Sitko.Core.Auth/AuthModule.cs @@ -12,26 +12,10 @@ namespace Sitko.Core.Auth; public interface IAuthModule : IApplicationModule; -internal static class AuthMiddlewareState -{ - public static bool IsConfigured { get; set; } -} - -public abstract class AuthModule : BaseApplicationModule, IWebApplicationModule, +public abstract class AuthModule : BaseApplicationModule, IAuthApplicationModule, IAuthModule where TAuthOptions : AuthOptions, new() { - public virtual void ConfigureAuthMiddleware(IApplicationContext applicationContext, - IApplicationBuilder appBuilder) - { - if (!AuthMiddlewareState.IsConfigured) - { - AuthMiddlewareState.IsConfigured = true; - appBuilder.UseAuthentication().UseAuthorization(); - appBuilder.UseMiddleware>(); - } - } - public override void ConfigureServices(IApplicationContext applicationContext, IServiceCollection services, TAuthOptions startupOptions) { @@ -65,15 +49,21 @@ public override void ConfigureServices(IApplicationContext applicationContext, I { options.AddPolicy(name, policy); } + + if (!string.IsNullOrEmpty(startupOptions.ForcePolicy)) + { + options.FallbackPolicy = startupOptions.Policies + .FirstOrDefault(pair => pair.Key == startupOptions.ForcePolicy).Value; + } }); if (startupOptions.EnableRedisDataProtection) { services.AddDataProtection().PersistKeysToStackExchangeRedis(() => - { - var redis = ConnectionMultiplexer - .Connect($"{startupOptions.RedisHost}:{startupOptions.RedisPort}"); - return redis.GetDatabase(startupOptions.RedisDb); - }, $"{applicationContext.Name}-DP") + { + var redis = ConnectionMultiplexer + .Connect($"{startupOptions.RedisHost}:{startupOptions.RedisPort}"); + return redis.GetDatabase(startupOptions.RedisDb); + }, $"{applicationContext.Name}-DP") .SetApplicationName(applicationContext.Name) .SetDefaultKeyLifetime(TimeSpan.FromMinutes(startupOptions.DataProtectionLifeTimeInMinutes)); } @@ -86,4 +76,3 @@ protected virtual void ConfigureCookieOptions(CookieAuthenticationOptions option protected abstract void ConfigureAuthentication(AuthenticationBuilder authenticationBuilder, TAuthOptions startupOptions); } - diff --git a/src/Sitko.Core.Auth/AuthorizationMiddleware.cs b/src/Sitko.Core.Auth/AuthorizationMiddleware.cs deleted file mode 100644 index 3dc22d0b5..000000000 --- a/src/Sitko.Core.Auth/AuthorizationMiddleware.cs +++ /dev/null @@ -1,46 +0,0 @@ -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Authorization.Policy; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.Options; - -namespace Sitko.Core.Auth; - -public class AuthorizationMiddleware where TAuthOptions : AuthOptions -{ - private readonly RequestDelegate next; - private readonly IOptionsMonitor options; - private readonly IPolicyEvaluator policyEvaluator; - - public AuthorizationMiddleware(RequestDelegate next, IOptionsMonitor options, - IPolicyEvaluator policyEvaluator) - { - this.next = next; - this.options = options; - this.policyEvaluator = policyEvaluator; - } - - public async Task Invoke(HttpContext httpContext) - { - if (!options.CurrentValue.IgnoreUrls.Any() || - options.CurrentValue.IgnoreUrls.All(u => !httpContext.Request.Path.StartsWithSegments(u)) - ) - { - if (!string.IsNullOrEmpty(options.CurrentValue.ForcePolicy)) - { - var policy = options.CurrentValue.Policies[options.CurrentValue.ForcePolicy]; - var authenticateResult = - await policyEvaluator.AuthenticateAsync(policy, httpContext); - var authorizationResult = - await policyEvaluator.AuthorizeAsync(policy, authenticateResult, httpContext, null); - if (!authorizationResult.Succeeded) - { - await httpContext.ChallengeAsync(); - return; - } - } - } - - await next(httpContext); - } -} - diff --git a/src/Sitko.Core.Identity/IdentityModule.cs b/src/Sitko.Core.Identity/IdentityModule.cs index 99d4012e0..cd7aa69b9 100644 --- a/src/Sitko.Core.Identity/IdentityModule.cs +++ b/src/Sitko.Core.Identity/IdentityModule.cs @@ -12,7 +12,7 @@ namespace Sitko.Core.Identity; public class IdentityModule : BaseApplicationModule, - IWebApplicationModule + IAuthApplicationModule where TUser : IdentityUser where TRole : IdentityRole where TDbContext : IdentityDbContext @@ -31,13 +31,6 @@ public void ConfigureEndpoints(IApplicationContext applicationContext, } } - public void ConfigureAfterUseRouting(IApplicationContext applicationContext, - IApplicationBuilder appBuilder) - { - appBuilder.UseAuthentication(); - appBuilder.UseAuthorization(); - } - public override void ConfigureServices(IApplicationContext applicationContext, IServiceCollection services, IdentityModuleOptions startupOptions) { @@ -110,4 +103,3 @@ public class FakeEnv : IWebHostEnvironment public string WebRootPath { get; set; } = ""; public IFileProvider WebRootFileProvider { get; set; } = null!; } -