Browse Source

feat(single): 增强单体应用模块

- 重写 `BrandingProvider` 组件,从配置中取值
- 增加账户、身份认证、设置管理、权限管理、功能管理、虚拟文件管理Web视图模块引用
- 增加启用https后的证书配置
- 增加泛域名身份签发者验证
- 增加账户OAuth模块引用
pull/1225/head
colin 8 months ago
parent
commit
b2caaef5b6
  1. 17
      aspnet-core/services/LY.MicroService.Applications.Single/Branding/SingleBrandingProvider.cs
  2. 19
      aspnet-core/services/LY.MicroService.Applications.Single/GlobalUsings.cs
  3. 16
      aspnet-core/services/LY.MicroService.Applications.Single/LY.MicroService.Applications.Single.csproj
  4. 121
      aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.Configure.cs
  5. 23
      aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.cs
  6. 127
      aspnet-core/services/LY.MicroService.Applications.Single/TokenWildcardIssuerValidator.cs
  7. 7
      aspnet-core/services/LY.MicroService.Applications.Single/appsettings.Development.json
  8. 8
      aspnet-core/services/LY.MicroService.Applications.Single/appsettings.json

17
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}";
}
}

19
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;

16
aspnet-core/services/LY.MicroService.Applications.Single/LY.MicroService.Applications.Single.csproj

@ -38,22 +38,28 @@
<PackageReference Include="Volo.Abp.Account.Web.OpenIddict" />
<PackageReference Include="Volo.Abp.AspNetCore.Serilog" />
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy" />
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic" />
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite" />
<!--<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic" />-->
<PackageReference Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" />
<PackageReference Include="Volo.Abp.Autofac" />
<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" />
<PackageReference Include="Volo.Abp.FeatureManagement.Application" />
<PackageReference Include="Volo.Abp.FeatureManagement.EntityFrameworkCore" />
<PackageReference Include="Volo.Abp.FeatureManagement.HttpApi" />
<PackageReference Include="Volo.Abp.FeatureManagement.Web" />
<PackageReference Include="Volo.Abp.PermissionManagement.Application" />
<PackageReference Include="Volo.Abp.PermissionManagement.Domain.Identity" />
<PackageReference Include="Volo.Abp.PermissionManagement.Domain.OpenIddict" />
<PackageReference Include="Volo.Abp.PermissionManagement.HttpApi" />
<PackageReference Include="Volo.Abp.PermissionManagement.EntityFrameworkCore" />
<PackageReference Include="Volo.Abp.PermissionManagement.Web" />
<PackageReference Include="Volo.Abp.SettingManagement.EntityFrameworkCore" />
<PackageReference Include="Volo.Abp.SettingManagement.Web" />
<PackageReference Include="Volo.Abp.Identity.AspNetCore" />
<PackageReference Include="Volo.Abp.Identity.Web" />
<PackageReference Include="Volo.Abp.VirtualFileExplorer.Web" />
<PackageReference Include="Volo.Abp.Imaging.ImageSharp" />
<PackageReference Include="Volo.Abp.MailKit" />
<PackageReference Include="Volo.Abp.SettingManagement.EntityFrameworkCore" />
<PackageReference Include="Volo.Abp.PermissionManagement.EntityFrameworkCore" />
<PackageReference Include="Volo.Abp.OpenIddict.EntityFrameworkCore" />
</ItemGroup>
@ -61,8 +67,6 @@
<ProjectReference Include="..\..\framework\auditing\LINGYUN.Abp.AuditLogging.EntityFrameworkCore\LINGYUN.Abp.AuditLogging.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\framework\auditing\LINGYUN.Abp.AuditLogging.IP.Location\LINGYUN.Abp.AuditLogging.IP.Location.csproj" />
<ProjectReference Include="..\..\framework\auditing\LINGYUN.Abp.AuditLogging\LINGYUN.Abp.AuditLogging.csproj" />
<ProjectReference Include="..\..\framework\authentication\LINGYUN.Abp.Authentication.QQ\LINGYUN.Abp.Authentication.QQ.csproj" />
<ProjectReference Include="..\..\framework\authentication\LINGYUN.Abp.Authentication.WeChat\LINGYUN.Abp.Authentication.WeChat.csproj" />
<ProjectReference Include="..\..\framework\authorization\LINGYUN.Abp.Authorization.OrganizationUnits\LINGYUN.Abp.Authorization.OrganizationUnits.csproj" />
<ProjectReference Include="..\..\framework\cloud-aliyun\LINGYUN.Abp.Aliyun.SettingManagement\LINGYUN.Abp.Aliyun.SettingManagement.csproj" />
<ProjectReference Include="..\..\framework\cloud-aliyun\LINGYUN.Abp.Aliyun\LINGYUN.Abp.Aliyun.csproj" />
@ -111,7 +115,6 @@
<ProjectReference Include="..\..\framework\wechat\LINGYUN.Abp.WeChat.Official.HttpApi\LINGYUN.Abp.WeChat.Official.HttpApi.csproj" />
<ProjectReference Include="..\..\framework\wechat\LINGYUN.Abp.WeChat.SettingManagement\LINGYUN.Abp.WeChat.SettingManagement.csproj" />
<ProjectReference Include="..\..\framework\wechat\LINGYUN.Abp.WeChat.Work.Application\LINGYUN.Abp.WeChat.Work.Application.csproj" />
<ProjectReference Include="..\..\framework\wechat\LINGYUN.Abp.WeChat.Work.AspNetCore\LINGYUN.Abp.WeChat.Work.AspNetCore.csproj" />
<ProjectReference Include="..\..\framework\wechat\LINGYUN.Abp.WeChat.Work.Handlers\LINGYUN.Abp.WeChat.Work.Handlers.csproj" />
<ProjectReference Include="..\..\framework\wechat\LINGYUN.Abp.WeChat.Work.HttpApi\LINGYUN.Abp.WeChat.Work.HttpApi.csproj" />
<ProjectReference Include="..\..\framework\wechat\LINGYUN.Abp.WeChat.Work\LINGYUN.Abp.WeChat.Work.csproj" />
@ -128,6 +131,7 @@
<ProjectReference Include="..\..\modules\account\LINGYUN.Abp.Account.Application\LINGYUN.Abp.Account.Application.csproj" />
<ProjectReference Include="..\..\modules\account\LINGYUN.Abp.Account.Emailing\LINGYUN.Abp.Account.Emailing.csproj" />
<ProjectReference Include="..\..\modules\account\LINGYUN.Abp.Account.HttpApi\LINGYUN.Abp.Account.HttpApi.csproj" />
<ProjectReference Include="..\..\modules\account\LINGYUN.Abp.Account.Web.OAuth\LINGYUN.Abp.Account.Web.OAuth.csproj" />
<ProjectReference Include="..\..\modules\account\LINGYUN.Abp.Account.Web.OpenIddict\LINGYUN.Abp.Account.Web.OpenIddict.csproj" />
<ProjectReference Include="..\..\modules\auditing\LINGYUN.Abp.Auditing.Application.Contracts\LINGYUN.Abp.Auditing.Application.Contracts.csproj" />
<ProjectReference Include="..\..\modules\auditing\LINGYUN.Abp.Auditing.Application\LINGYUN.Abp.Auditing.Application.csproj" />

