From 03eb74f649a4a92cea551a20fed836dd0b0a1a12 Mon Sep 17 00:00:00 2001 From: colin Date: Sat, 8 Nov 2025 15:50:30 +0800 Subject: [PATCH] feat(account): IP access not use the domain tenant resolver --- aspnet-core/LINGYUN.MicroService.All.sln | 7 +++ .../FodyWeavers.xml | 3 ++ .../FodyWeavers.xsd | 30 +++++++++++ ...LINGYUN.Abp.AspNetCore.MultiTenancy.csproj | 21 ++++++++ .../AbpAspNetCoreMultiTenancyModule.cs | 10 ++++ ...AbpAspNetCoreMultiTenancyResolveOptions.cs | 13 +++++ .../AbpMultiTenancyOptionsExtensions.cs | 15 ++++++ .../OnlyDomainTenantResolveContributor.cs | 52 +++++++++++++++++++ .../Properties/launchSettings.json | 12 +++++ .../AuthServerModule.Configure.cs | 4 +- .../AuthServerModule.cs | 2 + .../LY.MicroService.AuthServer.csproj | 1 + .../IdentityServerModule.Configure.cs | 3 +- .../IdentityServerModule.cs | 2 + .../LY.MicroService.IdentityServer.csproj | 1 + 15 files changed, 173 insertions(+), 3 deletions(-) create mode 100644 aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/FodyWeavers.xml create mode 100644 aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/FodyWeavers.xsd create mode 100644 aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/LINGYUN.Abp.AspNetCore.MultiTenancy.csproj create mode 100644 aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/LINGYUN/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs create mode 100644 aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/LINGYUN/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyResolveOptions.cs create mode 100644 aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/LINGYUN/Abp/AspNetCore/MultiTenancy/AbpMultiTenancyOptionsExtensions.cs create mode 100644 aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/LINGYUN/Abp/AspNetCore/MultiTenancy/OnlyDomainTenantResolveContributor.cs create mode 100644 aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/Properties/launchSettings.json diff --git a/aspnet-core/LINGYUN.MicroService.All.sln b/aspnet-core/LINGYUN.MicroService.All.sln index 0bf68ce8a..e8de430b4 100644 --- a/aspnet-core/LINGYUN.MicroService.All.sln +++ b/aspnet-core/LINGYUN.MicroService.All.sln @@ -849,6 +849,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Exporter.Pdf.Sp EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Account.Security", "modules\account\LINGYUN.Abp.Account.Security\LINGYUN.Abp.Account.Security.csproj", "{5FA85E8E-3276-43DF-CC93-6A9847905166}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.AspNetCore.MultiTenancy", "framework\tenants\LINGYUN.Abp.AspNetCore.MultiTenancy\LINGYUN.Abp.AspNetCore.MultiTenancy.csproj", "{AEEA81D6-B282-93CF-862B-9FCF1A5052F7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2203,6 +2205,10 @@ Global {5FA85E8E-3276-43DF-CC93-6A9847905166}.Debug|Any CPU.Build.0 = Debug|Any CPU {5FA85E8E-3276-43DF-CC93-6A9847905166}.Release|Any CPU.ActiveCfg = Release|Any CPU {5FA85E8E-3276-43DF-CC93-6A9847905166}.Release|Any CPU.Build.0 = Release|Any CPU + {AEEA81D6-B282-93CF-862B-9FCF1A5052F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AEEA81D6-B282-93CF-862B-9FCF1A5052F7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AEEA81D6-B282-93CF-862B-9FCF1A5052F7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AEEA81D6-B282-93CF-862B-9FCF1A5052F7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2615,6 +2621,7 @@ Global {738A72FB-ED83-4127-AA3B-59BF90635F8F} = {A4633711-7FB6-411A-8D08-BB9A0A778046} {9950639D-AA4C-4FF1-A65E-9790EB561C8A} = {A4633711-7FB6-411A-8D08-BB9A0A778046} {5FA85E8E-3276-43DF-CC93-6A9847905166} = {9E72FEB9-A626-4312-892B-CDD043879758} + {AEEA81D6-B282-93CF-862B-9FCF1A5052F7} = {A5543E56-DA53-494D-A531-DA75091D46FF} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718} diff --git a/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/FodyWeavers.xml b/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/FodyWeavers.xml new file mode 100644 index 000000000..5d6962159 --- /dev/null +++ b/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/FodyWeavers.xsd b/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/LINGYUN.Abp.AspNetCore.MultiTenancy.csproj b/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/LINGYUN.Abp.AspNetCore.MultiTenancy.csproj new file mode 100644 index 000000000..89b162615 --- /dev/null +++ b/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/LINGYUN.Abp.AspNetCore.MultiTenancy.csproj @@ -0,0 +1,21 @@ + + + + + + + net9.0 + LINGYUN.Abp.AspNetCore.MultiTenancy + LINGYUN.Abp.AspNetCore.MultiTenancy + false + false + false + Library + enable + + + + + + + diff --git a/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/LINGYUN/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs b/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/LINGYUN/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs new file mode 100644 index 000000000..61668fc97 --- /dev/null +++ b/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/LINGYUN/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs @@ -0,0 +1,10 @@ +using Volo.Abp.Modularity; +using VoloAbpAspNetCoreMultiTenancyModule = Volo.Abp.AspNetCore.MultiTenancy.AbpAspNetCoreMultiTenancyModule; + +namespace LINGYUN.Abp.AspNetCore.MultiTenancy; + +[DependsOn(typeof(VoloAbpAspNetCoreMultiTenancyModule))] +public class AbpAspNetCoreMultiTenancyModule : AbpModule +{ + +} diff --git a/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/LINGYUN/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyResolveOptions.cs b/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/LINGYUN/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyResolveOptions.cs new file mode 100644 index 000000000..1b7d0abc8 --- /dev/null +++ b/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/LINGYUN/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyResolveOptions.cs @@ -0,0 +1,13 @@ +namespace LINGYUN.Abp.AspNetCore.MultiTenancy; + +public class AbpAspNetCoreMultiTenancyResolveOptions +{ + /// + /// 仅解析域名中的租户, 默认: true + /// + public bool OnlyResolveDomain { get; set; } + public AbpAspNetCoreMultiTenancyResolveOptions() + { + OnlyResolveDomain = true; + } +} diff --git a/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/LINGYUN/Abp/AspNetCore/MultiTenancy/AbpMultiTenancyOptionsExtensions.cs b/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/LINGYUN/Abp/AspNetCore/MultiTenancy/AbpMultiTenancyOptionsExtensions.cs new file mode 100644 index 000000000..d78531af5 --- /dev/null +++ b/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/LINGYUN/Abp/AspNetCore/MultiTenancy/AbpMultiTenancyOptionsExtensions.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using Volo.Abp.MultiTenancy; + +namespace LINGYUN.Abp.AspNetCore.MultiTenancy; + +public static class AbpMultiTenancyOptionsExtensions +{ + public static void AddOnlyDomainTenantResolver(this AbpTenantResolveOptions options, string domainFormat) + { + options.TenantResolvers.InsertAfter( + r => r is CurrentUserTenantResolveContributor, + new OnlyDomainTenantResolveContributor(domainFormat) + ); + } +} diff --git a/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/LINGYUN/Abp/AspNetCore/MultiTenancy/OnlyDomainTenantResolveContributor.cs b/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/LINGYUN/Abp/AspNetCore/MultiTenancy/OnlyDomainTenantResolveContributor.cs new file mode 100644 index 000000000..b272971ff --- /dev/null +++ b/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/LINGYUN/Abp/AspNetCore/MultiTenancy/OnlyDomainTenantResolveContributor.cs @@ -0,0 +1,52 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using System; +using System.Net; +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.MultiTenancy; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Text.Formatting; + +namespace LINGYUN.Abp.AspNetCore.MultiTenancy; + +public class OnlyDomainTenantResolveContributor : HttpTenantResolveContributorBase +{ + public const string ContributorName = "Domain"; + + public override string Name => ContributorName; + + private static readonly string[] ProtocolPrefixes = { "http://", "https://" }; + + private readonly string _domainFormat; + + public OnlyDomainTenantResolveContributor(string domainFormat) + { + _domainFormat = domainFormat.RemovePreFix(ProtocolPrefixes); + } + + protected override Task GetTenantIdOrNameFromHttpContextOrNullAsync(ITenantResolveContext context, HttpContext httpContext) + { + if (!httpContext.Request.Host.HasValue) + { + return Task.FromResult(null); + } + + var options = httpContext.RequestServices.GetRequiredService>(); + if (options.Value.OnlyResolveDomain) + { + // 仅仅解析域名, 如果请求的是IP地址, 则不使用这个解析贡献者 + if (IPAddress.TryParse(httpContext.Request.Host.Host, out var _)) + { + return Task.FromResult(null); + } + } + + var hostName = httpContext.Request.Host.Value.RemovePreFix(ProtocolPrefixes); + var extractResult = FormattedStringValueExtracter.Extract(hostName, _domainFormat, ignoreCase: true); + + context.Handled = true; + + return Task.FromResult(extractResult.IsMatch ? extractResult.Matches[0].Value : null); + } +} diff --git a/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/Properties/launchSettings.json b/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/Properties/launchSettings.json new file mode 100644 index 000000000..8ac6471cc --- /dev/null +++ b/aspnet-core/framework/tenants/LINGYUN.Abp.AspNetCore.MultiTenancy/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "profiles": { + "LINGYUN.Abp.AspNetCore.MultiTenancy": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:61811;http://localhost:61812" + } + } +} \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.AuthServer/AuthServerModule.Configure.cs b/aspnet-core/services/LY.MicroService.AuthServer/AuthServerModule.Configure.cs index c9c9c2e7e..0080c2059 100644 --- a/aspnet-core/services/LY.MicroService.AuthServer/AuthServerModule.Configure.cs +++ b/aspnet-core/services/LY.MicroService.AuthServer/AuthServerModule.Configure.cs @@ -1,4 +1,5 @@ using DotNetCore.CAP; +using LINGYUN.Abp.AspNetCore.MultiTenancy; using LINGYUN.Abp.BlobStoring.OssManagement; using LINGYUN.Abp.Localization.CultureMap; using LINGYUN.Abp.LocalizationManagement; @@ -14,7 +15,6 @@ using LINGYUN.Abp.Wrapper; using LY.MicroService.AuthServer.Ui.Branding; using Medallion.Threading; using Medallion.Threading.Redis; -using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Cors; @@ -446,7 +446,7 @@ public partial class AuthServerModule var domains = tenantResolveCfg.Get(); foreach (var domain in domains) { - options.AddDomainTenantResolver(domain); + options.AddOnlyDomainTenantResolver(domain); } }); } diff --git a/aspnet-core/services/LY.MicroService.AuthServer/AuthServerModule.cs b/aspnet-core/services/LY.MicroService.AuthServer/AuthServerModule.cs index f79f1b147..a4c7d5cd5 100644 --- a/aspnet-core/services/LY.MicroService.AuthServer/AuthServerModule.cs +++ b/aspnet-core/services/LY.MicroService.AuthServer/AuthServerModule.cs @@ -2,6 +2,7 @@ using LINGYUN.Abp.Account.Web.OAuth; using LINGYUN.Abp.Account.Web.OpenIddict; using LINGYUN.Abp.AspNetCore.HttpOverrides; +using LINGYUN.Abp.AspNetCore.MultiTenancy; using LINGYUN.Abp.AspNetCore.Mvc.Wrapper; using LINGYUN.Abp.AuditLogging.Elasticsearch; using LINGYUN.Abp.BlobStoring.OssManagement; @@ -69,6 +70,7 @@ namespace LY.MicroService.AuthServer; typeof(AbpDataDbMigratorModule), typeof(AbpAuditLoggingElasticsearchModule), // 放在 AbpIdentity 模块之后,避免被覆盖 typeof(AbpLocalizationCultureMapModule), + typeof(AbpAspNetCoreMultiTenancyModule), typeof(AbpAspNetCoreMvcWrapperModule), typeof(AbpAspNetCoreHttpOverridesModule), typeof(AbpTelemetrySkyWalkingModule), diff --git a/aspnet-core/services/LY.MicroService.AuthServer/LY.MicroService.AuthServer.csproj b/aspnet-core/services/LY.MicroService.AuthServer/LY.MicroService.AuthServer.csproj index 6c80ea30c..d1fed8872 100644 --- a/aspnet-core/services/LY.MicroService.AuthServer/LY.MicroService.AuthServer.csproj +++ b/aspnet-core/services/LY.MicroService.AuthServer/LY.MicroService.AuthServer.csproj @@ -54,6 +54,7 @@ + diff --git a/aspnet-core/services/LY.MicroService.IdentityServer/IdentityServerModule.Configure.cs b/aspnet-core/services/LY.MicroService.IdentityServer/IdentityServerModule.Configure.cs index b9a4dc9a0..66a6ef394 100644 --- a/aspnet-core/services/LY.MicroService.IdentityServer/IdentityServerModule.Configure.cs +++ b/aspnet-core/services/LY.MicroService.IdentityServer/IdentityServerModule.Configure.cs @@ -1,6 +1,7 @@ using DotNetCore.CAP; using LINGYUN.Abp.Account.Web; using LINGYUN.Abp.Account.Web.IdentityServer; +using LINGYUN.Abp.AspNetCore.MultiTenancy; using LINGYUN.Abp.IdentityServer.IdentityResources; using LINGYUN.Abp.Localization.CultureMap; using LINGYUN.Abp.LocalizationManagement; @@ -372,7 +373,7 @@ public partial class IdentityServerModule var domains = tenantResolveCfg.Get(); foreach (var domain in domains) { - options.AddDomainTenantResolver(domain); + options.AddOnlyDomainTenantResolver(domain); } }); } diff --git a/aspnet-core/services/LY.MicroService.IdentityServer/IdentityServerModule.cs b/aspnet-core/services/LY.MicroService.IdentityServer/IdentityServerModule.cs index 7bad8a130..0801af9d5 100644 --- a/aspnet-core/services/LY.MicroService.IdentityServer/IdentityServerModule.cs +++ b/aspnet-core/services/LY.MicroService.IdentityServer/IdentityServerModule.cs @@ -1,6 +1,7 @@ using LINGYUN.Abp.Account; using LINGYUN.Abp.Account.Web.IdentityServer; using LINGYUN.Abp.AspNetCore.HttpOverrides; +using LINGYUN.Abp.AspNetCore.MultiTenancy; using LINGYUN.Abp.AspNetCore.Mvc.Wrapper; using LINGYUN.Abp.AuditLogging.Elasticsearch; using LINGYUN.Abp.Authentication.QQ; @@ -68,6 +69,7 @@ namespace LY.MicroService.IdentityServer; typeof(AbpDataDbMigratorModule), typeof(AbpAuditLoggingElasticsearchModule), // 放在 AbpIdentity 模块之后,避免被覆盖 typeof(AbpLocalizationCultureMapModule), + typeof(AbpAspNetCoreMultiTenancyModule), typeof(AbpAspNetCoreMvcWrapperModule), typeof(AbpAspNetCoreHttpOverridesModule), typeof(AbpTelemetrySkyWalkingModule), diff --git a/aspnet-core/services/LY.MicroService.IdentityServer/LY.MicroService.IdentityServer.csproj b/aspnet-core/services/LY.MicroService.IdentityServer/LY.MicroService.IdentityServer.csproj index 4076974cd..fba73edd9 100644 --- a/aspnet-core/services/LY.MicroService.IdentityServer/LY.MicroService.IdentityServer.csproj +++ b/aspnet-core/services/LY.MicroService.IdentityServer/LY.MicroService.IdentityServer.csproj @@ -56,6 +56,7 @@ +