diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs index 593992aed4..730fe98533 100644 --- a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs @@ -102,6 +102,7 @@ public static class AbpApplicationBuilderExtensions return app.UseMiddleware(); } + [Obsolete("Replace with AbpClaimsTransformation")] public static IApplicationBuilder UseAbpClaimsMap(this IApplicationBuilder app) { return app.UseMiddleware(); diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/AbpAspNetCoreServiceCollectionExtensions.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/AbpAspNetCoreServiceCollectionExtensions.cs index bda87a4e32..c6f8dd7ddc 100644 --- a/framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/AbpAspNetCoreServiceCollectionExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/AbpAspNetCoreServiceCollectionExtensions.cs @@ -1,6 +1,7 @@ -using System.Linq; +using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; +using Volo.Abp.AspNetCore.Security.Claims; namespace Microsoft.Extensions.DependencyInjection; @@ -20,4 +21,9 @@ public static class AbpAspNetCoreServiceCollectionExtensions return hostingEnvironment; } + + public static IServiceCollection TransformAbpClaims(this IServiceCollection services) + { + return services.AddTransient(); + } } diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsMapMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsMapMiddleware.cs index bb2bedf901..2104edab0a 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsMapMiddleware.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsMapMiddleware.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; @@ -10,6 +11,7 @@ using Volo.Abp.Security.Claims; namespace Volo.Abp.AspNetCore.Security.Claims; +[Obsolete("Replace with AbpClaimsTransformation")] public class AbpClaimsMapMiddleware : AbpMiddlewareBase, ITransientDependency { public async override Task InvokeAsync(HttpContext context, RequestDelegate next) diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsTransformation.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsTransformation.cs new file mode 100644 index 0000000000..17e8f0d599 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsTransformation.cs @@ -0,0 +1,35 @@ +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.Extensions.Options; + +namespace Volo.Abp.AspNetCore.Security.Claims; + +public class AbpClaimsTransformation : IClaimsTransformation +{ + protected IOptions AbpClaimsMapOptions { get; } + + public AbpClaimsTransformation(IOptions abpClaimsMapOptions) + { + AbpClaimsMapOptions = abpClaimsMapOptions; + } + + public virtual Task TransformAsync(ClaimsPrincipal principal) + { + var mapClaims = principal.Claims.Where(claim => AbpClaimsMapOptions.Value.Maps.Keys.Contains(claim.Type)); + + principal.AddIdentity(new ClaimsIdentity(mapClaims.Select( + claim => new Claim( + AbpClaimsMapOptions.Value.Maps[claim.Type](), + claim.Value, + claim.ValueType, + claim.Issuer + ) + ) + ) + ); + + return Task.FromResult(principal); + } +} diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs index 3f9c605f64..027403d226 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs @@ -73,9 +73,10 @@ public class AbpAspNetCoreMvcTestModule : AbpModule context.Services.AddAuthentication(options => { + options.DefaultAuthenticateScheme = FakeAuthenticationSchemeDefaults.Scheme; options.DefaultChallengeScheme = "Bearer"; options.DefaultForbidScheme = "Cookie"; - }).AddCookie("Cookie").AddJwtBearer("Bearer", _ => { }); + }).AddFakeAuthentication().AddCookie("Cookie").AddJwtBearer("Bearer", _ => { }); context.Services.AddAuthorization(options => { @@ -137,6 +138,8 @@ public class AbpAspNetCoreMvcTestModule : AbpModule { options.Contributors.Add(new TestApplicationConfigurationContributor()); }); + + context.Services.TransformAbpClaims(); } public override void OnApplicationInitialization(ApplicationInitializationContext context) @@ -148,8 +151,6 @@ public class AbpAspNetCoreMvcTestModule : AbpModule app.UseAbpRequestLocalization(); app.UseAbpSecurityHeaders(); app.UseRouting(); - app.UseMiddleware(); - app.UseAbpClaimsMap(); app.UseAuthentication(); app.UseAuthorization(); app.UseAuditing(); diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/FakeAuthenticationMiddleware.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/FakeAuthenticationMiddleware.cs index a3cd4a57e6..886e22f1dd 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/FakeAuthenticationMiddleware.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/FakeAuthenticationMiddleware.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; @@ -8,6 +9,7 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.AspNetCore.Mvc; +[Obsolete("Use FakeAuthenticationScheme instead.")] public class FakeAuthenticationMiddleware : AbpMiddlewareBase, ITransientDependency { private readonly FakeUserClaims _fakeUserClaims; diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/FakeAuthenticationScheme.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/FakeAuthenticationScheme.cs new file mode 100644 index 0000000000..641bbe03d7 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/FakeAuthenticationScheme.cs @@ -0,0 +1,68 @@ +using System; +using System.Security.Claims; +using System.Text.Encodings.Web; +using System.Threading.Tasks; +using DeviceDetectorNET; +using Microsoft.AspNetCore.Authentication; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace Volo.Abp.AspNetCore.Mvc; + +public static class FakeAuthenticationSchemeDefaults +{ + public static string Scheme => "FakeAuthenticationScheme"; +} + +public static class FakeAuthenticationBuilderExtensions +{ + public static AuthenticationBuilder AddFakeAuthentication(this AuthenticationBuilder builder) + { + return builder.AddScheme(FakeAuthenticationSchemeDefaults.Scheme, _ => { }); + } +} + +public class FakeAuthenticationOptions : AuthenticationSchemeOptions +{ + +} + +public class FakeAuthenticationHandler : AuthenticationHandler +{ + private readonly FakeUserClaims _fakeUserClaims; + + [Obsolete] + public FakeAuthenticationHandler( + IOptionsMonitor options, + ILoggerFactory logger, + UrlEncoder encoder, + ISystemClock clock, + FakeUserClaims fakeUserClaims) : base(options, logger, encoder, clock) + { + _fakeUserClaims = fakeUserClaims; + } + + public FakeAuthenticationHandler( + IOptionsMonitor options, + ILoggerFactory logger, + UrlEncoder encoder, + FakeUserClaims fakeUserClaims) + : base(options, logger, encoder) + { + _fakeUserClaims = fakeUserClaims; + } + + protected override Task HandleAuthenticateAsync() + { + if (_fakeUserClaims.Claims.Any()) + { + return Task.FromResult(AuthenticateResult.Success( + new AuthenticationTicket( + new ClaimsPrincipal(new ClaimsIdentity(_fakeUserClaims.Claims, + FakeAuthenticationSchemeDefaults.Scheme)), + FakeAuthenticationSchemeDefaults.Scheme))); + } + + return Task.FromResult(AuthenticateResult.NoResult()); + } +}