From b2caaef5b68d7f461bf0dfb35caf24b9724f6515 Mon Sep 17 00:00:00 2001 From: colin Date: Sat, 7 Jun 2025 18:51:54 +0800 Subject: [PATCH] =?UTF-8?q?feat(single):=20=E5=A2=9E=E5=BC=BA=E5=8D=95?= =?UTF-8?q?=E4=BD=93=E5=BA=94=E7=94=A8=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重写 `BrandingProvider` 组件,从配置中取值 - 增加账户、身份认证、设置管理、权限管理、功能管理、虚拟文件管理Web视图模块引用 - 增加启用https后的证书配置 - 增加泛域名身份签发者验证 - 增加账户OAuth模块引用 --- .../Branding/SingleBrandingProvider.cs | 17 +++ .../GlobalUsings.cs | 19 +-- ...LY.MicroService.Applications.Single.csproj | 16 ++- ...rviceApplicationsSingleModule.Configure.cs | 121 +++++++++-------- .../MicroServiceApplicationsSingleModule.cs | 23 ++-- .../TokenWildcardIssuerValidator.cs | 127 ++++++++++++++++++ .../appsettings.Development.json | 7 +- .../appsettings.json | 8 ++ 8 files changed, 256 insertions(+), 82 deletions(-) create mode 100644 aspnet-core/services/LY.MicroService.Applications.Single/Branding/SingleBrandingProvider.cs create mode 100644 aspnet-core/services/LY.MicroService.Applications.Single/TokenWildcardIssuerValidator.cs diff --git a/aspnet-core/services/LY.MicroService.Applications.Single/Branding/SingleBrandingProvider.cs b/aspnet-core/services/LY.MicroService.Applications.Single/Branding/SingleBrandingProvider.cs new file mode 100644 index 000000000..def50fa02 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.Applications.Single/Branding/SingleBrandingProvider.cs @@ -0,0 +1,17 @@ +using System.Globalization; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Ui.Branding; + +namespace LY.MicroService.Applications.Single.Branding; + +[Dependency(ReplaceServices = true)] +public class SingleBrandingProvider(IConfiguration configuration) : DefaultBrandingProvider +{ + public override string AppName => configuration[GetConfigKey("App:Name")] ?? base.AppName; + public override string LogoUrl => configuration["App:LogoUrl"] ?? base.LogoUrl; + public override string LogoReverseUrl => configuration["App:LogoReverseUrl"] ?? base.LogoUrl; + private static string GetConfigKey(string key) + { + return $"{key}:{CultureInfo.CurrentCulture.TwoLetterISOLanguageName}"; + } +} diff --git a/aspnet-core/services/LY.MicroService.Applications.Single/GlobalUsings.cs b/aspnet-core/services/LY.MicroService.Applications.Single/GlobalUsings.cs index 6a7b94ec5..c4b0eb6e3 100644 --- a/aspnet-core/services/LY.MicroService.Applications.Single/GlobalUsings.cs +++ b/aspnet-core/services/LY.MicroService.Applications.Single/GlobalUsings.cs @@ -2,6 +2,7 @@ global using Elsa; global using Elsa.Options; global using LINGYUN.Abp.Account; +global using LINGYUN.Abp.Account.Web.OAuth; global using LINGYUN.Abp.Account.Web.OpenIddict; global using LINGYUN.Abp.Aliyun.Localization; global using LINGYUN.Abp.Aliyun.SettingManagement; @@ -12,8 +13,6 @@ global using LINGYUN.Abp.AspNetCore.Mvc.Wrapper; global using LINGYUN.Abp.Auditing; global using LINGYUN.Abp.AuditLogging.EntityFrameworkCore; global using LINGYUN.Abp.AuditLogging.IP.Location; -global using LINGYUN.Abp.Authentication.QQ; -global using LINGYUN.Abp.Authentication.WeChat; global using LINGYUN.Abp.Authorization.OrganizationUnits; global using LINGYUN.Abp.BackgroundTasks; global using LINGYUN.Abp.BackgroundTasks.Activities; @@ -56,6 +55,7 @@ global using LINGYUN.Abp.Identity.OrganizaztionUnits; global using LINGYUN.Abp.Identity.Session; global using LINGYUN.Abp.Identity.Session.AspNetCore; global using LINGYUN.Abp.Identity.WeChat; +global using LINGYUN.Abp.Identity.WeChat.Work; global using LINGYUN.Abp.IdGenerator; global using LINGYUN.Abp.IM.SignalR; global using LINGYUN.Abp.IP2Region; @@ -70,7 +70,9 @@ global using LINGYUN.Abp.Notifications.Common; global using LINGYUN.Abp.Notifications.Emailing; global using LINGYUN.Abp.Notifications.EntityFrameworkCore; global using LINGYUN.Abp.Notifications.SignalR; +global using LINGYUN.Abp.Notifications.Templating; global using LINGYUN.Abp.Notifications.WeChat.MiniProgram; +global using LINGYUN.Abp.Notifications.WeChat.Work; global using LINGYUN.Abp.OpenApi.Authorization; global using LINGYUN.Abp.OpenIddict; global using LINGYUN.Abp.OpenIddict.AspNetCore.Session; @@ -84,6 +86,7 @@ global using LINGYUN.Abp.OpenIddict.WeChat.Work; global using LINGYUN.Abp.OssManagement; global using LINGYUN.Abp.OssManagement.FileSystem; global using LINGYUN.Abp.OssManagement.Imaging; +global using LINGYUN.Abp.OssManagement.Minio; global using LINGYUN.Abp.OssManagement.SettingManagement; global using LINGYUN.Abp.PermissionManagement.HttpApi; global using LINGYUN.Abp.PermissionManagement.OrganizationUnits; @@ -101,10 +104,6 @@ global using LINGYUN.Abp.Tencent.SettingManagement; global using LINGYUN.Abp.TextTemplating; global using LINGYUN.Abp.TextTemplating.EntityFrameworkCore; global using LINGYUN.Abp.UI.Navigation; -global using LINGYUN.Abp.Identity.WeChat.Work; -global using LINGYUN.Abp.Notifications.Templating; -global using LINGYUN.Abp.Notifications.WeChat.Work; -global using LINGYUN.Abp.OssManagement.Minio; global using LINGYUN.Abp.UI.Navigation.VueVbenAdmin5; global using LINGYUN.Abp.Webhooks; global using LINGYUN.Abp.Webhooks.EventBus; @@ -119,7 +118,6 @@ global using LINGYUN.Abp.WeChat.Official; global using LINGYUN.Abp.WeChat.Official.Handlers; global using LINGYUN.Abp.WeChat.SettingManagement; global using LINGYUN.Abp.WeChat.Work; -global using LINGYUN.Abp.WeChat.Work.AspNetCore; global using LINGYUN.Abp.WeChat.Work.Handlers; global using LINGYUN.Abp.Wrapper; global using LINGYUN.Platform; @@ -155,7 +153,8 @@ global using Volo.Abp.AspNetCore.Authentication.JwtBearer; global using Volo.Abp.AspNetCore.Mvc; global using Volo.Abp.AspNetCore.Mvc.AntiForgery; global using Volo.Abp.AspNetCore.Mvc.UI.Bundling; -global using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic; +//global using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic; +global using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite; global using Volo.Abp.AspNetCore.Serilog; global using Volo.Abp.Auditing; global using Volo.Abp.Authorization.Permissions; @@ -172,6 +171,7 @@ global using Volo.Abp.Features; global using Volo.Abp.GlobalFeatures; global using Volo.Abp.Http.Client; global using Volo.Abp.Identity.Localization; +global using Volo.Abp.Identity.Web; global using Volo.Abp.Imaging; global using Volo.Abp.Json; global using Volo.Abp.Json.SystemTextJson; @@ -186,12 +186,15 @@ global using Volo.Abp.PermissionManagement; global using Volo.Abp.PermissionManagement.EntityFrameworkCore; global using Volo.Abp.PermissionManagement.Identity; global using Volo.Abp.PermissionManagement.OpenIddict; +global using Volo.Abp.PermissionManagement.Web; global using Volo.Abp.Quartz; global using Volo.Abp.Security.Claims; global using Volo.Abp.SettingManagement; global using Volo.Abp.SettingManagement.EntityFrameworkCore; global using Volo.Abp.SettingManagement.Localization; +global using Volo.Abp.SettingManagement.Web; global using Volo.Abp.Sms; global using Volo.Abp.Threading; global using Volo.Abp.UI.Navigation.Urls; +global using Volo.Abp.VirtualFileExplorer.Web; global using Volo.Abp.VirtualFileSystem; diff --git a/aspnet-core/services/LY.MicroService.Applications.Single/LY.MicroService.Applications.Single.csproj b/aspnet-core/services/LY.MicroService.Applications.Single/LY.MicroService.Applications.Single.csproj index 7928ca5d8..937882672 100644 --- a/aspnet-core/services/LY.MicroService.Applications.Single/LY.MicroService.Applications.Single.csproj +++ b/aspnet-core/services/LY.MicroService.Applications.Single/LY.MicroService.Applications.Single.csproj @@ -38,22 +38,28 @@ - + + + + + + + + + - - @@ -61,8 +67,6 @@ - - @@ -111,7 +115,6 @@ - @@ -128,6 +131,7 @@ + diff --git a/aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.Configure.cs b/aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.Configure.cs index 3226c5afc..897e53079 100644 --- a/aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.Configure.cs +++ b/aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.Configure.cs @@ -1,6 +1,7 @@ using LINGYUN.Abp.Identity.QrCode; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; using OpenIddict.Validation.AspNetCore; using Volo.Abp.BlobStoring.Minio; using VoloAbpExceptionHandlingOptions = Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingOptions; @@ -86,73 +87,59 @@ public partial class MicroServiceApplicationsSingleModule private void PreConfigureCertificate(IConfiguration configuration, IWebHostEnvironment environment) { - var cerConfig = configuration.GetSection("Certificates"); - if (environment.IsProduction() && cerConfig.Exists()) + if (!environment.IsDevelopment()) { - // 开发环境下存在证书配置 - // 且证书文件存在则使用自定义的证书文件来启动Ids服务器 - var cerPath = Path.Combine(environment.ContentRootPath, cerConfig["CerPath"]); - if (File.Exists(cerPath)) + PreConfigure(options => { - var certificate = new X509Certificate2(cerPath, cerConfig["Password"]); - - PreConfigure(options => - { - //https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html - options.AddDevelopmentEncryptionAndSigningCertificate = false; - }); + options.AddDevelopmentEncryptionAndSigningCertificate = false; + }); - PreConfigure(builder => - { - builder.AddSigningCertificate(certificate); - builder.AddEncryptionCertificate(certificate); + PreConfigure(builder => + { + builder.UseDataProtection(); - builder.UseDataProtection(); + // 禁用https + builder.UseAspNetCore() + .DisableTransportSecurityRequirement(); - // 禁用https - builder.UseAspNetCore() - .DisableTransportSecurityRequirement(); - }); - } + builder.AddProductionEncryptionAndSigningCertificate(configuration["App:SslFile"], configuration["App:SslPassword"]); + }); } else { - if (configuration.GetValue("AuthServer:UseOpenIddict")) + PreConfigure(options => { - PreConfigure(options => - { - //https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html - options.AddDevelopmentEncryptionAndSigningCertificate = false; - }); + //https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html + options.AddDevelopmentEncryptionAndSigningCertificate = false; + }); - PreConfigure(builder => + PreConfigure(builder => + { + //https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html + using (var algorithm = RSA.Create(keySizeInBits: 2048)) { - //https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html - using (var algorithm = RSA.Create(keySizeInBits: 2048)) - { - var subject = new X500DistinguishedName("CN=Fabrikam Encryption Certificate"); - var request = new CertificateRequest(subject, algorithm, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); - request.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature, critical: true)); - var certificate = request.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddYears(2)); - builder.AddSigningCertificate(certificate); - } + var subject = new X500DistinguishedName("CN=Fabrikam Encryption Certificate"); + var request = new CertificateRequest(subject, algorithm, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); + request.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature, critical: true)); + var certificate = request.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddYears(2)); + builder.AddSigningCertificate(certificate); + } - using (var algorithm = RSA.Create(keySizeInBits: 2048)) - { - var subject = new X500DistinguishedName("CN=Fabrikam Signing Certificate"); - var request = new CertificateRequest(subject, algorithm, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); - request.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.KeyEncipherment, critical: true)); - var certificate = request.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddYears(2)); - builder.AddEncryptionCertificate(certificate); - } + using (var algorithm = RSA.Create(keySizeInBits: 2048)) + { + var subject = new X500DistinguishedName("CN=Fabrikam Signing Certificate"); + var request = new CertificateRequest(subject, algorithm, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); + request.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.KeyEncipherment, critical: true)); + var certificate = request.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddYears(2)); + builder.AddEncryptionCertificate(certificate); + } - builder.UseDataProtection(); + builder.UseDataProtection(); - // 禁用https - builder.UseAspNetCore() - .DisableTransportSecurityRequirement(); - }); - } + // 禁用https + builder.UseAspNetCore() + .DisableTransportSecurityRequirement(); + }); } } @@ -304,13 +291,26 @@ public partial class MicroServiceApplicationsSingleModule //}); } - private void ConfigureKestrelServer() + private void ConfigureKestrelServer(IConfiguration configuration, IWebHostEnvironment environment) { Configure(options => { options.Limits.MaxRequestBodySize = null; options.Limits.MaxRequestBufferSize = null; }); + + if (!environment.IsDevelopment()) + { + Configure(options => + { + options.ConfigureHttpsDefaults(https => + { + https.ServerCertificate = X509CertificateLoader.LoadPkcs12FromFile( + configuration["App:SslFile"], + configuration["App:SslPassword"]); + }); + }); + } } private void ConfigureOssManagement(IServiceCollection services, IConfiguration configuration) @@ -824,6 +824,13 @@ public partial class MicroServiceApplicationsSingleModule { configuration.GetSection("AuthServer").Bind(options); + var validIssuers = configuration.GetSection("AuthServer:ValidIssuers").Get>(); + if (validIssuers?.Count > 0) + { + options.TokenValidationParameters.ValidIssuers = validIssuers; + options.TokenValidationParameters.IssuerValidator = TokenWildcardIssuerValidator.IssuerValidator; + } + options.Events ??= new JwtBearerEvents(); options.Events.OnMessageReceived = context => { @@ -836,10 +843,6 @@ public partial class MicroServiceApplicationsSingleModule } return Task.CompletedTask; }; - }) - .AddWeChatWork(options => - { - options.SignInScheme = IdentityConstants.ExternalScheme; }); services.ConfigureApplicationCookie(options => @@ -847,7 +850,7 @@ public partial class MicroServiceApplicationsSingleModule options.Events.OnRedirectToLogin = (ctx) => { if (ctx.Request.Path.Value.StartsWith("/api") || - ctx.Request.Path.Value.StartsWith("/connect")) + ctx.Request.Path.Value.StartsWith("/connect/token")) { ctx.Response.Clear(); ctx.Response.StatusCode = 401; diff --git a/aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.cs b/aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.cs index ee93906bc..8388f5609 100644 --- a/aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.cs +++ b/aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.cs @@ -29,6 +29,8 @@ namespace LY.MicroService.Applications.Single; typeof(AbpIdentityHttpApiModule), // 身份认证模块 实体框架 typeof(AbpIdentityEntityFrameworkCoreModule), + // 身份认证模块 Mvc视图 + typeof(AbpIdentityWebModule), // 账户模块 应用服务 typeof(AbpAccountApplicationModule), @@ -36,6 +38,8 @@ namespace LY.MicroService.Applications.Single; typeof(AbpAccountHttpApiModule), // 账户模块 OpenIddict集成 typeof(AbpAccountWebOpenIddictModule), + // 账户模块 OAuth集成 + typeof(AbpAccountWebOAuthModule), // Gdpr 身份认证提供者模块 typeof(AbpGdprDomainIdentityModule), @@ -49,7 +53,8 @@ namespace LY.MicroService.Applications.Single; typeof(AbpGdprWebModule), // MVC Theme - typeof(AbpAspNetCoreMvcUiBasicThemeModule), + //typeof(AbpAspNetCoreMvcUiBasicThemeModule), + typeof(AbpAspNetCoreMvcUiLeptonXLiteThemeModule), // 审计日志模块 应用服务 typeof(AbpAuditingApplicationModule), @@ -212,6 +217,8 @@ namespace LY.MicroService.Applications.Single; typeof(AbpSettingManagementHttpApiModule), // 设置管理模块 实体框架 typeof(AbpSettingManagementEntityFrameworkCoreModule), + // 设置管理模块 Mvc视图 + typeof(AbpSettingManagementWebModule), // 权限管理模块 应用服务 typeof(LINGYUN.Abp.PermissionManagement.AbpPermissionManagementApplicationModule), @@ -226,16 +233,14 @@ namespace LY.MicroService.Applications.Single; typeof(AbpPermissionManagementEntityFrameworkCoreModule), // 权限管理模块 组织机构集成 typeof(AbpPermissionManagementDomainOrganizationUnitsModule), // 组织机构权限管理 + // 权限管理模块 Mvc视图 + typeof(AbpPermissionManagementWebModule), // 短信模块 阿里云集成 typeof(AbpAliyunSmsModule), // 阿里云模块 设置管理 typeof(AbpAliyunSettingManagementModule), - // 认证模块 腾讯QQ集成 - typeof(AbpAuthenticationQQModule), - // 认证模块 微信集成 - typeof(AbpAuthenticationWeChatModule), // 认证模块 JWT认证 typeof(AbpAspNetCoreAuthenticationJwtBearerModule), // 授权模块 组织机构集成 @@ -283,6 +288,8 @@ namespace LY.MicroService.Applications.Single; typeof(AbpFeaturesLimitValidationModule), // 客户端功能限制模块 Redis集成 typeof(AbpFeaturesValidationRedisClientModule), + // 功能管理模块 Mvc视图 + typeof(AbpFeatureManagementWebModule), // 多语言模块 typeof(AbpAspNetCoreMvcLocalizationModule), // 多语言模块 语言映射 @@ -334,8 +341,6 @@ namespace LY.MicroService.Applications.Single; typeof(AbpWeChatOfficialHandlersModule), // 微信模块 企业微信 事件处理 typeof(AbpWeChatWorkHandlersModule), - // 认证模块 企业微信 - typeof(AbpWeChatWorkAspNetCoreModule), // 微信模块 设置管理 typeof(AbpWeChatSettingManagementModule), @@ -360,6 +365,8 @@ namespace LY.MicroService.Applications.Single; // 数据导出模块 MiniExcel集成 typeof(AbpExporterMiniExcelModule), + // 虚拟文件浏览器 Mvc视图 + typeof(AbpVirtualFileExplorerWebModule), typeof(AbpHttpClientWrapperModule), typeof(AbpAspNetCoreMvcWrapperModule), typeof(AbpAspNetCoreMvcIdempotentWrapperModule), @@ -402,7 +409,6 @@ public partial class MicroServiceApplicationsSingleModule : AbpModule ConfigureIdempotent(); ConfigureMvcUiTheme(); ConfigureLocalization(); - ConfigureKestrelServer(); ConfigureBackgroundTasks(); ConfigureExceptionHandling(); ConfigureVirtualFileSystem(); @@ -426,6 +432,7 @@ public partial class MicroServiceApplicationsSingleModule : AbpModule ConfigureCors(context.Services, configuration); ConfigureOssManagement(context.Services, configuration); ConfigureDistributedLock(context.Services, configuration); + ConfigureKestrelServer(configuration, hostingEnvironment); ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment()); ConfigureSingleModule(context.Services, hostingEnvironment.IsDevelopment()); diff --git a/aspnet-core/services/LY.MicroService.Applications.Single/TokenWildcardIssuerValidator.cs b/aspnet-core/services/LY.MicroService.Applications.Single/TokenWildcardIssuerValidator.cs new file mode 100644 index 000000000..57b993557 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.Applications.Single/TokenWildcardIssuerValidator.cs @@ -0,0 +1,127 @@ +using Microsoft.IdentityModel.Tokens; +using System.Globalization; +using System.Text; +using Volo.Abp.Text.Formatting; + +namespace LY.MicroService.Applications.Single; + +/// +/// 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.Applications.Single/appsettings.Development.json b/aspnet-core/services/LY.MicroService.Applications.Single/appsettings.Development.json index 8cb0069e9..7e7570be8 100644 --- a/aspnet-core/services/LY.MicroService.Applications.Single/appsettings.Development.json +++ b/aspnet-core/services/LY.MicroService.Applications.Single/appsettings.Development.json @@ -2,7 +2,7 @@ "App": { "ShowPii": true, "SelfUrl": "http://127.0.0.1:30001/", - "CorsOrigins": "http://127.0.0.1:3100,http://127.0.0.1:30001", + "CorsOrigins": "http://127.0.0.1:3100,http://localhost:5666,http://127.0.0.1:30001", "Urls": { "Applications": { "MVC": { @@ -171,6 +171,10 @@ }, "InternalService": { "ClientId": "InternalServiceClient" + }, + "OAuthClient": { + "ClientId": "vue-oauth-client", + "RootUrl": "http://localhost:5666" } }, "Lifetime": { @@ -249,6 +253,7 @@ "Override": { "System": "Warning", "Microsoft": "Warning", + "Microsoft.EntityFrameworkCore": "Warning", "DotNetCore": "Warning" } }, diff --git a/aspnet-core/services/LY.MicroService.Applications.Single/appsettings.json b/aspnet-core/services/LY.MicroService.Applications.Single/appsettings.json index d822f1bc2..080b0b1d6 100644 --- a/aspnet-core/services/LY.MicroService.Applications.Single/appsettings.json +++ b/aspnet-core/services/LY.MicroService.Applications.Single/appsettings.json @@ -1,4 +1,12 @@ { + "App": { + "Name": { + "zh": "身份认证服务器", + "en": "Identity authentication server" + }, + "SslFile": "openiddict.pfx", + "SslPassword": "e1c48393-0c43-11f0-9582-4aecacda42db" + }, "CAP": { "IsEnabled": false },