From b26fc4d2493c00000a751ebfa4022ee58baf110b Mon Sep 17 00:00:00 2001 From: colin Date: Sat, 7 Jun 2025 19:05:10 +0800 Subject: [PATCH] =?UTF-8?q?feat(auth-server):=20=E5=A2=9E=E5=BC=BA?= =?UTF-8?q?=E8=AE=A4=E8=AF=81=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 增加openiddict泛域名配置 - 增加泛域名认证配置 - 移除微信、QQ认证模块引用 - 添加 **AbpAccountWebOAuthModule** 模块引用 - 主题切换为 **LeptonXLite** - 更新 **package.json** 版本 --- aspnet-core/LINGYUN.MicroService.All.sln | 14 ++ .../AuthServerModule.Configure.cs | 27 +++- .../AuthServerModule.cs | 13 +- .../LY.MicroService.AuthServer.csproj | 15 +- .../TokenWildcardIssuerValidator.cs | 130 ++++++++++++++++++ .../appsettings.Development.json | 4 +- .../LY.MicroService.AuthServer/package.json | 6 +- 7 files changed, 179 insertions(+), 30 deletions(-) create mode 100644 aspnet-core/services/LY.MicroService.AuthServer/TokenWildcardIssuerValidator.cs diff --git a/aspnet-core/LINGYUN.MicroService.All.sln b/aspnet-core/LINGYUN.MicroService.All.sln index 8905b0b34..6deeeb0ae 100644 --- a/aspnet-core/LINGYUN.MicroService.All.sln +++ b/aspnet-core/LINGYUN.MicroService.All.sln @@ -839,6 +839,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Saas.DbChecker" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.UI.Navigation.VueVbenAdmin5", "modules\platform\LINGYUN.Abp.UI.Navigation.VueVbenAdmin5\LINGYUN.Abp.UI.Navigation.VueVbenAdmin5.csproj", "{4105FC8B-E8C6-DBD7-FFEA-EA5AB09C7D08}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Account.Web.OAuth", "modules\account\LINGYUN.Abp.Account.Web.OAuth\LINGYUN.Abp.Account.Web.OAuth.csproj", "{DD11D070-F39E-1C41-1843-AE3ADBE501EF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Account.OAuth", "modules\account\LINGYUN.Abp.Account.OAuth\LINGYUN.Abp.Account.OAuth.csproj", "{001D0817-1EED-4C04-821E-F815F148EC90}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2173,6 +2177,14 @@ Global {4105FC8B-E8C6-DBD7-FFEA-EA5AB09C7D08}.Debug|Any CPU.Build.0 = Debug|Any CPU {4105FC8B-E8C6-DBD7-FFEA-EA5AB09C7D08}.Release|Any CPU.ActiveCfg = Release|Any CPU {4105FC8B-E8C6-DBD7-FFEA-EA5AB09C7D08}.Release|Any CPU.Build.0 = Release|Any CPU + {DD11D070-F39E-1C41-1843-AE3ADBE501EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DD11D070-F39E-1C41-1843-AE3ADBE501EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DD11D070-F39E-1C41-1843-AE3ADBE501EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DD11D070-F39E-1C41-1843-AE3ADBE501EF}.Release|Any CPU.Build.0 = Release|Any CPU + {001D0817-1EED-4C04-821E-F815F148EC90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {001D0817-1EED-4C04-821E-F815F148EC90}.Debug|Any CPU.Build.0 = Debug|Any CPU + {001D0817-1EED-4C04-821E-F815F148EC90}.Release|Any CPU.ActiveCfg = Release|Any CPU + {001D0817-1EED-4C04-821E-F815F148EC90}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2580,6 +2592,8 @@ Global {D63FEED3-2342-7E96-4121-B0C19CF1EA81} = {6A3FF105-7E8B-4B4D-A736-1C2BAF86FDAA} {DED16774-635C-D781-4D5B-D1FA56EECF10} = {D01D859E-4B72-478A-BABD-90F0981652D5} {4105FC8B-E8C6-DBD7-FFEA-EA5AB09C7D08} = {F4923692-D343-4318-AECA-96F580B1A563} + {DD11D070-F39E-1C41-1843-AE3ADBE501EF} = {9E72FEB9-A626-4312-892B-CDD043879758} + {001D0817-1EED-4C04-821E-F815F148EC90} = {9E72FEB9-A626-4312-892B-CDD043879758} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718} diff --git a/aspnet-core/services/LY.MicroService.AuthServer/AuthServerModule.Configure.cs b/aspnet-core/services/LY.MicroService.AuthServer/AuthServerModule.Configure.cs index 92b283da7..855c61ac8 100644 --- a/aspnet-core/services/LY.MicroService.AuthServer/AuthServerModule.Configure.cs +++ b/aspnet-core/services/LY.MicroService.AuthServer/AuthServerModule.Configure.cs @@ -28,9 +28,11 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.IdentityModel.Logging; +using Microsoft.IdentityModel.Tokens; using OpenIddict.Validation.AspNetCore; using StackExchange.Redis; using System; +using System.Collections.Generic; using System.Linq; using System.Text.Encodings.Web; using System.Text.Unicode; @@ -47,6 +49,7 @@ using Volo.Abp.Json.SystemTextJson; using Volo.Abp.Localization; using Volo.Abp.MultiTenancy; using Volo.Abp.OpenIddict; +using Volo.Abp.OpenIddict.WildcardDomains; using Volo.Abp.Security.Claims; using Volo.Abp.SettingManagement; using Volo.Abp.Threading; @@ -148,6 +151,16 @@ public partial class AuthServerModule builder.UseAspNetCore() .DisableTransportSecurityRequirement(); }); + + var wildcardDomains = configuration.GetSection("App:WildcardDomains").Get>(); + if (wildcardDomains?.Count > 0) + { + PreConfigure(options => + { + options.EnableWildcardDomainSupport = true; + options.WildcardDomainsFormat.AddIfNotContains(wildcardDomains); + }); + } } private void ConfigureMvc(IServiceCollection services, IConfiguration configuration) @@ -367,11 +380,17 @@ public partial class AuthServerModule .AddJwtBearer(options => { configuration.GetSection("AuthServer").Bind(options); - }) - .AddWeChatWork(options => - { - options.SignInScheme = IdentityConstants.ExternalScheme; + var validIssuers = configuration.GetSection("AuthServer:ValidIssuers").Get>(); + if (validIssuers?.Count > 0) + { + options.TokenValidationParameters.ValidIssuers = validIssuers; + options.TokenValidationParameters.IssuerValidator = TokenWildcardIssuerValidator.IssuerValidator; + } }); + //.AddWeChatWork(options => + //{ + // options.SignInScheme = IdentityConstants.ExternalScheme; + //}); if (!isDevelopment) { diff --git a/aspnet-core/services/LY.MicroService.AuthServer/AuthServerModule.cs b/aspnet-core/services/LY.MicroService.AuthServer/AuthServerModule.cs index 1abcfdf92..160bb7d4a 100644 --- a/aspnet-core/services/LY.MicroService.AuthServer/AuthServerModule.cs +++ b/aspnet-core/services/LY.MicroService.AuthServer/AuthServerModule.cs @@ -1,10 +1,9 @@ using LINGYUN.Abp.Account; +using LINGYUN.Abp.Account.Web.OAuth; using LINGYUN.Abp.Account.Web.OpenIddict; using LINGYUN.Abp.AspNetCore.HttpOverrides; using LINGYUN.Abp.AspNetCore.Mvc.Wrapper; using LINGYUN.Abp.AuditLogging.Elasticsearch; -using LINGYUN.Abp.Authentication.QQ; -using LINGYUN.Abp.Authentication.WeChat; using LINGYUN.Abp.BlobStoring.OssManagement; using LINGYUN.Abp.Data.DbMigrator; using LINGYUN.Abp.Emailing.Platform; @@ -16,7 +15,6 @@ using LINGYUN.Abp.Identity.AspNetCore.Session; using LINGYUN.Abp.Identity.OrganizaztionUnits; using LINGYUN.Abp.Identity.Session.AspNetCore; using LINGYUN.Abp.Localization.CultureMap; -using LINGYUN.Abp.OpenIddict.AspNetCore; using LINGYUN.Abp.OpenIddict.AspNetCore.Session; using LINGYUN.Abp.OpenIddict.LinkUser; using LINGYUN.Abp.OpenIddict.Portal; @@ -27,14 +25,13 @@ using LINGYUN.Abp.Serilog.Enrichers.Application; using LINGYUN.Abp.Serilog.Enrichers.UniqueId; using LINGYUN.Abp.Sms.Platform; using LINGYUN.Abp.Telemetry.SkyWalking; -using LINGYUN.Abp.WeChat.Work.AspNetCore; using LY.MicroService.AuthServer.EntityFrameworkCore; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Volo.Abp; -using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic; +using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite; using Volo.Abp.AspNetCore.Serilog; using Volo.Abp.Autofac; using Volo.Abp.Caching.StackExchangeRedis; @@ -50,11 +47,12 @@ namespace LY.MicroService.AuthServer; typeof(AbpAccountApplicationModule), typeof(AbpAccountHttpApiModule), typeof(AbpAccountWebOpenIddictModule), + typeof(AbpAccountWebOAuthModule), typeof(AbpBlobStoringOssManagementModule), typeof(AbpGdprApplicationModule), typeof(AbpGdprHttpApiModule), typeof(AbpGdprWebModule), - typeof(AbpAspNetCoreMvcUiBasicThemeModule), + typeof(AbpAspNetCoreMvcUiLeptonXLiteThemeModule), typeof(AbpAutofacModule), typeof(AbpCachingStackExchangeRedisModule), typeof(AbpIdentityAspNetCoreSessionModule), @@ -65,9 +63,6 @@ namespace LY.MicroService.AuthServer; typeof(AbpOpenIddictLinkUserModule), typeof(AbpOpenIddictPortalModule), typeof(AbpOpenIddictWeChatWorkModule), - typeof(AbpWeChatWorkAspNetCoreModule), // 实现企业微信登录 - typeof(AbpAuthenticationQQModule), - typeof(AbpAuthenticationWeChatModule), typeof(AbpIdentityOrganizaztionUnitsModule), typeof(AbpPermissionManagementDomainIdentityModule), typeof(AuthServerMigrationsEntityFrameworkCoreModule), 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 ae59c132f..3e66a46de 100644 --- a/aspnet-core/services/LY.MicroService.AuthServer/LY.MicroService.AuthServer.csproj +++ b/aspnet-core/services/LY.MicroService.AuthServer/LY.MicroService.AuthServer.csproj @@ -31,13 +31,10 @@ - - + + @@ -47,8 +44,6 @@ - - @@ -59,13 +54,13 @@ - + @@ -85,10 +80,6 @@ - - - - PreserveNewest diff --git a/aspnet-core/services/LY.MicroService.AuthServer/TokenWildcardIssuerValidator.cs b/aspnet-core/services/LY.MicroService.AuthServer/TokenWildcardIssuerValidator.cs new file mode 100644 index 000000000..3d87d7862 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.AuthServer/TokenWildcardIssuerValidator.cs @@ -0,0 +1,130 @@ +using Microsoft.IdentityModel.Logging; +using Microsoft.IdentityModel.Tokens; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using Volo.Abp.Text.Formatting; + +namespace LY.MicroService.AuthServer; + +/// +/// https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/dev/src/Microsoft.IdentityModel.Tokens/Validators.cs#L207 +/// +public static class TokenWildcardIssuerValidator +{ + private const string IDX10204 = "IDX10204: Unable to validate issuer. validationParameters.ValidIssuer is null or whitespace AND validationParameters.ValidIssuers is null."; + private const string IDX10205 = "IDX10205: Issuer validation failed. Issuer: '{0}'. Did not match: validationParameters.ValidIssuer: '{1}' or validationParameters.ValidIssuers: '{2}'."; + private const string IDX10211 = "IDX10211: Unable to validate issuer. The 'issuer' parameter is null or whitespace"; + private const string IDX10235 = "IDX10235: ValidateIssuer property on ValidationParameters is set to false. Exiting without validating the issuer."; + private const string IDX10236 = "IDX10236: Issuer Validated.Issuer: '{0}'"; + + public static readonly IssuerValidator IssuerValidator = (issuer, token, validationParameters) => + { + if (validationParameters == null) + { + throw LogHelper.LogArgumentNullException(nameof(validationParameters)); + } + + if (!validationParameters.ValidateIssuer) + { + LogHelper.LogInformation(IDX10235); + return issuer; + } + + if (string.IsNullOrWhiteSpace(issuer)) + { + throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidIssuerException(IDX10211) + { + InvalidIssuer = issuer + }); + } + + // Throw if all possible places to validate against are null or empty + if (string.IsNullOrWhiteSpace(validationParameters.ValidIssuer) && + validationParameters.ValidIssuers == null) + { + throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidIssuerException(IDX10204) + { + InvalidIssuer = issuer + }); + } + + if (string.Equals(validationParameters.ValidIssuer, issuer, StringComparison.Ordinal)) + { + LogHelper.LogInformation(IDX10236, issuer); + return issuer; + } + + if (!string.IsNullOrWhiteSpace(validationParameters.ValidIssuer)) + { + var extractResult = FormattedStringValueExtracter.Extract(issuer, validationParameters.ValidIssuer, ignoreCase: true); + if (extractResult.IsMatch && + extractResult.Matches.Aggregate(validationParameters.ValidIssuer, (current, nameValue) => current.Replace($"{{{nameValue.Name}}}", nameValue.Value)) + .IndexOf(issuer, StringComparison.OrdinalIgnoreCase) >= 0) + { + return issuer; + } + } + + if (null != validationParameters.ValidIssuers) + { + foreach (var str in validationParameters.ValidIssuers) + { + if (string.IsNullOrEmpty(str)) + { + LogHelper.LogInformation(IDX10235); + continue; + } + + if (string.Equals(str, issuer, StringComparison.Ordinal)) + { + LogHelper.LogInformation(IDX10236, issuer); + return issuer; + } + + var extractResult = FormattedStringValueExtracter.Extract(issuer, str, ignoreCase: true); + if (extractResult.IsMatch && + extractResult.Matches.Aggregate(str, (current, nameValue) => current.Replace($"{{{nameValue.Name}}}", nameValue.Value)) + .IndexOf(issuer, StringComparison.OrdinalIgnoreCase) >= 0) + { + return issuer; + } + } + } + + throw LogHelper.LogExceptionMessage( + new SecurityTokenInvalidIssuerException(LogHelper.FormatInvariant(IDX10205, issuer, + (validationParameters.ValidIssuer ?? "null"), + SerializeAsSingleCommaDelimitedString(validationParameters.ValidIssuers))) + { + InvalidIssuer = issuer + }); + }; + + private static string SerializeAsSingleCommaDelimitedString(IEnumerable strings) + { + if (strings == null) + { + return Utility.Null; + } + + var sb = new StringBuilder(); + var first = true; + foreach (var str in strings) + { + if (first) + { + sb.AppendFormat(CultureInfo.InvariantCulture, "{0}", str ?? Utility.Null); + first = false; + } + else + { + sb.AppendFormat(CultureInfo.InvariantCulture, ", {0}", str ?? Utility.Null); + } + } + + return first ? Utility.Empty : sb.ToString(); + } +} diff --git a/aspnet-core/services/LY.MicroService.AuthServer/appsettings.Development.json b/aspnet-core/services/LY.MicroService.AuthServer/appsettings.Development.json index bc78dbb5d..62e92ffce 100644 --- a/aspnet-core/services/LY.MicroService.AuthServer/appsettings.Development.json +++ b/aspnet-core/services/LY.MicroService.AuthServer/appsettings.Development.json @@ -135,11 +135,11 @@ }, "Serilog": { "MinimumLevel": { - "Default": "Information", + "Default": "Warning", "Override": { "System": "Warning", "Microsoft": "Warning", - "DotNetCore": "Information" + "DotNetCore": "Warning" } }, "WriteTo": [ diff --git a/aspnet-core/services/LY.MicroService.AuthServer/package.json b/aspnet-core/services/LY.MicroService.AuthServer/package.json index bde2dc451..bc16ffb7e 100644 --- a/aspnet-core/services/LY.MicroService.AuthServer/package.json +++ b/aspnet-core/services/LY.MicroService.AuthServer/package.json @@ -1,9 +1,9 @@ { - "version": "9.0.4", + "version": "9.1.3", "name": "my-app-authserver", "private": true, "dependencies": { - "@abp/aspnetcore.mvc.ui.theme.basic": "9.0.4", - "@abp/qrcode": "9.0.4" + "@abp/aspnetcore.mvc.ui.theme.leptonxlite": "4.1.3", + "@abp/qrcode": "9.1.3" } } \ No newline at end of file