121
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<AbpOpenIddictAspNetCoreOptions>(options =>
{
var certificate = new X509Certificate2(cerPath, cerConfig["Password"]);
PreConfigure<AbpOpenIddictAspNetCoreOptions>(options =>
{
//https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html
options.AddDevelopmentEncryptionAndSigningCertificate = false;
});
options.AddDevelopmentEncryptionAndSigningCertificate = false;
});
PreConfigure<OpenIddictServerBuilder>(builder =>
{
builder.AddSigningCertificate(certificate);
builder.AddEncryptionCertificate(certificate);
PreConfigure<OpenIddictServerBuilder>(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<bool>("AuthServer:UseOpenIddict"))
PreConfigure<AbpOpenIddictAspNetCoreOptions>(options =>
{
PreConfigure<AbpOpenIddictAspNetCoreOptions>(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<OpenIddictServerBuilder>(builder =>
PreConfigure<OpenIddictServerBuilder>(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<KestrelServerOptions>(options =>
{
options.Limits.MaxRequestBodySize = null;
options.Limits.MaxRequestBufferSize = null;
});
if (!environment.IsDevelopment())
{
Configure<KestrelServerOptions>(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<List<string>>();
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;

23
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());

127
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;
/// <summary>
/// https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/dev/src/Microsoft.IdentityModel.Tokens/Validators.cs#L207
/// </summary>
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<string> 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();
}
}

7
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"
}
},

8
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
},

Loading…
Cancel
Save