From abf07bae29e1f86ee519552dfff7666aab502acd Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Fri, 29 Oct 2021 15:48:55 +0800 Subject: [PATCH] feat(module): adjust module structure --- aspnet-core/LINGYUN.MicroService.All.sln | 48 ++ .../appsettings.Development.json | 114 ---- .../appsettings.Development.json | 143 ----- .../appsettings.Development.json | 107 ---- .../appsettings.Development.json | 119 ----- .../README.md | 32 ++ .../Abp/Auditing/Logging/Dto/LogFieldDto.cs | 2 + .../Auditing/Logging/Dto/LogGetByPagedDto.cs | 2 + .../Abp/Auditing/Logging/LogAppService.cs | 9 +- .../SerilogElasticsearchLoggingManager.cs | 18 + .../Serilog/Elasticsearch/SerilogField.cs | 6 + .../README.md | 32 ++ .../AbpLoggingEnricherPropertyNames.cs | 8 + .../Abp/AuditLogging/AbpLoggingModule.cs | 8 +- .../Abp/AuditLogging/DefaultLoggingManager.cs | 37 +- .../Abp/AuditLogging/ILoggingManager.cs | 4 + .../LINGYUN/Abp/AuditLogging/LogField.cs | 2 + .../logging/LINGYUN.Abp.Logging/README.md | 31 ++ .../AuthIdentityServerModule.Configure.cs | 169 ++++++ .../AuthIdentityServerModule.Seeder.cs | 23 + .../AuthIdentityServerModule.cs | 496 ++++++------------ .../AuthServer.Host/AuthServer.Host.csproj | 4 + .../appsettings.Development.json | 118 +++++ .../account/AuthServer.Host/appsettings.json} | 175 +++--- .../BackendAdminHostModule.Configure.cs | 259 +++++++++ .../BackendAdminHostModule.Development.cs | 17 + .../BackendAdminHostModule.Seeder.cs | 23 + .../BackendAdminHostModule.cs | 288 +--------- .../BackendAdminHostMigrationsDbContext.cs | 58 +- ...NGYUN.Abp.BackendAdmin.HttpApi.Host.csproj | 9 +- .../Properties/launchSettings.json | 2 +- .../appsettings.Development.json | 92 ++++ .../appsettings.json | 72 +++ .../ApiGatewayHostModule.cs | 24 +- .../LINGYUN.ApiGateway.Host.csproj | 5 +- .../appsettings.Development.json | 79 +++ .../LINGYUN.ApiGateway.Host/appsettings.json} | 167 +++--- .../ApiGatewayHttpApiHostModule.Configure.cs | 179 +++++++ .../ApiGatewayHttpApiHostModule.Seeder.cs | 24 + .../ApiGatewayHttpApiHostModule.cs | 356 ++++--------- .../LINGYUN.ApiGateway.HttpApi.Host.csproj | 7 +- .../appsettings.Development.json | 72 +++ .../appsettings.json} | 163 +++--- ...yServerAdminHttpApiHostModule.Configure.cs | 247 +++++++++ ...tityServerAdminHttpApiHostModule.Seeder.cs | 11 + ...AbpIdentityServerAdminHttpApiHostModule.cs | 421 ++++----------- ...UN.Abp.IdentityServer4.HttpApi.Host.csproj | 21 +- .../appsettings.Development.json | 74 +++ .../appsettings.json} | 169 +++--- ...onManagementHttpApiHostModule.Configure.cs | 198 +++++++ ...ationManagementHttpApiHostModule.Seeder.cs | 21 + ...LocalizationManagementHttpApiHostModule.cs | 369 ++++--------- ...LocalizationManagement.HttpApi.Host.csproj | 4 + ...ssageServiceHttpApiHostModule.Configure.cs | 239 +++++++++ ...pMessageServiceHttpApiHostModule.Seeder.cs | 21 + .../AbpMessageServiceHttpApiHostModule.cs | 225 +------- ...YUN.Abp.MessageService.HttpApi.Host.csproj | 19 +- .../AppPlatformHttpApiHostModule.Configure.cs | 243 +++++++++ .../AppPlatformHttpApiHostModule.Seeder.cs | 21 + .../AppPlatformHttpApiHostModule.cs | 252 +-------- .../LINGYUN.Platform.HttpApi.Host.csproj | 21 +- 61 files changed, 3359 insertions(+), 2820 deletions(-) delete mode 100644 aspnet-core/configuration/account/AuthServer.Host/appsettings.Development.json delete mode 100644 aspnet-core/configuration/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/appsettings.Development.json delete mode 100644 aspnet-core/configuration/messages/LINGYUN.Abp.MessageService.HttpApi.Host/appsettings.Development.json delete mode 100644 aspnet-core/configuration/platform/LINGYUN.Platform.HttpApi.Host/appsettings.Development.json create mode 100644 aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.EntityFrameworkCore/README.md create mode 100644 aspnet-core/modules/logging/LINGYUN.Abp.Logging.Serilog.Elasticsearch/README.md create mode 100644 aspnet-core/modules/logging/LINGYUN.Abp.Logging/LINGYUN/Abp/AuditLogging/AbpLoggingEnricherPropertyNames.cs create mode 100644 aspnet-core/modules/logging/LINGYUN.Abp.Logging/README.md create mode 100644 aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.Configure.cs create mode 100644 aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.Seeder.cs create mode 100644 aspnet-core/services/account/AuthServer.Host/appsettings.Development.json rename aspnet-core/{configuration/apigateway/LINGYUN.ApiGateway.Host/appsettings.Development.json => services/account/AuthServer.Host/appsettings.json} (60%) create mode 100644 aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/BackendAdminHostModule.Configure.cs create mode 100644 aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/BackendAdminHostModule.Development.cs create mode 100644 aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/BackendAdminHostModule.Seeder.cs create mode 100644 aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/appsettings.Development.json create mode 100644 aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/appsettings.json create mode 100644 aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/appsettings.Development.json rename aspnet-core/{configuration/apigateway/LINGYUN.ApiGateway.HttpApi.Host/appsettings.Development.json => services/apigateway/LINGYUN.ApiGateway.Host/appsettings.json} (62%) create mode 100644 aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/ApiGatewayHttpApiHostModule.Configure.cs create mode 100644 aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/ApiGatewayHttpApiHostModule.Seeder.cs create mode 100644 aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/appsettings.Development.json rename aspnet-core/{configuration/localization/LINGYUN.Abp.LocalizationManagement.HttpApi.Host/appsettings.Development.json => services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/appsettings.json} (59%) create mode 100644 aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/AbpIdentityServerAdminHttpApiHostModule.Configure.cs create mode 100644 aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/AbpIdentityServerAdminHttpApiHostModule.Seeder.cs create mode 100644 aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/appsettings.Development.json rename aspnet-core/{configuration/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/appsettings.Development.json => services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/appsettings.json} (55%) create mode 100644 aspnet-core/services/localization/LINGYUN.Abp.LocalizationManagement.HttpApi.Host/AbpLocalizationManagementHttpApiHostModule.Configure.cs create mode 100644 aspnet-core/services/localization/LINGYUN.Abp.LocalizationManagement.HttpApi.Host/AbpLocalizationManagementHttpApiHostModule.Seeder.cs create mode 100644 aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/AbpMessageServiceHttpApiHostModule.Configure.cs create mode 100644 aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/AbpMessageServiceHttpApiHostModule.Seeder.cs create mode 100644 aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.Configure.cs create mode 100644 aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.Seeder.cs diff --git a/aspnet-core/LINGYUN.MicroService.All.sln b/aspnet-core/LINGYUN.MicroService.All.sln index c74f1e080..617d14485 100644 --- a/aspnet-core/LINGYUN.MicroService.All.sln +++ b/aspnet-core/LINGYUN.MicroService.All.sln @@ -333,6 +333,22 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Hangfire.Dashbo EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.WeChat", "modules\wechat\LINGYUN.Abp.Identity.WeChat\LINGYUN.Abp.Identity.WeChat.csproj", "{BC518F26-996E-4DF0-BB44-783EB1C275D2}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "logging", "logging", "{6FC0578B-CDF1-43AD-9F7E-4AA7E4720A02}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "elasticsearch", "elasticsearch", "{B981DD7D-7083-4C7A-9A5F-B8CFAE7B670B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Elasticsearch", "modules\elasticsearch\LINGYUN.Abp.Elasticsearch\LINGYUN.Abp.Elasticsearch.csproj", "{63D1DC91-C7C7-491A-8423-B0B89F39443F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Logging", "modules\logging\LINGYUN.Abp.Logging\LINGYUN.Abp.Logging.csproj", "{1E0E82D2-F53A-4326-9E39-D7D677590543}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Logging.Serilog.Elasticsearch", "modules\logging\LINGYUN.Abp.Logging.Serilog.Elasticsearch\LINGYUN.Abp.Logging.Serilog.Elasticsearch.csproj", "{D82DB535-67FB-4712-B3EC-9A7A1EA6F7E9}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AuditLogging", "modules\auditing\LINGYUN.Abp.AuditLogging\LINGYUN.Abp.AuditLogging.csproj", "{6C3D4C1C-4864-44A9-8649-9856ABF667FA}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AuditLogging.Elasticsearch", "modules\auditing\LINGYUN.Abp.AuditLogging.Elasticsearch\LINGYUN.Abp.AuditLogging.Elasticsearch.csproj", "{AD3CC5B5-366B-4E34-8E80-EC5BB68B573A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AuditLogging.EntityFrameworkCore", "modules\auditing\LINGYUN.Abp.AuditLogging.EntityFrameworkCore\LINGYUN.Abp.AuditLogging.EntityFrameworkCore.csproj", "{F71A0D28-397D-4094-B1C2-7925E1310676}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -871,6 +887,30 @@ Global {BC518F26-996E-4DF0-BB44-783EB1C275D2}.Debug|Any CPU.Build.0 = Debug|Any CPU {BC518F26-996E-4DF0-BB44-783EB1C275D2}.Release|Any CPU.ActiveCfg = Release|Any CPU {BC518F26-996E-4DF0-BB44-783EB1C275D2}.Release|Any CPU.Build.0 = Release|Any CPU + {63D1DC91-C7C7-491A-8423-B0B89F39443F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {63D1DC91-C7C7-491A-8423-B0B89F39443F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {63D1DC91-C7C7-491A-8423-B0B89F39443F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {63D1DC91-C7C7-491A-8423-B0B89F39443F}.Release|Any CPU.Build.0 = Release|Any CPU + {1E0E82D2-F53A-4326-9E39-D7D677590543}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1E0E82D2-F53A-4326-9E39-D7D677590543}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1E0E82D2-F53A-4326-9E39-D7D677590543}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1E0E82D2-F53A-4326-9E39-D7D677590543}.Release|Any CPU.Build.0 = Release|Any CPU + {D82DB535-67FB-4712-B3EC-9A7A1EA6F7E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D82DB535-67FB-4712-B3EC-9A7A1EA6F7E9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D82DB535-67FB-4712-B3EC-9A7A1EA6F7E9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D82DB535-67FB-4712-B3EC-9A7A1EA6F7E9}.Release|Any CPU.Build.0 = Release|Any CPU + {6C3D4C1C-4864-44A9-8649-9856ABF667FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6C3D4C1C-4864-44A9-8649-9856ABF667FA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6C3D4C1C-4864-44A9-8649-9856ABF667FA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6C3D4C1C-4864-44A9-8649-9856ABF667FA}.Release|Any CPU.Build.0 = Release|Any CPU + {AD3CC5B5-366B-4E34-8E80-EC5BB68B573A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AD3CC5B5-366B-4E34-8E80-EC5BB68B573A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AD3CC5B5-366B-4E34-8E80-EC5BB68B573A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AD3CC5B5-366B-4E34-8E80-EC5BB68B573A}.Release|Any CPU.Build.0 = Release|Any CPU + {F71A0D28-397D-4094-B1C2-7925E1310676}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F71A0D28-397D-4094-B1C2-7925E1310676}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F71A0D28-397D-4094-B1C2-7925E1310676}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F71A0D28-397D-4094-B1C2-7925E1310676}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1035,6 +1075,14 @@ Global {60D0BEF2-FEAF-4066-8377-6C873CB24858} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E} {340BE5AC-68EC-41A5-9D0D-266037C58F13} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E} {BC518F26-996E-4DF0-BB44-783EB1C275D2} = {DD9BE9E7-F6BF-4869-BCD2-82F5072BDA21} + {6FC0578B-CDF1-43AD-9F7E-4AA7E4720A02} = {C5CAD011-DF84-4914-939C-0C029DCEF26F} + {B981DD7D-7083-4C7A-9A5F-B8CFAE7B670B} = {C5CAD011-DF84-4914-939C-0C029DCEF26F} + {63D1DC91-C7C7-491A-8423-B0B89F39443F} = {B981DD7D-7083-4C7A-9A5F-B8CFAE7B670B} + {1E0E82D2-F53A-4326-9E39-D7D677590543} = {6FC0578B-CDF1-43AD-9F7E-4AA7E4720A02} + {D82DB535-67FB-4712-B3EC-9A7A1EA6F7E9} = {6FC0578B-CDF1-43AD-9F7E-4AA7E4720A02} + {6C3D4C1C-4864-44A9-8649-9856ABF667FA} = {67DAB2A0-D407-4CAB-8414-AE3D0AC52FC4} + {AD3CC5B5-366B-4E34-8E80-EC5BB68B573A} = {67DAB2A0-D407-4CAB-8414-AE3D0AC52FC4} + {F71A0D28-397D-4094-B1C2-7925E1310676} = {67DAB2A0-D407-4CAB-8414-AE3D0AC52FC4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718} diff --git a/aspnet-core/configuration/account/AuthServer.Host/appsettings.Development.json b/aspnet-core/configuration/account/AuthServer.Host/appsettings.Development.json deleted file mode 100644 index e0914e0d8..000000000 --- a/aspnet-core/configuration/account/AuthServer.Host/appsettings.Development.json +++ /dev/null @@ -1,114 +0,0 @@ -{ - "App": { - "TrackingEntitiesChanged": true, - "SelfUrl": "http://localhost:44385/", - "CorsOrigins": "http://localhost:4200,http://localhost:9528,http://127.0.0.1:63898" - }, - "AppSelfUrl": "http://localhost:44385/", - "ConnectionStrings": { - "Default": "Server=127.0.0.1;Database=IdentityServer;User Id=root;Password=123456", - "AbpIdentity": "Server=127.0.0.1;Database=IdentityServer;User Id=root;Password=123456", - "AbpIdentityServer": "Server=127.0.0.1;Database=IdentityServer;User Id=root;Password=123456", - "AbpTenantManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpSettingManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpPermissionManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpFeatureManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456" - }, - "CAP": { - "EventBus": { - "DefaultGroupName": "AuthServer", - "Version": "v1", - "FailedRetryInterval": 300, - "FailedRetryCount": 10 - }, - "RabbitMQ": { - "HostName": "127.0.0.1", - "Port": 5672, - "UserName": "admin", - "Password": "admin", - "ExchangeName": "LINGYUN.AbpApplication", - "VirtualHost": "multi.service.test" - } - }, - "Redis": { - "Configuration": "127.0.0.1", - "InstanceName": "LINGYUN.AbpApplication", - "DefaultDatabase": 10 - }, - "AuthServer": { - "Authority": "http://localhost:44385/", - "ApiName": "lingyun-abp-application" - }, - "IdentityServer": { - "Clients": { - "AuthManagement": { - "ClientId": "auth-management", - "RootUrl": "http://localhost:44313/" - }, - "AuthVueAdmin": { - "ClientId": "vue-admin-element" - }, - "AuthApiGateway": { - "ClientId": "ApigatewayHostClient" - } - } - }, - "Serilog": { - "MinimumLevel": { - "Default": "Information", - "Override": { - "System": "Warning", - "Microsoft": "Warning", - "DotNetCore": "Information" - } - }, - "Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId" ], - "WriteTo": [ - { - "Name": "File", - "Args": { - "path": "Logs/Debug-.log", - "restrictedToMinimumLevel": "Debug", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Info-.log", - "restrictedToMinimumLevel": "Information", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Warn-.log", - "restrictedToMinimumLevel": "Warning", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Error-.log", - "restrictedToMinimumLevel": "Error", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Fatal-.log", - "restrictedToMinimumLevel": "Fatal", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - } - ] - } -} diff --git a/aspnet-core/configuration/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/appsettings.Development.json b/aspnet-core/configuration/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/appsettings.Development.json deleted file mode 100644 index 457fc7f90..000000000 --- a/aspnet-core/configuration/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/appsettings.Development.json +++ /dev/null @@ -1,143 +0,0 @@ -{ - "App": { - "TrackingEntitiesChanged": true, - "SelfUrl": "http://localhost:44385/" - }, - "ConnectionStrings": { - "Default": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpIdentity": "Server=127.0.0.1;Database=IdentityServer;User Id=root;Password=123456", - "AbpIdentityServer": "Server=127.0.0.1;Database=IdentityServer;User Id=root;Password=123456", - "AbpTenantManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpSettingManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpPermissionManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpLocalizationManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456" - }, - "Logging": { - "Serilog": { - "Elasticsearch": { - "IndexFormat": "linyun.abp.logging-{0:yyyy.MM.dd}" - } - } - }, - "AuditLogging": { - "Elasticsearch": { - "IndexPrefix": "lingyun.abp.auditing" - } - }, - "Elasticsearch": { - "NodeUris": "http://localhost:9200" - }, - "Location": { - "Baidu": { - "AccessKey": "你自己的百度地图WebAPI Key", - "ExtensionsRoad": true, - "ExtensionsTown": true, - "ExtensionsPoi": "1", - "VisableErrorToClient": true - }, - "Tencent": { - "AccessKey": "你自己的腾讯地图WebAPI Key", - "SecretKey": "你自己的腾讯地图WebAPI SecretKey Key, 不填的话不计算签名", - "VisableErrorToClient": true - } - }, - "CAP": { - "EventBus": { - "DefaultGroupName": "BackendAdmin", - "Version": "v1", - "FailedRetryInterval": 300, - "FailedRetryCount": 10 - }, - "RabbitMQ": { - "HostName": "Your RabbitMQ server connection address", - "Port": 5672, - "UserName": "Your RabbitMQ server connection user", - "Password": "Your RabbitMQ server connection user password", - "ExchangeName": "The name of your RabbitMQ server switch", - "VirtualHost": "Name of your RabbitMQ server VirtualHost" - } - }, - "Redis": { - "Configuration": "127.0.0.1", - "InstanceName": "LINGYUN.AbpApplication", - "DefaultDatabase": 10 - }, - "AuthServer": { - "Authority": "http://localhost:44385/", - "ApiName": "lingyun-abp-application" - }, - "Serilog": { - "MinimumLevel": { - "Default": "Debug", - "Override": { - "Microsoft.EntityFrameworkCore": "Debug", - "System": "Warning", - "Microsoft": "Warning" - } - }, - "Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId" ], - "WriteTo": [ - { - "Name": "Console", - "Args": { - "restrictedToMinimumLevel": "Debug", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "Elasticsearch", - "Args": { - "nodeUris": "http://localhost:9200", - "indexFormat": "linyun.abp.logging-{0:yyyy.MM.dd}", - "autoRegisterTemplate": true, - "autoRegisterTemplateVersion": "ESv7" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Debug-.log", - "restrictedToMinimumLevel": "Debug", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Info-.log", - "restrictedToMinimumLevel": "Information", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Warn-.log", - "restrictedToMinimumLevel": "Warning", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Error-.log", - "restrictedToMinimumLevel": "Error", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Fatal-.log", - "restrictedToMinimumLevel": "Fatal", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - } - ] - } -} diff --git a/aspnet-core/configuration/messages/LINGYUN.Abp.MessageService.HttpApi.Host/appsettings.Development.json b/aspnet-core/configuration/messages/LINGYUN.Abp.MessageService.HttpApi.Host/appsettings.Development.json deleted file mode 100644 index feb326a3d..000000000 --- a/aspnet-core/configuration/messages/LINGYUN.Abp.MessageService.HttpApi.Host/appsettings.Development.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "App": { - "CorsOrigins": "http://localhost:9527,http://127.0.0.1:30000" - }, - "ConnectionStrings": { - "Default": "Server=127.0.0.1;Database=Messages;User Id=root;Password=123456", - "MessageService": "Server=127.0.0.1;Database=Messages;User Id=root;Password=123456", - "AbpTenantManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpSettingManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpPermissionManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456" - }, - "Redis": { - "Configuration": "127.0.0.1,defaultDatabase=10", - "InstanceName": "LINGYUN.AbpApplication" - }, - "AuthServer": { - "Authority": "http://localhost:44385/", - "ApiName": "lingyun-abp-application" - }, - "Hangfire": { - "MySql": { - "Connection": "Server=127.0.0.1;Database=Messages;User Id=root;Password=123456;Allow User Variables=true", - "TablePrefix": "AppHangfire" - } - }, - "Notifications": { - "WeChat": { - "WeApp": { - "DefaultWeAppState": "formal" - } - } - }, - "CAP": { - "EventBus": { - "DefaultGroupName": "MessageService", - "Version": "v1", - "FailedRetryInterval": 300, - "FailedRetryCount": 10 - }, - "RabbitMQ": { - "HostName": "127.0.0.1", - "Port": 5672, - "UserName": "admin", - "Password": "admin", - "ExchangeName": "LINGYUN.AbpApplication", - "VirtualHost": "multi.service.test" - } - }, - "Serilog": { - "MinimumLevel": { - "Default": "Debug", - "Override": { - "Microsoft.EntityFrameworkCore": "Debug", - "System": "Warning", - "Microsoft": "Warning" - } - }, - "Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId" ], - "WriteTo": [ - { - "Name": "File", - "Args": { - "path": "Logs/Debug-.log", - "restrictedToMinimumLevel": "Debug", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Info-.log", - "restrictedToMinimumLevel": "Information", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Warn-.log", - "restrictedToMinimumLevel": "Warning", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Error-.log", - "restrictedToMinimumLevel": "Error", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Fatal-.log", - "restrictedToMinimumLevel": "Fatal", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - } - ] - } -} diff --git a/aspnet-core/configuration/platform/LINGYUN.Platform.HttpApi.Host/appsettings.Development.json b/aspnet-core/configuration/platform/LINGYUN.Platform.HttpApi.Host/appsettings.Development.json deleted file mode 100644 index 0a87a944f..000000000 --- a/aspnet-core/configuration/platform/LINGYUN.Platform.HttpApi.Host/appsettings.Development.json +++ /dev/null @@ -1,119 +0,0 @@ -{ - "App": { - "CorsOrigins": "http://localhost:9527,http://127.0.0.1:30000" - }, - "ConnectionStrings": { - "Default": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AppPlatform": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpTenantManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpSettingManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpPermissionManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpLocalizationManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456" - }, - "Features": { - "Validation": { - "Redis": { - "Configuration": "127.0.0.1,defaultDatabase=11", - "InstanceName": "LINGYUN.Abp.Application" - } - } - }, - "CAP": { - "EventBus": { - "DefaultGroupName": "Platform", - "Version": "v1", - "FailedRetryInterval": 300, - "FailedRetryCount": 10 - }, - "RabbitMQ": { - "HostName": "Your RabbitMQ server connection address", - "Port": 5672, - "UserName": "Your RabbitMQ server connection user", - "Password": "Your RabbitMQ server connection user password", - "ExchangeName": "The name of your RabbitMQ server switch", - "VirtualHost": "Name of your RabbitMQ server VirtualHost" - } - }, - "RemoteServices": { - "AbpIdentity": { - "BaseUrl": "http://localhost:30015/", - "IdentityClient": "internal-service-client" - } - }, - "IdentityClients": { - "internal-service-client": { - "Authority": "http://localhost:44385", - "RequireHttps": false, - "GrantType": "client_credentials", - "Scope": "lingyun-abp-application", - "ClientId": "internal-service-client", - "ClientSecret": "1q2w3e*" - } - }, - "Redis": { - "Configuration": "127.0.0.1,defaultDatabase=10", - "InstanceName": "LINGYUN.AbpApplication" - }, - "AuthServer": { - "Authority": "http://localhost:44385/", - "ApiName": "lingyun-abp-application" - }, - "Serilog": { - "MinimumLevel": { - "Default": "Debug", - "Override": { - "Microsoft.EntityFrameworkCore": "Debug", - "System": "Warning", - "Microsoft": "Warning" - } - }, - "Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId" ], - "WriteTo": [ - { - "Name": "File", - "Args": { - "path": "Logs/Debug-.log", - "restrictedToMinimumLevel": "Debug", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Info-.log", - "restrictedToMinimumLevel": "Information", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Warn-.log", - "restrictedToMinimumLevel": "Warning", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Error-.log", - "restrictedToMinimumLevel": "Error", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Fatal-.log", - "restrictedToMinimumLevel": "Fatal", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - } - ] - } -} diff --git a/aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.EntityFrameworkCore/README.md b/aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.EntityFrameworkCore/README.md new file mode 100644 index 000000000..1d889c964 --- /dev/null +++ b/aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.EntityFrameworkCore/README.md @@ -0,0 +1,32 @@ +# LINGYUN.Abp.AuditLogging.EntityFrameworkCore + +审计模块 EntityFrameworkCore 实现, 此模块仅作为桥梁, 具体实现交给abp官方模块 + +AuditLogManager 实现了 IAuditLogManager, 审计日志由Volo.Abp.AuditLogging模块管理 +SecurityLogManager 实现了 ISecurityLogManager, 安全日志由Volo.Abp.Identity模块管理 + +## 模块引用 + +```csharp +[DependsOn(typeof(AbpAuditLoggingEntityFrameworkCoreModule))] +public class YouProjectModule : AbpModule +{ + // other +} +``` + +## 配置项 + +请遵循 Volo.Abp.AuditLogging、Volo.Abp.Identity模块中的配置 + +## appsettings.json + +```json +{ + "ConnectionStrings": { + "AbpIdentity": "Server=127.0.0.1;Database=Identity;User Id=root;Password=*", + "AbpAuditLogging": "Server=127.0.0.1;Database=AuditLogging;User Id=root;Password=*", + } +} + +``` \ No newline at end of file diff --git a/aspnet-core/modules/auditing/LINGYUN.Abp.Auditing.Application.Contracts/LINGYUN/Abp/Auditing/Logging/Dto/LogFieldDto.cs b/aspnet-core/modules/auditing/LINGYUN.Abp.Auditing.Application.Contracts/LINGYUN/Abp/Auditing/Logging/Dto/LogFieldDto.cs index 0bd6c1334..2745ce383 100644 --- a/aspnet-core/modules/auditing/LINGYUN.Abp.Auditing.Application.Contracts/LINGYUN/Abp/Auditing/Logging/Dto/LogFieldDto.cs +++ b/aspnet-core/modules/auditing/LINGYUN.Abp.Auditing.Application.Contracts/LINGYUN/Abp/Auditing/Logging/Dto/LogFieldDto.cs @@ -2,6 +2,8 @@ { public class LogFieldDto { + public string MachineName { get; set; } + public string Environment { get; set; } public string Context { get; set; } public string ActionId { get; set; } public string ActionName { get; set; } diff --git a/aspnet-core/modules/auditing/LINGYUN.Abp.Auditing.Application.Contracts/LINGYUN/Abp/Auditing/Logging/Dto/LogGetByPagedDto.cs b/aspnet-core/modules/auditing/LINGYUN.Abp.Auditing.Application.Contracts/LINGYUN/Abp/Auditing/Logging/Dto/LogGetByPagedDto.cs index bd173e84c..b33932686 100644 --- a/aspnet-core/modules/auditing/LINGYUN.Abp.Auditing.Application.Contracts/LINGYUN/Abp/Auditing/Logging/Dto/LogGetByPagedDto.cs +++ b/aspnet-core/modules/auditing/LINGYUN.Abp.Auditing.Application.Contracts/LINGYUN/Abp/Auditing/Logging/Dto/LogGetByPagedDto.cs @@ -7,6 +7,8 @@ namespace LINGYUN.Abp.Auditing.Logging { public DateTime? StartTime { get; set; } public DateTime? EndTime { get; set; } + public string MachineName { get; set; } + public string Environment { get; set; } public string Context { get; set; } public string RequestId { get; set; } public string RequestPath { get; set; } diff --git a/aspnet-core/modules/auditing/LINGYUN.Abp.Auditing.Application/LINGYUN/Abp/Auditing/Logging/LogAppService.cs b/aspnet-core/modules/auditing/LINGYUN.Abp.Auditing.Application/LINGYUN/Abp/Auditing/Logging/LogAppService.cs index 34b60712e..083d4255b 100644 --- a/aspnet-core/modules/auditing/LINGYUN.Abp.Auditing.Application/LINGYUN/Abp/Auditing/Logging/LogAppService.cs +++ b/aspnet-core/modules/auditing/LINGYUN.Abp.Auditing.Application/LINGYUN/Abp/Auditing/Logging/LogAppService.cs @@ -25,14 +25,17 @@ namespace LINGYUN.Abp.Auditing.Logging { var count = await _manager.GetCountAsync( input.StartTime, input.EndTime, - input.Context, input.RequestId, input.RequestPath, - input.CorrelationId, input.ProcessId, input.ThreadId, + input.MachineName, input.Environment, + input.Context, input.RequestId, + input.RequestPath, input.CorrelationId, + input.ProcessId, input.ThreadId, input.HasException); var logs = await _manager.GetListAsync( input.Sorting, input.MaxResultCount, input.SkipCount, input.StartTime, input.EndTime, - input.Context, input.RequestId, input.RequestPath, + input.MachineName, input.Environment, input.Context, + input.RequestId, input.RequestPath, input.CorrelationId, input.ProcessId, input.ThreadId, input.HasException, includeDetails: false); diff --git a/aspnet-core/modules/logging/LINGYUN.Abp.Logging.Serilog.Elasticsearch/LINGYUN/Abp/AuditLogging/Serilog/Elasticsearch/SerilogElasticsearchLoggingManager.cs b/aspnet-core/modules/logging/LINGYUN.Abp.Logging.Serilog.Elasticsearch/LINGYUN/Abp/AuditLogging/Serilog/Elasticsearch/SerilogElasticsearchLoggingManager.cs index 8c1807f17..edd96b993 100644 --- a/aspnet-core/modules/logging/LINGYUN.Abp.Logging.Serilog.Elasticsearch/LINGYUN/Abp/AuditLogging/Serilog/Elasticsearch/SerilogElasticsearchLoggingManager.cs +++ b/aspnet-core/modules/logging/LINGYUN.Abp.Logging.Serilog.Elasticsearch/LINGYUN/Abp/AuditLogging/Serilog/Elasticsearch/SerilogElasticsearchLoggingManager.cs @@ -65,6 +65,8 @@ namespace LINGYUN.Abp.Logging.Serilog.Elasticsearch public virtual async Task GetCountAsync( DateTime? startTime = null, DateTime? endTime = null, + string machineName = null, + string environment = null, string context = null, string requestId = null, string requestPath = null, @@ -79,6 +81,8 @@ namespace LINGYUN.Abp.Logging.Serilog.Elasticsearch var querys = BuildQueryDescriptor( startTime, endTime, + machineName, + environment, context, requestId, requestPath, @@ -119,6 +123,8 @@ namespace LINGYUN.Abp.Logging.Serilog.Elasticsearch int skipCount = 0, DateTime? startTime = null, DateTime? endTime = null, + string machineName = null, + string environment = null, string context = null, string requestId = null, string requestPath = null, @@ -137,6 +143,8 @@ namespace LINGYUN.Abp.Logging.Serilog.Elasticsearch var querys = BuildQueryDescriptor( startTime, endTime, + machineName, + environment, context, requestId, requestPath, @@ -172,6 +180,8 @@ namespace LINGYUN.Abp.Logging.Serilog.Elasticsearch protected virtual List, QueryContainer>> BuildQueryDescriptor( DateTime? startTime = null, DateTime? endTime = null, + string machineName = null, + string environment = null, string context = null, string requestId = null, string requestPath = null, @@ -190,6 +200,14 @@ namespace LINGYUN.Abp.Logging.Serilog.Elasticsearch { querys.Add((log) => log.DateRange((q) => q.Field(f => f.TimeStamp).LessThanOrEquals(endTime))); } + if (!machineName.IsNullOrWhiteSpace()) + { + querys.Add((log) => log.Term((q) => q.Field((f) => f.Fields.MachineName.Suffix("keyword")).Value(machineName))); + } + if (!environment.IsNullOrWhiteSpace()) + { + querys.Add((log) => log.Term((q) => q.Field((f) => f.Fields.Environment.Suffix("keyword")).Value(environment))); + } if (!context.IsNullOrWhiteSpace()) { querys.Add((log) => log.Term((q) => q.Field((f) => f.Fields.Context.Suffix("keyword")).Value(context))); diff --git a/aspnet-core/modules/logging/LINGYUN.Abp.Logging.Serilog.Elasticsearch/LINGYUN/Abp/AuditLogging/Serilog/Elasticsearch/SerilogField.cs b/aspnet-core/modules/logging/LINGYUN.Abp.Logging.Serilog.Elasticsearch/LINGYUN/Abp/AuditLogging/Serilog/Elasticsearch/SerilogField.cs index d8be177eb..2846eff46 100644 --- a/aspnet-core/modules/logging/LINGYUN.Abp.Logging.Serilog.Elasticsearch/LINGYUN/Abp/AuditLogging/Serilog/Elasticsearch/SerilogField.cs +++ b/aspnet-core/modules/logging/LINGYUN.Abp.Logging.Serilog.Elasticsearch/LINGYUN/Abp/AuditLogging/Serilog/Elasticsearch/SerilogField.cs @@ -2,6 +2,12 @@ { public class SerilogField { + [Nest.PropertyName(AbpLoggingEnricherPropertyNames.MachineName)] + public string MachineName { get; set; } + + [Nest.PropertyName(AbpLoggingEnricherPropertyNames.EnvironmentName)] + public string Environment { get; set; } + [Nest.PropertyName("SourceContext")] public string Context { get; set; } diff --git a/aspnet-core/modules/logging/LINGYUN.Abp.Logging.Serilog.Elasticsearch/README.md b/aspnet-core/modules/logging/LINGYUN.Abp.Logging.Serilog.Elasticsearch/README.md new file mode 100644 index 000000000..c4e39eb12 --- /dev/null +++ b/aspnet-core/modules/logging/LINGYUN.Abp.Logging.Serilog.Elasticsearch/README.md @@ -0,0 +1,32 @@ +# LINGYUN.Abp.Logging.Serilog.Elasticsearch + +ILoggingManager 接口的ES实现, 从ES中检索日志信息 + +## 模块引用 + +```csharp +[DependsOn(typeof(AbpLoggingSerilogElasticsearchModule))] +public class YouProjectModule : AbpModule +{ + // other +} +``` + +## 配置项 + +* AbpLoggingSerilogElasticsearchOptions.IndexFormat 必须和Serilog配置项中的IndexFormat相同,否则无法定位到正确的索引 + +## appsettings.json + +```json +{ + "Logging": { + "Serilog": { + "Elasticsearch": { + "IndexFormat": "logstash-{0:yyyy.MM.dd}" + } + } + } +} + +``` \ No newline at end of file diff --git a/aspnet-core/modules/logging/LINGYUN.Abp.Logging/LINGYUN/Abp/AuditLogging/AbpLoggingEnricherPropertyNames.cs b/aspnet-core/modules/logging/LINGYUN.Abp.Logging/LINGYUN/Abp/AuditLogging/AbpLoggingEnricherPropertyNames.cs new file mode 100644 index 000000000..111a75260 --- /dev/null +++ b/aspnet-core/modules/logging/LINGYUN.Abp.Logging/LINGYUN/Abp/AuditLogging/AbpLoggingEnricherPropertyNames.cs @@ -0,0 +1,8 @@ +namespace LINGYUN.Abp.Logging +{ + public class AbpLoggingEnricherPropertyNames + { + public const string MachineName = "MachineName"; + public const string EnvironmentName = "EnvironmentName"; + } +} diff --git a/aspnet-core/modules/logging/LINGYUN.Abp.Logging/LINGYUN/Abp/AuditLogging/AbpLoggingModule.cs b/aspnet-core/modules/logging/LINGYUN.Abp.Logging/LINGYUN/Abp/AuditLogging/AbpLoggingModule.cs index f69d75d12..ede5199da 100644 --- a/aspnet-core/modules/logging/LINGYUN.Abp.Logging/LINGYUN/Abp/AuditLogging/AbpLoggingModule.cs +++ b/aspnet-core/modules/logging/LINGYUN.Abp.Logging/LINGYUN/Abp/AuditLogging/AbpLoggingModule.cs @@ -1,9 +1,15 @@ -using System; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Modularity; namespace LINGYUN.Abp.Logging { public class AbpLoggingModule : AbpModule { + public override void ConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + + Configure(configuration.GetSection("Logging")); + } } } diff --git a/aspnet-core/modules/logging/LINGYUN.Abp.Logging/LINGYUN/Abp/AuditLogging/DefaultLoggingManager.cs b/aspnet-core/modules/logging/LINGYUN.Abp.Logging/LINGYUN/Abp/AuditLogging/DefaultLoggingManager.cs index e17f902ab..f748acffd 100644 --- a/aspnet-core/modules/logging/LINGYUN.Abp.Logging/LINGYUN/Abp/AuditLogging/DefaultLoggingManager.cs +++ b/aspnet-core/modules/logging/LINGYUN.Abp.Logging/LINGYUN/Abp/AuditLogging/DefaultLoggingManager.cs @@ -1,5 +1,4 @@ -using LINGYUN.Abp.Logging; -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using System; using System.Collections.Generic; @@ -7,7 +6,7 @@ using System.Threading; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; -namespace LINGYUN.Abp.AuditLogging +namespace LINGYUN.Abp.Logging { [Dependency(TryRegister = true)] public class DefaultLoggingManager : ILoggingManager, ISingletonDependency @@ -26,13 +25,41 @@ namespace LINGYUN.Abp.AuditLogging return Task.FromResult(logInfo); } - public Task GetCountAsync(DateTime? startTime = null, DateTime? endTime = null, string context = null, string requestId = null, string requestPath = null, string correlationId = null, int? processId = null, int? threadId = null, bool? hasException = null, CancellationToken cancellationToken = default) + public Task GetCountAsync( + DateTime? startTime = null, + DateTime? endTime = null, + string machineName = null, + string environment = null, + string context = null, + string requestId = null, + string requestPath = null, + string correlationId = null, + int? processId = null, + int? threadId = null, + bool? hasException = null, + CancellationToken cancellationToken = default) { Logger.LogDebug("No logging manager is available!"); return Task.FromResult(0L); } - public Task> GetListAsync(string sorting = null, int maxResultCount = 50, int skipCount = 0, DateTime? startTime = null, DateTime? endTime = null, string context = null, string requestId = null, string requestPath = null, string correlationId = null, int? processId = null, int? threadId = null, bool? hasException = null, bool includeDetails = false, CancellationToken cancellationToken = default) + public Task> GetListAsync( + string sorting = null, + int maxResultCount = 50, + int skipCount = 0, + DateTime? startTime = null, + DateTime? endTime = null, + string machineName = null, + string environment = null, + string context = null, + string requestId = null, + string requestPath = null, + string correlationId = null, + int? processId = null, + int? threadId = null, + bool? hasException = null, + bool includeDetails = false, + CancellationToken cancellationToken = default) { Logger.LogDebug("No logging manager is available!"); return Task.FromResult(new List()); diff --git a/aspnet-core/modules/logging/LINGYUN.Abp.Logging/LINGYUN/Abp/AuditLogging/ILoggingManager.cs b/aspnet-core/modules/logging/LINGYUN.Abp.Logging/LINGYUN/Abp/AuditLogging/ILoggingManager.cs index 8935e5a92..d1ff89912 100644 --- a/aspnet-core/modules/logging/LINGYUN.Abp.Logging/LINGYUN/Abp/AuditLogging/ILoggingManager.cs +++ b/aspnet-core/modules/logging/LINGYUN.Abp.Logging/LINGYUN/Abp/AuditLogging/ILoggingManager.cs @@ -14,6 +14,8 @@ namespace LINGYUN.Abp.Logging Task GetCountAsync( DateTime? startTime = null, DateTime? endTime = null, + string machineName = null, + string environment = null, string context = null, string requestId = null, string requestPath = null, @@ -29,6 +31,8 @@ namespace LINGYUN.Abp.Logging int skipCount = 0, DateTime? startTime = null, DateTime? endTime = null, + string machineName = null, + string environment = null, string context = null, string requestId = null, string requestPath = null, diff --git a/aspnet-core/modules/logging/LINGYUN.Abp.Logging/LINGYUN/Abp/AuditLogging/LogField.cs b/aspnet-core/modules/logging/LINGYUN.Abp.Logging/LINGYUN/Abp/AuditLogging/LogField.cs index 0d6106c67..348219f2a 100644 --- a/aspnet-core/modules/logging/LINGYUN.Abp.Logging/LINGYUN/Abp/AuditLogging/LogField.cs +++ b/aspnet-core/modules/logging/LINGYUN.Abp.Logging/LINGYUN/Abp/AuditLogging/LogField.cs @@ -2,6 +2,8 @@ { public class LogField { + public string MachineName { get; set; } + public string Environment { get; set; } public string Context { get; set; } public string ActionId { get; set; } public string ActionName { get; set; } diff --git a/aspnet-core/modules/logging/LINGYUN.Abp.Logging/README.md b/aspnet-core/modules/logging/LINGYUN.Abp.Logging/README.md new file mode 100644 index 000000000..1b5c7707b --- /dev/null +++ b/aspnet-core/modules/logging/LINGYUN.Abp.Logging/README.md @@ -0,0 +1,31 @@ +# LINGYUN.Abp.Logging + +日志基础模块 + +定义 ILoggingManager 接口, 实现日志信息查询 + +## 模块引用 + +```csharp +[DependsOn(typeof(AbpLoggingModule))] +public class YouProjectModule : AbpModule +{ + // other +} +``` + +## 配置项 + +* AbpLoggingOptions.ApplicationPropertyName 用于自定义ApplicationName字段的名称 +* AbpLoggingOptions.ApplicationName 在日志中标识当前应用的名称 + +## appsettings.json + +```json +{ + "Logging": { + "ApplicationName": "app" + } +} + +``` \ No newline at end of file diff --git a/aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.Configure.cs b/aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.Configure.cs new file mode 100644 index 000000000..dbcd3f9b2 --- /dev/null +++ b/aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.Configure.cs @@ -0,0 +1,169 @@ +using Microsoft.AspNetCore.Cors; +using Microsoft.AspNetCore.DataProtection; +using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.Caching.StackExchangeRedis; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using StackExchange.Redis; +using System; +using System.Linq; +using System.Text.Encodings.Web; +using System.Text.Unicode; +using Volo.Abp.Account.Localization; +using Volo.Abp.Auditing; +using Volo.Abp.Caching; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Json.SystemTextJson; +using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; +using Volo.Abp.UI.Navigation.Urls; +using Volo.Abp.VirtualFileSystem; + +namespace AuthServer.Host +{ + public partial class AuthIdentityServerModule + { + private void ConfigureDbContext() + { + Configure(options => + { + options.UseMySQL(); + }); + } + private void ConfigureJsonSerializer() + { + // 中文序列化的编码问题 + Configure(options => + { + options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); + }); + } + private void ConfigureCaching(IConfiguration configuration) + { + Configure(options => + { + // 最好统一命名,不然某个缓存变动其他应用服务有例外发生 + options.KeyPrefix = "LINGYUN.Abp.Application"; + // 滑动过期30天 + options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30); + // 绝对过期60天 + options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60); + }); + + Configure(options => + { + var redisConfig = ConfigurationOptions.Parse(options.Configuration); + options.ConfigurationOptions = redisConfig; + options.InstanceName = configuration["Redis:InstanceName"]; + }); + } + private void ConfigureIdentity(IConfiguration configuration) + { + // 增加配置文件定义,在新建租户时需要 + Configure(options => + { + var identityConfiguration = configuration.GetSection("Identity"); + if (identityConfiguration.Exists()) + { + identityConfiguration.Bind(options); + } + }); + } + private void ConfigureVirtualFileSystem() + { + Configure(options => + { + options.FileSets.AddEmbedded("AuthServer"); + }); + } + private void ConfigureLocalization() + { + Configure(options => + { + options.Languages.Add(new LanguageInfo("en", "en", "English")); + options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); + + options.Resources + .Get() + .AddVirtualJson("/Localization/Resources"); + }); + } + private void ConfigureAuditing() + { + Configure(options => + { + // options.IsEnabledForGetRequests = true; + options.ApplicationName = "Identity-Server-STS"; + }); + } + private void ConfigureUrls(IConfiguration configuration) + { + Configure(options => + { + options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"]; + // 邮件登录地址 + options.Applications["MVC"].Urls["EmailVerifyLogin"] = "Account/VerifyCode"; + }); + } + private void ConfigureSecurity(IServiceCollection services, IConfiguration configuration, bool isDevelopment = false) + { + services.AddAuthentication() + .AddJwtBearer(options => + { + options.Authority = configuration["AuthServer:Authority"]; + options.RequireHttpsMetadata = false; + options.Audience = configuration["AuthServer:ApiName"]; + }); + + if (!isDevelopment) + { + var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); + services + .AddDataProtection() + .PersistKeysToStackExchangeRedis(redis, "AuthServer-Protection-Keys"); + } + } + private void ConfigureMultiTenancy(IConfiguration configuration) + { + // 多租户 + Configure(options => + { + options.IsEnabled = true; + }); + + var tenantResolveCfg = configuration.GetSection("App:Domains"); + if (tenantResolveCfg.Exists()) + { + Configure(options => + { + var domains = tenantResolveCfg.Get(); + foreach (var domain in domains) + { + options.AddDomainTenantResolver(domain); + } + }); + } + } + private void ConfigureCors(IServiceCollection services, IConfiguration configuration) + { + services.AddCors(options => + { + options.AddPolicy(DefaultCorsPolicyName, builder => + { + builder + .WithOrigins( + configuration["App:CorsOrigins"] + .Split(",", StringSplitOptions.RemoveEmptyEntries) + .Select(o => o.RemovePostFix("/")) + .ToArray() + ) + .WithAbpExposedHeaders() + .SetIsOriginAllowedToAllowWildcardSubdomains() + .AllowAnyHeader() + .AllowAnyMethod() + .AllowCredentials(); + }); + }); + } + } +} diff --git a/aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.Seeder.cs b/aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.Seeder.cs new file mode 100644 index 000000000..f83736867 --- /dev/null +++ b/aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.Seeder.cs @@ -0,0 +1,23 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Volo.Abp; +using Volo.Abp.Data; +using Volo.Abp.Threading; + +namespace AuthServer.Host +{ + public partial class AuthIdentityServerModule + { + private void SeedData(ApplicationInitializationContext context) + { + if (context.GetEnvironment().IsDevelopment()) + { + AsyncHelper.RunSync(async () => + { + using var scope = context.ServiceProvider.CreateScope(); + await scope.ServiceProvider.GetRequiredService().SeedAsync(); + }); + } + } + } +} diff --git a/aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.cs b/aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.cs index 85a3d1399..874450942 100644 --- a/aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.cs +++ b/aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.cs @@ -1,328 +1,168 @@ -using DotNetCore.CAP; -using LINGYUN.Abp.AspNetCore.HttpOverrides; -using LINGYUN.Abp.EventBus.CAP; -using LINGYUN.Abp.Identity.EntityFrameworkCore; -using LINGYUN.Abp.IdentityServer; -using LINGYUN.Abp.IdentityServer.EntityFrameworkCore; -using LINGYUN.Abp.IdentityServer.WeChat; -using LINGYUN.Abp.MultiTenancy.DbFinder; -using LINGYUN.Abp.PermissionManagement.Identity; -using LINGYUN.Abp.Sms.Aliyun; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Cors; -using Microsoft.AspNetCore.DataProtection; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Identity; -using Microsoft.Extensions.Caching.StackExchangeRedis; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using StackExchange.Redis; -using System; -using System.IO; -using System.Linq; -using System.Security.Cryptography.X509Certificates; -using System.Text; -using System.Text.Encodings.Web; -using System.Text.Unicode; -using Volo.Abp; -using Volo.Abp.Account; -using Volo.Abp.Account.Localization; -using Volo.Abp.Account.Web; -using Volo.Abp.AspNetCore.Authentication.JwtBearer; -using Volo.Abp.AspNetCore.Mvc; -using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic; -using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; -using Volo.Abp.Auditing; -using Volo.Abp.Autofac; -using Volo.Abp.Caching; -using Volo.Abp.Caching.StackExchangeRedis; -using Volo.Abp.Data; -using Volo.Abp.EntityFrameworkCore; -using Volo.Abp.EntityFrameworkCore.MySQL; -using Volo.Abp.FeatureManagement.EntityFrameworkCore; -using Volo.Abp.Identity; -using Volo.Abp.IdentityServer; -using Volo.Abp.IdentityServer.Jwt; -using Volo.Abp.Json; -using Volo.Abp.Json.SystemTextJson; -using Volo.Abp.Localization; -using Volo.Abp.Modularity; -using Volo.Abp.MultiTenancy; -using Volo.Abp.PermissionManagement.EntityFrameworkCore; -using Volo.Abp.Security.Encryption; -using Volo.Abp.SettingManagement.EntityFrameworkCore; -using Volo.Abp.TenantManagement.EntityFrameworkCore; -using Volo.Abp.Threading; -using Volo.Abp.UI.Navigation.Urls; -using Volo.Abp.VirtualFileSystem; - -namespace AuthServer.Host -{ - [DependsOn( - typeof(AbpAccountWebIdentityServerModule), - typeof(AbpAccountApplicationModule), - typeof(AbpAspNetCoreMvcUiBasicThemeModule), - typeof(AbpAutofacModule), - typeof(AbpCachingStackExchangeRedisModule), - typeof(AbpEntityFrameworkCoreMySQLModule), - typeof(AbpIdentityEntityFrameworkCoreModule), - typeof(AbpIdentityApplicationModule), - typeof(AbpIdentityHttpApiModule), - typeof(AbpIdentityServerEntityFrameworkCoreModule), - typeof(AbpIdentityServerSmsValidatorModule), - typeof(AbpIdentityServerWeChatModule), - typeof(AbpPermissionManagementDomainIdentityModule), - typeof(AbpPermissionManagementEntityFrameworkCoreModule), - typeof(AbpSettingManagementEntityFrameworkCoreModule), - typeof(AbpFeatureManagementEntityFrameworkCoreModule), - typeof(AbpTenantManagementEntityFrameworkCoreModule), - typeof(AbpAspNetCoreAuthenticationJwtBearerModule), - typeof(AbpAspNetCoreHttpOverridesModule), - typeof(AbpDbFinderMultiTenancyModule), - typeof(AbpCAPEventBusModule), - typeof(AbpAliyunSmsModule) - )] - public class AuthIdentityServerModule : AbpModule - { - private const string DefaultCorsPolicyName = "Default"; - - public override void PreConfigureServices(ServiceConfigurationContext context) - { - var configuration = context.Services.GetConfiguration(); - var hostingEnvironment = context.Services.GetHostingEnvironment(); - - PreConfigure(options => - { - options - .UseMySql(configuration.GetConnectionString("Default")) - .UseRabbitMQ(rabbitMQOptions => - { - configuration.GetSection("CAP:RabbitMQ").Bind(rabbitMQOptions); - }) - .UseDashboard(); - }); - - var cerConfig = configuration.GetSection("Certificates"); - if (hostingEnvironment.IsProduction() && - cerConfig.Exists()) - { - // 开发环境下存在证书配置 - // 且证书文件存在则使用自定义的证书文件来启动Ids服务器 - var cerPath = Path.Combine(hostingEnvironment.ContentRootPath, cerConfig["CerPath"]); - if (File.Exists(cerPath)) - { - PreConfigure(options => - { - options.AddDeveloperSigningCredential = false; - }); - - var cer = new X509Certificate2(cerPath, cerConfig["Password"]); - - PreConfigure(builder => - { - builder.AddSigningCredential(cer); - }); - } - } - } - - public override void ConfigureServices(ServiceConfigurationContext context) - { - var hostingEnvironment = context.Services.GetHostingEnvironment(); - var configuration = context.Services.GetConfiguration(); - - Configure(options => - { - options.UseMySQL(); - }); - - // 中文序列化的编码问题 - Configure(options => - { - options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); - }); - - // 加解密 - Configure(options => - { - var encryptionConfiguration = configuration.GetSection("Encryption"); - if (encryptionConfiguration.Exists()) - { - options.DefaultPassPhrase = encryptionConfiguration["PassPhrase"] ?? options.DefaultPassPhrase; - options.DefaultSalt = encryptionConfiguration.GetSection("Salt").Exists() - ? Encoding.ASCII.GetBytes(encryptionConfiguration["Salt"]) - : options.DefaultSalt; - options.InitVectorBytes = encryptionConfiguration.GetSection("InitVector").Exists() - ? Encoding.ASCII.GetBytes(encryptionConfiguration["InitVector"]) - : options.InitVectorBytes; - - var keySizeConfig = encryptionConfiguration.GetSection("Keysize"); - options.Keysize = keySizeConfig.Exists() - ? keySizeConfig.Get() - : options.Keysize; - } - }); - - Configure(options => - { - // 最好统一命名,不然某个缓存变动其他应用服务有例外发生 - options.KeyPrefix = "LINGYUN.Abp.Application"; - // 滑动过期30天 - options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30); - // 绝对过期60天 - options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60); - }); - - Configure(options => - { - var redisConfig = ConfigurationOptions.Parse(options.Configuration); - options.ConfigurationOptions = redisConfig; - options.InstanceName = configuration["Redis:InstanceName"]; - }); - - // 增加配置文件定义,在新建租户时需要 - Configure(options => - { - var identityConfiguration = configuration.GetSection("Identity"); - if (identityConfiguration.Exists()) - { - identityConfiguration.Bind(options); - } - }); - - Configure(options => - { - options.FileSets.AddEmbedded("AuthServer"); - }); - - Configure(options => - { - options.Languages.Add(new LanguageInfo("en", "en", "English")); - options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); - - options.Resources - .Get() - .AddVirtualJson("/Localization/Resources"); - }); - - Configure(options => - { - // options.IsEnabledForGetRequests = true; - options.ApplicationName = "Identity-Server-STS"; - }); - - Configure(options => - { - options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"]; - // 邮件登录地址 - options.Applications["MVC"].Urls["EmailVerifyLogin"] = "Account/VerifyCode"; - }); - - context.Services.ConfigureNonBreakingSameSiteCookies(); - - // context.Services.AddAuthentication(); - context.Services.AddAuthentication() - .AddJwtBearer(options => - { - options.Authority = configuration["AuthServer:Authority"]; - options.RequireHttpsMetadata = false; - options.Audience = configuration["AuthServer:ApiName"]; - }); - - - - if (!hostingEnvironment.IsDevelopment()) - { - var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); - context.Services - .AddDataProtection() - .PersistKeysToStackExchangeRedis(redis, "AuthServer-Protection-Keys"); - } - - Configure(options => - { - options.IsEnabled = true; - }); - - var tenantResolveCfg = configuration.GetSection("App:Domains"); - if (tenantResolveCfg.Exists()) - { - Configure(options => - { - var domains = tenantResolveCfg.Get(); - foreach (var domain in domains) - { - options.AddDomainTenantResolver(domain); - } - }); - } - - context.Services.AddCors(options => - { - options.AddPolicy(DefaultCorsPolicyName, builder => - { - builder - .WithOrigins( - configuration["App:CorsOrigins"] - .Split(",", StringSplitOptions.RemoveEmptyEntries) - .Select(o => o.RemovePostFix("/")) - .ToArray() - ) - .WithAbpExposedHeaders() - .SetIsOriginAllowedToAllowWildcardSubdomains() - .AllowAnyHeader() - .AllowAnyMethod() - .AllowCredentials(); - }); - }); - } - - public override void OnApplicationInitialization(ApplicationInitializationContext context) - { - var app = context.GetApplicationBuilder(); - var env = context.GetEnvironment(); - - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - else - { - // 需要实现一个错误页面 - app.UseErrorPage(); - app.UseHsts(); - } - - // app.UseHttpsRedirection(); - app.UseCookiePolicy(); - app.UseCorrelationId(); - app.UseStaticFiles(); - app.UseRouting(); - app.UseCors(DefaultCorsPolicyName); - app.UseWeChatSignature(); - app.UseMultiTenancy(); - app.UseAuthentication(); - app.UseJwtTokenMiddleware(); - app.UseAbpRequestLocalization(); - app.UseIdentityServer(); - app.UseAuthorization(); - app.UseAuditing(); - app.UseConfiguredEndpoints(); - - if (context.GetEnvironment().IsDevelopment()) - { - SeedData(context); - } - } - - private void SeedData(ApplicationInitializationContext context) - { - AsyncHelper.RunSync(async () => - { - using var scope = context.ServiceProvider.CreateScope(); - await scope.ServiceProvider.GetRequiredService().SeedAsync(); - }); - } - } -} +using DotNetCore.CAP; +using LINGYUN.Abp.AspNetCore.HttpOverrides; +using LINGYUN.Abp.AuditLogging.Elasticsearch; +using LINGYUN.Abp.EventBus.CAP; +using LINGYUN.Abp.Identity.EntityFrameworkCore; +using LINGYUN.Abp.IdentityServer; +using LINGYUN.Abp.IdentityServer.EntityFrameworkCore; +using LINGYUN.Abp.IdentityServer.WeChat; +using LINGYUN.Abp.MultiTenancy.DbFinder; +using LINGYUN.Abp.PermissionManagement.Identity; +using LINGYUN.Abp.Sms.Aliyun; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using System.IO; +using System.Security.Cryptography.X509Certificates; +using Volo.Abp; +using Volo.Abp.Account; +using Volo.Abp.Account.Web; +using Volo.Abp.AspNetCore.Authentication.JwtBearer; +using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic; +using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; +using Volo.Abp.AspNetCore.Serilog; +using Volo.Abp.Autofac; +using Volo.Abp.Caching.StackExchangeRedis; +using Volo.Abp.EntityFrameworkCore.MySQL; +using Volo.Abp.FeatureManagement.EntityFrameworkCore; +using Volo.Abp.Identity; +using Volo.Abp.IdentityServer; +using Volo.Abp.IdentityServer.Jwt; +using Volo.Abp.Modularity; +using Volo.Abp.PermissionManagement.EntityFrameworkCore; +using Volo.Abp.SettingManagement.EntityFrameworkCore; +using Volo.Abp.TenantManagement.EntityFrameworkCore; + +namespace AuthServer.Host +{ + [DependsOn( + typeof(AbpAspNetCoreSerilogModule), + typeof(AbpAuditLoggingElasticsearchModule), + typeof(AbpAccountWebIdentityServerModule), + typeof(AbpAccountApplicationModule), + typeof(AbpAspNetCoreMvcUiBasicThemeModule), + typeof(AbpAutofacModule), + typeof(AbpCachingStackExchangeRedisModule), + typeof(AbpEntityFrameworkCoreMySQLModule), + typeof(AbpIdentityEntityFrameworkCoreModule), + typeof(AbpIdentityApplicationModule), + typeof(AbpIdentityHttpApiModule), + typeof(AbpIdentityServerEntityFrameworkCoreModule), + typeof(AbpIdentityServerSmsValidatorModule), + typeof(AbpIdentityServerWeChatModule), + typeof(AbpPermissionManagementDomainIdentityModule), + typeof(AbpPermissionManagementEntityFrameworkCoreModule), + typeof(AbpSettingManagementEntityFrameworkCoreModule), + typeof(AbpFeatureManagementEntityFrameworkCoreModule), + typeof(AbpTenantManagementEntityFrameworkCoreModule), + typeof(AbpAspNetCoreAuthenticationJwtBearerModule), + typeof(AbpAspNetCoreHttpOverridesModule), + typeof(AbpDbFinderMultiTenancyModule), + typeof(AbpCAPEventBusModule), + typeof(AbpAliyunSmsModule) + )] + public partial class AuthIdentityServerModule : AbpModule + { + private const string DefaultCorsPolicyName = "Default"; + + public override void PreConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + var hostingEnvironment = context.Services.GetHostingEnvironment(); + + PreConfigure(options => + { + options + .UseMySql(configuration.GetConnectionString("Default")) + .UseRabbitMQ(rabbitMQOptions => + { + configuration.GetSection("CAP:RabbitMQ").Bind(rabbitMQOptions); + }) + .UseDashboard(); + }); + + var cerConfig = configuration.GetSection("Certificates"); + if (hostingEnvironment.IsProduction() && + cerConfig.Exists()) + { + // 开发环境下存在证书配置 + // 且证书文件存在则使用自定义的证书文件来启动Ids服务器 + var cerPath = Path.Combine(hostingEnvironment.ContentRootPath, cerConfig["CerPath"]); + if (File.Exists(cerPath)) + { + PreConfigure(options => + { + options.AddDeveloperSigningCredential = false; + }); + + var cer = new X509Certificate2(cerPath, cerConfig["Password"]); + + PreConfigure(builder => + { + builder.AddSigningCredential(cer); + }); + } + } + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + var hostingEnvironment = context.Services.GetHostingEnvironment(); + var configuration = hostingEnvironment.BuildConfiguration(); + + ConfigureDbContext(); + ConfigureJsonSerializer(); + ConfigureCaching(configuration); + ConfigureIdentity(configuration); + ConfigureVirtualFileSystem(); + ConfigureLocalization(); + ConfigureAuditing(); + ConfigureUrls(configuration); + ConfigureMultiTenancy(configuration); + ConfigureCors(context.Services, configuration); + ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment()); + + context.Services.ConfigureNonBreakingSameSiteCookies(); + + + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + var app = context.GetApplicationBuilder(); + var env = context.GetEnvironment(); + + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + else + { + // 需要实现一个错误页面 + app.UseErrorPage(); + app.UseHsts(); + } + + // app.UseHttpsRedirection(); + app.UseCookiePolicy(); + app.UseCorrelationId(); + app.UseStaticFiles(); + app.UseRouting(); + app.UseCors(DefaultCorsPolicyName); + app.UseWeChatSignature(); + app.UseMultiTenancy(); + app.UseAuthentication(); + app.UseJwtTokenMiddleware(); + app.UseAbpRequestLocalization(); + app.UseIdentityServer(); + app.UseAuthorization(); + app.UseAuditing(); + app.UseAbpSerilogEnrichers(); + app.UseConfiguredEndpoints(); + + SeedData(context); + } + } +} diff --git a/aspnet-core/services/account/AuthServer.Host/AuthServer.Host.csproj b/aspnet-core/services/account/AuthServer.Host/AuthServer.Host.csproj index 574b08c85..bedc142a7 100644 --- a/aspnet-core/services/account/AuthServer.Host/AuthServer.Host.csproj +++ b/aspnet-core/services/account/AuthServer.Host/AuthServer.Host.csproj @@ -27,15 +27,18 @@ + + all runtime; build; native; contentfiles; analyzers; buildtransitive + @@ -52,6 +55,7 @@ + diff --git a/aspnet-core/services/account/AuthServer.Host/appsettings.Development.json b/aspnet-core/services/account/AuthServer.Host/appsettings.Development.json new file mode 100644 index 000000000..aa9603de2 --- /dev/null +++ b/aspnet-core/services/account/AuthServer.Host/appsettings.Development.json @@ -0,0 +1,118 @@ +{ + "App": { + "TrackingEntitiesChanged": true, + "SelfUrl": "http://localhost:44385/", + "CorsOrigins": "http://localhost:4200,http://localhost:9527,http://localhost:3100" + }, + "AppSelfUrl": "http://localhost:44385/", + "ConnectionStrings": { + "Default": "Server=localhost;Database=IdentityServer;User Id=root;Password=123456", + "AbpIdentity": "Server=localhost;Database=IdentityServer;User Id=root;Password=123456", + "AbpIdentityServer": "Server=localhost;Database=IdentityServer;User Id=root;Password=123456", + "AbpTenantManagement": "Server=localhost;Database=Platform;User Id=root;Password=123456", + "AbpSettingManagement": "Server=localhost;Database=Platform;User Id=root;Password=123456", + "AbpPermissionManagement": "Server=localhost;Database=Platform;User Id=root;Password=123456", + "AbpFeatureManagement": "Server=localhost;Database=Platform;User Id=root;Password=123456" + }, + "CAP": { + "EventBus": { + "DefaultGroupName": "AuthServer", + "Version": "v1", + "FailedRetryInterval": 300, + "FailedRetryCount": 10 + }, + "MySql": { + "TableNamePrefix": "auth", + "ConnectionString": "Server=localhost;Database=IdentityServer;User Id=root;Password=123456" + }, + "RabbitMQ": { + "HostName": "localhost", + "Port": 5672, + "UserName": "guest", + "Password": "guest", + "ExchangeName": "LINGYUN.Abp.Application", + "VirtualHost": "/" + } + }, + "Redis": { + "Configuration": "localhost", + "InstanceName": "LINGYUN.Abp.Application", + "DefaultDatabase": 10 + }, + "AuthServer": { + "Authority": "http://localhost:44385/", + "ApiName": "lingyun-abp-application" + }, + "IdentityServer": { + "Clients": { + "AuthManagement": { + "ClientId": "auth-management", + "RootUrl": "http://localhost:44313/" + }, + "AuthVueAdmin": { + "ClientId": "vue-admin-element" + }, + "AuthApiGateway": { + "ClientId": "ApigatewayHostClient" + }, + "InternalService": { + "ClientId": "internal-service-client" + } + } + }, + "Identity": { + "Password": { + "RequiredLength": 6, + "RequiredUniqueChars": 0, + "RequireNonAlphanumeric": false, + "RequireLowercase": false, + "RequireUppercase": false, + "RequireDigit": false + }, + "Lockout": { + "AllowedForNewUsers": false, + "LockoutDuration": 5, + "MaxFailedAccessAttempts": 5 + }, + "SignIn": { + "RequireConfirmedEmail": false, + "RequireConfirmedPhoneNumber": false + } + }, + "AuditLogging": { + "Elasticsearch": { + "IndexPrefix": "lingyun.abp.auditing" + } + }, + "Elasticsearch": { + "NodeUris": "http://localhost:9200" + }, + "Serilog": { + "MinimumLevel": { + "Default": "Debug", + "Override": { + "System": "Warning", + "Microsoft": "Warning", + "DotNetCore": "Debug" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "restrictedToMinimumLevel": "Debug", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "Elasticsearch", + "Args": { + "nodeUris": "http://localhost:9200", + "indexFormat": "lingyun.abp.logging-{0:yyyy.MM.dd}", + "autoRegisterTemplate": true, + "autoRegisterTemplateVersion": "ESv7" + } + } + ] + } +} diff --git a/aspnet-core/configuration/apigateway/LINGYUN.ApiGateway.Host/appsettings.Development.json b/aspnet-core/services/account/AuthServer.Host/appsettings.json similarity index 60% rename from aspnet-core/configuration/apigateway/LINGYUN.ApiGateway.Host/appsettings.Development.json rename to aspnet-core/services/account/AuthServer.Host/appsettings.json index 7fd0398da..857129659 100644 --- a/aspnet-core/configuration/apigateway/LINGYUN.ApiGateway.Host/appsettings.Development.json +++ b/aspnet-core/services/account/AuthServer.Host/appsettings.json @@ -1,103 +1,72 @@ -{ - "ApiGateway": { - "AppId": "TEST-APP"//这里是用于Ocelot主机去API服务器获取参数的标识,指定需要获取什么类型的网关配置 - }, - "Redis": { - "Configuration": "127.0.0.1,defaultDatabase=10", - "InstanceName": "LINGYUN.AbpApplication" - }, - "RemoteServices": { - "ApiGateway": { - "BaseUrl": "http://localhost:30001/", - "IdentityClient": "ApigatewayHostClient" - } - }, - "IdentityClients": { - "ApigatewayHostClient": { - "Authority": "http://localhost:44385", - "RequireHttps": false, - "GrantType": "client_credentials", - "ClientId": "ApigatewayHostClient", - "ClientSecret": "1q2w3e*", - "Scope": "lingyun-abp-application" - } - }, - "EnabledDynamicOcelot": true, - "CAP": { - "EventBus": { - "DefaultGroupName": "ApiGateway-Host", - "Version": "v1", - "FailedRetryInterval": 300, - "FailedRetryCount": 10 - }, - "RabbitMQ": { - "HostName": "127.0.0.1", - "Port": 5672, - "UserName": "admin", - "Password": "admin", - "ExchangeName": "LINGYUN.ApiGateway", - "VirtualHost": "multi.service.test" - } - }, - "AuthServer": { - "Authority": "http://localhost:44385/", - "ApiName": "lingyun-abp-application" - }, - "Serilog": { - "MinimumLevel": { - "Default": "Debug", - "Override": { - "System": "Warning", - "Microsoft": "Warning" - } - }, - "Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId" ], - "WriteTo": [ - { - "Name": "File", - "Args": { - "path": "Logs/Debug-.log", - "restrictedToMinimumLevel": "Debug", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Info-.log", - "restrictedToMinimumLevel": "Information", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Warn-.log", - "restrictedToMinimumLevel": "Warning", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Error-.log", - "restrictedToMinimumLevel": "Error", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Fatal-.log", - "restrictedToMinimumLevel": "Fatal", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - } - ] - } -} +{ + "StringEncryption": { + "DefaultPassPhrase": "s46c5q55nxpeS8Ra", + "InitVectorBytes": "s83ng0abvd02js84", + "DefaultSalt": "sf&5)s3#" + }, + "Serilog": { + "MinimumLevel": { + "Default": "Debug", + "Override": { + "System": "Warning", + "Microsoft": "Warning", + "DotNetCore": "Information" + } + }, + "Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId", "WithEnvironmentName", "WithMachineName" ], + "WriteTo": [ + { + "Name": "Console", + "Args": { + "restrictedToMinimumLevel": "Debug", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Debug-.log", + "restrictedToMinimumLevel": "Debug", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Info-.log", + "restrictedToMinimumLevel": "Information", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Warn-.log", + "restrictedToMinimumLevel": "Warning", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Error-.log", + "restrictedToMinimumLevel": "Error", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Fatal-.log", + "restrictedToMinimumLevel": "Fatal", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + } + ] + } +} diff --git a/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/BackendAdminHostModule.Configure.cs b/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/BackendAdminHostModule.Configure.cs new file mode 100644 index 000000000..584864c4c --- /dev/null +++ b/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/BackendAdminHostModule.Configure.cs @@ -0,0 +1,259 @@ +using DotNetCore.CAP; +using LINGYUN.Abp.ExceptionHandling; +using LINGYUN.Abp.ExceptionHandling.Emailing; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.DataProtection; +using Microsoft.Extensions.Caching.StackExchangeRedis; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.OpenApi.Models; +using StackExchange.Redis; +using System; +using System.Text.Encodings.Web; +using System.Text.Unicode; +using Volo.Abp; +using Volo.Abp.Auditing; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Caching; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Identity.Localization; +using Volo.Abp.Json.SystemTextJson; +using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; +using Volo.Abp.PermissionManagement; +using Volo.Abp.VirtualFileSystem; + +namespace LINGYUN.Abp.BackendAdmin +{ + public partial class BackendAdminHostModule + { + private void PreConfigureCAP(IConfiguration configuration) + { + PreConfigure(options => + { + options + .UseMySql(configuration.GetConnectionString("Default")) + .UseRabbitMQ(rabbitMQOptions => + { + configuration.GetSection("CAP:RabbitMQ").Bind(rabbitMQOptions); + }) + .UseDashboard(); + }); + } + + private void ConfigureDbContext() + { + // 配置Ef + Configure(options => + { + options.UseMySQL(); + }); + } + + private void ConfigureJsonSerializer() + { + // 中文序列化的编码问题 + Configure(options => + { + options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); + }); + } + + private void ConfigurePermissionManagement() + { + Configure(options => + { + // Rename IdentityServer.Client.ManagePermissions + // See https://github.com/abpframework/abp/blob/dev/modules/identityserver/src/Volo.Abp.PermissionManagement.Domain.IdentityServer/Volo/Abp/PermissionManagement/IdentityServer/AbpPermissionManagementDomainIdentityServerModule.cs + options.ProviderPolicies[ClientPermissionValueProvider.ProviderName] = + LINGYUN.Abp.IdentityServer.AbpIdentityServerPermissions.Clients.ManagePermissions; + }); + } + + private void ConfigureExceptionHandling() + { + // 自定义需要处理的异常 + Configure(options => + { + // 加入需要处理的异常类型 + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + }); + + // 自定义需要发送邮件通知的异常类型 + Configure(options => + { + // 是否发送堆栈信息 + options.SendStackTrace = true; + // 未指定异常接收者的默认接收邮件 + // 请指定自己的邮件地址 + // options.DefaultReceiveEmail = "colin.in@foxmail.com"; + }); + } + + private void ConfigureCaching(IConfiguration configuration) + { + Configure(options => + { + // 最好统一命名,不然某个缓存变动其他应用服务有例外发生 + options.KeyPrefix = "LINGYUN.Abp.Application"; + // 滑动过期30天 + options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30); + // 绝对过期60天 + options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60); + }); + + Configure(options => + { + options.AutoEventSelectors.AddNamespace("Volo.Abp.TenantManagement"); + }); + + Configure(options => + { + var redisConfig = ConfigurationOptions.Parse(options.Configuration); + options.ConfigurationOptions = redisConfig; + options.InstanceName = configuration["Redis:InstanceName"]; + }); + } + + private void ConfigureVirtualFileSystem() + { + Configure(options => + { + options.FileSets.AddEmbedded("LINGYUN.Abp.BackendAdmin"); + }); + } + + private void ConfigureMultiTenancy(IConfiguration configuration) + { + // 多租户 + Configure(options => + { + options.IsEnabled = true; + }); + + var tenantResolveCfg = configuration.GetSection("App:Domains"); + if (tenantResolveCfg.Exists()) + { + Configure(options => + { + var domains = tenantResolveCfg.Get(); + foreach (var domain in domains) + { + options.AddDomainTenantResolver(domain); + } + }); + } + } + + private void ConfigureAuditing(IConfiguration configuration) + { + Configure(options => + { + options.ApplicationName = "Backend-Admin"; + // 是否启用实体变更记录 + var entitiesChangedConfig = configuration.GetSection("App:TrackingEntitiesChanged"); + if (entitiesChangedConfig.Exists() && entitiesChangedConfig.Get()) + { + options + .EntityHistorySelectors + .AddAllEntities(); + } + }); + } + + private void ConfigureSwagger(IServiceCollection services) + { + // Swagger + services.AddSwaggerGen( + options => + { + options.SwaggerDoc("v1", new OpenApiInfo { Title = "BackendAdmin API", Version = "v1" }); + options.DocInclusionPredicate((docName, description) => true); + options.CustomSchemaIds(type => type.FullName); + options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme + { + Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"", + Name = "Authorization", + In = ParameterLocation.Header, + Scheme = "bearer", + Type = SecuritySchemeType.Http, + BearerFormat = "JWT" + }); + options.AddSecurityRequirement(new OpenApiSecurityRequirement + { + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } + }, + new string[] { } + } + }); + }); + } + + private void ConfigureLocalization() + { + // 支持本地化语言类型 + Configure(options => + { + options.Languages.Add(new LanguageInfo("en", "en", "English")); + options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); + + options.Resources + .Get() + .AddVirtualJson("/Localization"); + options + .AddLanguagesMapOrUpdate( + "vue-admin-element-ui", + new NameValue("zh-Hans", "zh"), + new NameValue("en", "en")); + + // vben admin 语言映射 + options + .AddLanguagesMapOrUpdate( + "vben-admin-ui", + new NameValue("zh_CN", "zh-Hans")); + + options + .AddLanguageFilesMapOrUpdate( + "vue-admin-element-ui", + new NameValue("zh-Hans", "zh"), + new NameValue("en", "en")); + options + .AddLanguageFilesMapOrUpdate( + "vben-admin-ui", + new NameValue("zh_CN", "zh-Hans")); + + options.Resources.AddDynamic(); + }); + } + + private void ConfigureSecurity(IServiceCollection services, IConfiguration configuration, bool isDevelopment = false) + { + services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(options => + { + options.Authority = configuration["AuthServer:Authority"]; + options.RequireHttpsMetadata = false; + options.Audience = configuration["AuthServer:ApiName"]; + }); + + if (!isDevelopment) + { + var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); + services + .AddDataProtection() + .PersistKeysToStackExchangeRedis(redis, "BackendAdmin-Protection-Keys"); + } + } + } +} diff --git a/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/BackendAdminHostModule.Development.cs b/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/BackendAdminHostModule.Development.cs new file mode 100644 index 000000000..6db2e7402 --- /dev/null +++ b/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/BackendAdminHostModule.Development.cs @@ -0,0 +1,17 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Hosting; +using Volo.Abp; + +namespace LINGYUN.Abp.BackendAdmin +{ + public partial class BackendAdminHostModule + { + private void UseDevelopment(IApplicationBuilder app, ApplicationInitializationContext context) + { + if (context.GetEnvironment().IsDevelopment()) + { + app.UseProxyConnectTest(); + } + } + } +} diff --git a/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/BackendAdminHostModule.Seeder.cs b/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/BackendAdminHostModule.Seeder.cs new file mode 100644 index 000000000..90f31107f --- /dev/null +++ b/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/BackendAdminHostModule.Seeder.cs @@ -0,0 +1,23 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Volo.Abp; +using Volo.Abp.Data; +using Volo.Abp.Threading; + +namespace LINGYUN.Abp.BackendAdmin +{ + public partial class BackendAdminHostModule + { + private static void SeedData(ApplicationInitializationContext context) + { + if (context.GetEnvironment().IsDevelopment()) + { + AsyncHelper.RunSync(async () => + { + using var scope = context.ServiceProvider.CreateScope(); + await scope.ServiceProvider.GetRequiredService().SeedAsync(); + }); + } + } + } +} diff --git a/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/BackendAdminHostModule.cs b/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/BackendAdminHostModule.cs index 11b76eb88..05721823b 100644 --- a/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/BackendAdminHostModule.cs +++ b/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/BackendAdminHostModule.cs @@ -1,73 +1,46 @@ -using DotNetCore.CAP; -using LINGYUN.Abp.AspNetCore.HttpOverrides; +using LINGYUN.Abp.AspNetCore.HttpOverrides; using LINGYUN.Abp.Auditing; +using LINGYUN.Abp.AuditLogging.Elasticsearch; using LINGYUN.Abp.EventBus.CAP; -using LINGYUN.Abp.ExceptionHandling; using LINGYUN.Abp.ExceptionHandling.Emailing; using LINGYUN.Abp.FeatureManagement; using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore; +using LINGYUN.Abp.Logging.Serilog.Elasticsearch; using LINGYUN.Abp.MultiTenancy.DbFinder; using LINGYUN.Abp.PermissionManagement.Identity; using LINGYUN.Abp.SettingManagement; using LINGYUN.Abp.Sms.Aliyun; using LINGYUN.Abp.TenantManagement; -using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Caching.StackExchangeRedis; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Microsoft.OpenApi.Models; -using StackExchange.Redis; -using System; -using System.Text; -using System.Text.Encodings.Web; -using System.Text.Unicode; using Volo.Abp; using Volo.Abp.AspNetCore.Authentication.JwtBearer; -using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy; -using Volo.Abp.AspNetCore.Security.Claims; -using Volo.Abp.Auditing; -using Volo.Abp.AuditLogging.EntityFrameworkCore; -using Volo.Abp.Authorization.Permissions; +using Volo.Abp.AspNetCore.MultiTenancy; +using Volo.Abp.AspNetCore.Serilog; using Volo.Abp.Autofac; -using Volo.Abp.Caching; using Volo.Abp.Caching.StackExchangeRedis; -using Volo.Abp.Data; -using Volo.Abp.Domain.Entities.Events.Distributed; -using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore.MySQL; using Volo.Abp.FeatureManagement; using Volo.Abp.FeatureManagement.EntityFrameworkCore; using Volo.Abp.Identity.EntityFrameworkCore; -using Volo.Abp.Identity.Localization; using Volo.Abp.IdentityServer.EntityFrameworkCore; -using Volo.Abp.Json.SystemTextJson; -using Volo.Abp.Localization; using Volo.Abp.Modularity; -using Volo.Abp.MultiTenancy; using Volo.Abp.PermissionManagement; using Volo.Abp.PermissionManagement.EntityFrameworkCore; using Volo.Abp.PermissionManagement.HttpApi; using Volo.Abp.PermissionManagement.IdentityServer; -using Volo.Abp.AspNetCore.Serilog; -using Volo.Abp.Security.Claims; -using Volo.Abp.Security.Encryption; using Volo.Abp.SettingManagement.EntityFrameworkCore; using Volo.Abp.TenantManagement.EntityFrameworkCore; -using Volo.Abp.Threading; -using Volo.Abp.VirtualFileSystem; -using LINGYUN.Abp.AuditLogging.Elasticsearch; -using LINGYUN.Abp.Logging.Serilog.Elasticsearch; namespace LINGYUN.Abp.BackendAdmin { [DependsOn( + typeof(AbpAspNetCoreSerilogModule), typeof(AbpLoggingSerilogElasticsearchModule), typeof(AbpAuditLoggingElasticsearchModule), - typeof(AbpAspNetCoreMvcUiMultiTenancyModule), + typeof(AbpAspNetCoreMultiTenancyModule), typeof(AbpSettingManagementApplicationModule), typeof(AbpSettingManagementHttpApiModule), typeof(AbpPermissionManagementApplicationModule), @@ -82,7 +55,6 @@ namespace LINGYUN.Abp.BackendAdmin typeof(AbpEntityFrameworkCoreMySQLModule), typeof(AbpIdentityEntityFrameworkCoreModule),// 用户角色权限需要引用包 typeof(AbpIdentityServerEntityFrameworkCoreModule), // 客户端权限需要引用包 - //typeof(AbpAuditLoggingEntityFrameworkCoreModule), typeof(AbpTenantManagementEntityFrameworkCoreModule), typeof(AbpSettingManagementEntityFrameworkCoreModule), typeof(AbpPermissionManagementDomainIdentityModule), @@ -97,25 +69,15 @@ namespace LINGYUN.Abp.BackendAdmin typeof(AbpDbFinderMultiTenancyModule), typeof(AbpCachingStackExchangeRedisModule), typeof(AbpAspNetCoreHttpOverridesModule), - typeof(AbpAspNetCoreSerilogModule), typeof(AbpAutofacModule) )] - public class BackendAdminHostModule : AbpModule + public partial class BackendAdminHostModule : AbpModule { public override void PreConfigureServices(ServiceConfigurationContext context) { var configuration = context.Services.GetConfiguration(); - PreConfigure(options => - { - options - .UseMySql(configuration.GetConnectionString("Default")) - .UseRabbitMQ(rabbitMQOptions => - { - configuration.GetSection("CAP:RabbitMQ").Bind(rabbitMQOptions); - }) - .UseDashboard(); - }); + PreConfigureCAP(configuration); } public override void ConfigureServices(ServiceConfigurationContext context) @@ -123,207 +85,17 @@ namespace LINGYUN.Abp.BackendAdmin var hostingEnvironment = context.Services.GetHostingEnvironment(); var configuration = hostingEnvironment.BuildConfiguration(); - // 配置Ef - Configure(options => - { - options.UseMySQL(); - }); - - // 中文序列化的编码问题 - Configure(options => - { - options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); - }); - - // 加解密 - Configure(options => - { - var encryptionConfiguration = configuration.GetSection("Encryption"); - if (encryptionConfiguration.Exists()) - { - options.DefaultPassPhrase = encryptionConfiguration["PassPhrase"] ?? options.DefaultPassPhrase; - options.DefaultSalt = encryptionConfiguration.GetSection("Salt").Exists() - ? Encoding.ASCII.GetBytes(encryptionConfiguration["Salt"]) - : options.DefaultSalt; - options.InitVectorBytes = encryptionConfiguration.GetSection("InitVector").Exists() - ? Encoding.ASCII.GetBytes(encryptionConfiguration["InitVector"]) - : options.InitVectorBytes; - } - }); - - Configure(options => - { - // Rename IdentityServer.Client.ManagePermissions - // See https://github.com/abpframework/abp/blob/dev/modules/identityserver/src/Volo.Abp.PermissionManagement.Domain.IdentityServer/Volo/Abp/PermissionManagement/IdentityServer/AbpPermissionManagementDomainIdentityServerModule.cs - options.ProviderPolicies[ClientPermissionValueProvider.ProviderName] = - LINGYUN.Abp.IdentityServer.AbpIdentityServerPermissions.Clients.ManagePermissions; - }); - - // 自定义需要处理的异常 - Configure(options => - { - // 加入需要处理的异常类型 - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - }); - // 自定义需要发送邮件通知的异常类型 - Configure(options => - { - // 是否发送堆栈信息 - options.SendStackTrace = true; - // 未指定异常接收者的默认接收邮件 - // 请指定自己的邮件地址 - // options.DefaultReceiveEmail = "colin.in@foxmail.com"; - }); - - - Configure(options => - { - // 最好统一命名,不然某个缓存变动其他应用服务有例外发生 - options.KeyPrefix = "LINGYUN.Abp.Application"; - // 滑动过期30天 - options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30); - // 绝对过期60天 - options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60); - }); - - Configure(options => - { - options.AutoEventSelectors.AddNamespace("Volo.Abp.TenantManagement"); - }); - - Configure(options => - { - var redisConfig = ConfigurationOptions.Parse(options.Configuration); - options.ConfigurationOptions = redisConfig; - options.InstanceName = configuration["Redis:InstanceName"]; - }); - - Configure(options => - { - options.FileSets.AddEmbedded("LINGYUN.Abp.BackendAdmin"); - }); - - // 多租户 - Configure(options => - { - options.IsEnabled = true; - }); - - var tenantResolveCfg = configuration.GetSection("App:Domains"); - if (tenantResolveCfg.Exists()) - { - Configure(options => - { - var domains = tenantResolveCfg.Get(); - foreach (var domain in domains) - { - options.AddDomainTenantResolver(domain); - } - }); - } - - Configure(options => - { - options.ApplicationName = "Backend-Admin"; - // 是否启用实体变更记录 - var entitiesChangedConfig = configuration.GetSection("App:TrackingEntitiesChanged"); - if (entitiesChangedConfig.Exists() && entitiesChangedConfig.Get()) - { - options - .EntityHistorySelectors - .AddAllEntities(); - } - }); - - // Swagger - context.Services.AddSwaggerGen( - options => - { - options.SwaggerDoc("v1", new OpenApiInfo { Title = "BackendAdmin API", Version = "v1" }); - options.DocInclusionPredicate((docName, description) => true); - options.CustomSchemaIds(type => type.FullName); - options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme - { - Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"", - Name = "Authorization", - In = ParameterLocation.Header, - Scheme = "bearer", - Type = SecuritySchemeType.Http, - BearerFormat = "JWT" - }); - options.AddSecurityRequirement(new OpenApiSecurityRequirement - { - { - new OpenApiSecurityScheme - { - Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } - }, - new string[] { } - } - }); - }); - - // 支持本地化语言类型 - Configure(options => - { - options.Languages.Add(new LanguageInfo("en", "en", "English")); - options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); - - options.Resources - .Get() - .AddVirtualJson("/Localization"); - options - .AddLanguagesMapOrUpdate( - "vue-admin-element-ui", - new NameValue("zh-Hans", "zh"), - new NameValue("en", "en")); - - // vben admin 语言映射 - options - .AddLanguagesMapOrUpdate( - "vben-admin-ui", - new NameValue("zh_CN", "zh-Hans")); - - options - .AddLanguageFilesMapOrUpdate( - "vue-admin-element-ui", - new NameValue("zh-Hans", "zh"), - new NameValue("en", "en")); - options - .AddLanguageFilesMapOrUpdate( - "vben-admin-ui", - new NameValue("zh_CN", "zh-Hans")); - - options.Resources.AddDynamic(); - }); - - Configure(options => - { - options.Maps.TryAdd("name", () => AbpClaimTypes.UserName); - }); - - context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) - .AddJwtBearer(options => - { - options.Authority = configuration["AuthServer:Authority"]; - options.RequireHttpsMetadata = false; - options.Audience = configuration["AuthServer:ApiName"]; - }); - - if (!hostingEnvironment.IsDevelopment()) - { - var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); - context.Services - .AddDataProtection() - .PersistKeysToStackExchangeRedis(redis, "BackendAdmin-Protection-Keys"); - } + ConfigureDbContext(); + ConfigureJsonSerializer(); + ConfigurePermissionManagement(); + ConfigureExceptionHandling(); + ConfigureCaching(configuration); + ConfigureVirtualFileSystem(); + ConfigureMultiTenancy(configuration); + ConfigureAuditing(configuration); + ConfigureSwagger(context.Services); + ConfigureLocalization(); + ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment()); } public override void OnApplicationInitialization(ApplicationInitializationContext context) @@ -353,27 +125,11 @@ namespace LINGYUN.Abp.BackendAdmin // 审计日志 app.UseAuditing(); app.UseAbpSerilogEnrichers(); - // 处理微信消息 - // app.UseWeChatSignature(); + UseDevelopment(app, context); // 路由 app.UseConfiguredEndpoints(); - // 调试代理连接信息用,上线后注释掉 - app.UseProxyConnectTest(); - - if (context.GetEnvironment().IsDevelopment()) - { - SeedData(context); - } - } - - private void SeedData(ApplicationInitializationContext context) - { - AsyncHelper.RunSync(async () => - { - using var scope = context.ServiceProvider.CreateScope(); - await scope.ServiceProvider.GetRequiredService().SeedAsync(); - }); + SeedData(context); } } } diff --git a/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/EntityFrameworkCore/BackendAdminHostMigrationsDbContext.cs b/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/EntityFrameworkCore/BackendAdminHostMigrationsDbContext.cs index 521f632cc..edaa221d3 100644 --- a/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/EntityFrameworkCore/BackendAdminHostMigrationsDbContext.cs +++ b/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/EntityFrameworkCore/BackendAdminHostMigrationsDbContext.cs @@ -1,30 +1,28 @@ -using Microsoft.EntityFrameworkCore; -using Volo.Abp.AuditLogging.EntityFrameworkCore; -using Volo.Abp.EntityFrameworkCore; -using Volo.Abp.FeatureManagement.EntityFrameworkCore; -using Volo.Abp.PermissionManagement.EntityFrameworkCore; -using Volo.Abp.SettingManagement.EntityFrameworkCore; -using Volo.Abp.TenantManagement.EntityFrameworkCore; - -namespace LINGYUN.Abp.BackendAdmin.EntityFrameworkCore -{ - public class BackendAdminHostMigrationsDbContext : AbpDbContext - { - public BackendAdminHostMigrationsDbContext(DbContextOptions options) - : base(options) - { - - } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - base.OnModelCreating(modelBuilder); - - modelBuilder.ConfigureAuditLogging(); - modelBuilder.ConfigureFeatureManagement(); - modelBuilder.ConfigureTenantManagement(); - modelBuilder.ConfigureSettingManagement(); - modelBuilder.ConfigurePermissionManagement(); - } - } -} +using Microsoft.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.FeatureManagement.EntityFrameworkCore; +using Volo.Abp.PermissionManagement.EntityFrameworkCore; +using Volo.Abp.SettingManagement.EntityFrameworkCore; +using Volo.Abp.TenantManagement.EntityFrameworkCore; + +namespace LINGYUN.Abp.BackendAdmin.EntityFrameworkCore +{ + public class BackendAdminHostMigrationsDbContext : AbpDbContext + { + public BackendAdminHostMigrationsDbContext(DbContextOptions options) + : base(options) + { + + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.ConfigureFeatureManagement(); + modelBuilder.ConfigureTenantManagement(); + modelBuilder.ConfigureSettingManagement(); + modelBuilder.ConfigurePermissionManagement(); + } + } +} diff --git a/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/LINGYUN.Abp.BackendAdmin.HttpApi.Host.csproj b/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/LINGYUN.Abp.BackendAdmin.HttpApi.Host.csproj index 006f860e5..0c8671ef0 100644 --- a/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/LINGYUN.Abp.BackendAdmin.HttpApi.Host.csproj +++ b/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/LINGYUN.Abp.BackendAdmin.HttpApi.Host.csproj @@ -1,4 +1,4 @@ - + net5.0 @@ -33,14 +33,16 @@ + + - - + + @@ -53,7 +55,6 @@ - diff --git a/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/Properties/launchSettings.json b/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/Properties/launchSettings.json index 7a6916353..f04e44238 100644 --- a/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/Properties/launchSettings.json +++ b/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/Properties/launchSettings.json @@ -13,7 +13,7 @@ "launchBrowser": false, "applicationUrl": "http://0.0.0.0:30010", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" + "ASPNETCORE_ENVIRONMENT": "Production" } } } diff --git a/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/appsettings.Development.json b/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/appsettings.Development.json new file mode 100644 index 000000000..4bf63229f --- /dev/null +++ b/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/appsettings.Development.json @@ -0,0 +1,92 @@ +{ + "App": { + "TrackingEntitiesChanged": true, + "Forwarded": { + "ForwardedHeaders": 5, + "KnownProxies": [ + "localhost" + ] + } + }, + "ConnectionStrings": { + "Default": "Server=localhost;Database=Platform;User Id=colin;Password=123456", + "AbpIdentity": "Server=localhost;Database=IdentityServer;User Id=colin;Password=123456", + "AbpIdentityServer": "Server=localhost;Database=IdentityServer;User Id=colin;Password=123456", + "AbpTenantManagement": "Server=localhost;Database=Platform;User Id=colin;Password=123456", + "AbpSettingManagement": "Server=localhost;Database=Platform;User Id=colin;Password=123456", + "AbpFeatureManagement": "Server=localhost;Database=Platform;User Id=colin;Password=123456", + "AbpPermissionManagement": "Server=localhost;Database=Platform;User Id=colin;Password=123456", + "AbpLocalizationManagement": "Server=localhost;Database=Platform;User Id=colin;Password=123456" + }, + "CAP": { + "EventBus": { + "DefaultGroup": "BackendAdmin", + "Version": "v1", + "FailedRetryInterval": 300, + "FailedRetryCount": 10 + }, + "MySql": { + "TableNamePrefix": "admin", + "ConnectionString": "Server=localhost;Database=Platform;User Id=root;Password=123456" + }, + "RabbitMQ": { + "HostName": "localhost", + "Port": 5672, + "UserName": "guest", + "Password": "guest", + "ExchangeName": "LINGYUN.Abp.Application", + "VirtualHost": "/" + } + }, + "Redis": { + "Configuration": "localhost,defaultDatabase=10", + "InstanceName": "LINGYUN.Abp.Application" + }, + "AuthServer": { + "Authority": "http://localhost:44385/", + "ApiName": "lingyun-abp-application" + }, + "Logging": { + "Serilog": { + "Elasticsearch": { + "IndexFormat": "lingyun.abp.logging-{0:yyyy.MM.dd}" + } + } + }, + "AuditLogging": { + "Elasticsearch": { + "IndexPrefix": "lingyun.abp.auditing" + } + }, + "Elasticsearch": { + "NodeUris": "http://localhost:9200" + }, + "Serilog": { + "MinimumLevel": { + "Default": "Debug", + "Override": { + "System": "Warning", + "Microsoft": "Warning", + "DotNetCore": "Debug" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "restrictedToMinimumLevel": "Debug", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "Elasticsearch", + "Args": { + "nodeUris": "http://localhost:9200", + "indexFormat": "lingyun.abp.logging-{0:yyyy.MM.dd}", + "autoRegisterTemplate": true, + "autoRegisterTemplateVersion": "ESv7" + } + } + ] + } +} diff --git a/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/appsettings.json b/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/appsettings.json new file mode 100644 index 000000000..5813c33d9 --- /dev/null +++ b/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/appsettings.json @@ -0,0 +1,72 @@ +{ + "StringEncryption": { + "DefaultPassPhrase": "s46c5q55nxpeS8Ra", + "InitVectorBytes": "s83ng0abvd02js84", + "DefaultSalt": "sf&5)s3#" + }, + "Serilog": { + "MinimumLevel": { + "Default": "Information", + "Override": { + "System": "Warning", + "Microsoft": "Warning", + "DotNetCore": "Information" + } + }, + "Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId", "WithEnvironmentName", "WithMachineName" ], + "WriteTo": [ + { + "Name": "Console", + "Args": { + "restrictedToMinimumLevel": "Debug", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Debug-.log", + "restrictedToMinimumLevel": "Debug", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Info-.log", + "restrictedToMinimumLevel": "Information", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Warn-.log", + "restrictedToMinimumLevel": "Warning", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Error-.log", + "restrictedToMinimumLevel": "Error", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Fatal-.log", + "restrictedToMinimumLevel": "Fatal", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + } + ] + } +} diff --git a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/ApiGatewayHostModule.cs b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/ApiGatewayHostModule.cs index f06c4137c..98d185d68 100644 --- a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/ApiGatewayHostModule.cs +++ b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/ApiGatewayHostModule.cs @@ -19,21 +19,18 @@ using Ocelot.Middleware.Multiplexer; using Ocelot.Provider.Polly; using StackExchange.Redis; using System; -using System.Text; using System.Text.Encodings.Web; using System.Text.Unicode; using Volo.Abp; -using Volo.Abp.AspNetCore; +using Volo.Abp.AspNetCore.Serilog; using Volo.Abp.Autofac; using Volo.Abp.AutoMapper; using Volo.Abp.Caching; using Volo.Abp.Caching.StackExchangeRedis; using Volo.Abp.Http.Client.IdentityModel; -using Volo.Abp.Json; using Volo.Abp.Json.SystemTextJson; using Volo.Abp.Localization; using Volo.Abp.Modularity; -using Volo.Abp.Security.Encryption; using Volo.Abp.VirtualFileSystem; namespace LINGYUN.ApiGateway @@ -45,7 +42,7 @@ namespace LINGYUN.ApiGateway typeof(AbpAutoMapperModule), typeof(ApiGatewayHttpApiClientModule), typeof(AbpCAPEventBusModule), - typeof(AbpAspNetCoreModule), + typeof(AbpAspNetCoreSerilogModule), typeof(AbpAspNetCoreHttpOverridesModule) )] public class ApiGatewayHostModule : AbpModule @@ -122,22 +119,6 @@ namespace LINGYUN.ApiGateway options.InstanceName = configuration["Redis:InstanceName"]; }); - // 加解密 - Configure(options => - { - var encryptionConfiguration = configuration.GetSection("Encryption"); - if (encryptionConfiguration.Exists()) - { - options.DefaultPassPhrase = encryptionConfiguration["PassPhrase"] ?? options.DefaultPassPhrase; - options.DefaultSalt = encryptionConfiguration.GetSection("Salt").Exists() - ? Encoding.ASCII.GetBytes(encryptionConfiguration["Salt"]) - : options.DefaultSalt; - options.InitVectorBytes = encryptionConfiguration.GetSection("InitVector").Exists() - ? Encoding.ASCII.GetBytes(encryptionConfiguration["InitVector"]) - : options.InitVectorBytes; - } - }); - Configure(options => { options.FileSets.AddEmbedded(); @@ -215,6 +196,7 @@ namespace LINGYUN.ApiGateway // 启用ws协议 app.UseWebSockets(); + app.UseAbpSerilogEnrichers(); app.UseOcelot().Wait(); } } diff --git a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/LINGYUN.ApiGateway.Host.csproj b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/LINGYUN.ApiGateway.Host.csproj index 74d0576d5..a5635921f 100644 --- a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/LINGYUN.ApiGateway.Host.csproj +++ b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/LINGYUN.ApiGateway.Host.csproj @@ -1,4 +1,4 @@ - + net5.0 @@ -17,11 +17,14 @@ + + + diff --git a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/appsettings.Development.json b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/appsettings.Development.json new file mode 100644 index 000000000..45de74e69 --- /dev/null +++ b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/appsettings.Development.json @@ -0,0 +1,79 @@ +{ + "EnabledDynamicOcelot": true, + "ApiGateway": { + "AppId": "TEST-APP" //这里是用于Ocelot主机去API服务器获取参数的标识,指定需要获取什么类型的网关配置 + }, + "Redis": { + "Configuration": "localhost,defaultDatabase=10", + "InstanceName": "LINGYUN.Abp.Application" + }, + "RemoteServices": { + "ApiGateway": { + "BaseUrl": "http://localhost:30001/", + "IdentityClient": "ApigatewayHostClient" + } + }, + "IdentityClients": { + "ApigatewayHostClient": { + "Authority": "http://localhost:44385", + "RequireHttps": false, + "GrantType": "client_credentials", + "ClientId": "ApigatewayHostClient", + "ClientSecret": "1q2w3e*", + "Scope": "lingyun-abp-application" + } + }, + "CAP": { + "Abp": { + "NotifyFailedCallback": true, + "CleanUpExpiresMessageBatch": 1000, + "CleanUpExpiresMessageInterval": 3600000 + }, + "EventBus": { + "DefaultGroupName": "ApiGateway-Host", + "Version": "v1", + "FailedRetryInterval": 300, + "FailedRetryCount": 10 + }, + "RabbitMQ": { + "HostName": "localhost", + "Port": 5672, + "UserName": "guest", + "Password": "guest", + "ExchangeName": "LINGYUN.ApiGateway", + "VirtualHost": "/" + } + }, + "AuthServer": { + "Authority": "http://localhost:44385/", + "ApiName": "lingyun-abp-application" + }, + "Serilog": { + "MinimumLevel": { + "Default": "Debug", + "Override": { + "System": "Warning", + "Microsoft": "Warning", + "DotNetCore": "Debug" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "restrictedToMinimumLevel": "Debug", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "Elasticsearch", + "Args": { + "nodeUris": "http://localhost:9200", + "indexFormat": "lingyun.abp.logging-{0:yyyy.MM.dd}", + "autoRegisterTemplate": true, + "autoRegisterTemplateVersion": "ESv7" + } + } + ] + } +} diff --git a/aspnet-core/configuration/apigateway/LINGYUN.ApiGateway.HttpApi.Host/appsettings.Development.json b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/appsettings.json similarity index 62% rename from aspnet-core/configuration/apigateway/LINGYUN.ApiGateway.HttpApi.Host/appsettings.Development.json rename to aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/appsettings.json index 7a258c74d..4421b97ef 100644 --- a/aspnet-core/configuration/apigateway/LINGYUN.ApiGateway.HttpApi.Host/appsettings.Development.json +++ b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/appsettings.json @@ -1,94 +1,73 @@ -{ - "App": { - "TrackingEntitiesChanged": true, - "SelfUrl": "http://localhost:44385/" - }, - "ConnectionStrings": { - "Default": "Server=127.0.0.1;Database=ApiGateway;User Id=root;Password=123456", - "ApiGateway": "Server=127.0.0.1;Database=ApiGateway;User Id=root;Password=123456", - "AbpTenantManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpSettingManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpPermissionManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456" - }, - "Redis": { - "Configuration": "127.0.0.1,defaultDatabase=10", - "InstanceName": "LINGYUN.AbpApplication" - }, - "CAP": { - "EventBus": { - "DefaultGroupName": "ApiGateway-Admin", - "Version": "v1", - "FailedRetryInterval": 300, - "FailedRetryCount": 10 - }, - "RabbitMQ": { - "HostName": "127.0.0.1", - "Port": 5672, - "UserName": "admin", - "Password": "admin", - "ExchangeName": "LINGYUN.ApiGateway", - "VirtualHost": "multi.service.test" - } - }, - "AuthServer": { - "Authority": "http://localhost:44385/", - "ApiName": "lingyun-abp-application" - }, - "Serilog": { - "MinimumLevel": { - "Default": "Debug", - "Override": { - "System": "Warning", - "Microsoft": "Warning" - } - }, - "Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId" ], - "WriteTo": [ - { - "Name": "File", - "Args": { - "path": "Logs/Debug-.log", - "restrictedToMinimumLevel": "Debug", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Info-.log", - "restrictedToMinimumLevel": "Information", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Warn-.log", - "restrictedToMinimumLevel": "Warning", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Error-.log", - "restrictedToMinimumLevel": "Error", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Fatal-.log", - "restrictedToMinimumLevel": "Fatal", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - } - ] - } -} +{ + "StringEncryption": { + "DefaultPassPhrase": "s46c5q55nxpeS8Ra", + "InitVectorBytes": "s83ng0abvd02js84", + "DefaultSalt": "sf&5)s3#" + }, + "Serilog": { + "MinimumLevel": { + "Default": "Debug", + "Override": { + "System": "Warning", + "Microsoft": "Warning" + } + }, + "Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId", "WithEnvironmentName", "WithMachineName" ], + "WriteTo": [ + { + "Name": "Console", + "Args": { + "initialMinimumLevel": "Information", + "standardErrorFromLevel": "Information", + "restrictedToMinimumLevel": "Information", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Debug-.log", + "restrictedToMinimumLevel": "Debug", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Info-.log", + "restrictedToMinimumLevel": "Information", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Warn-.log", + "restrictedToMinimumLevel": "Warning", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Error-.log", + "restrictedToMinimumLevel": "Error", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Fatal-.log", + "restrictedToMinimumLevel": "Fatal", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + } + ] + } +} diff --git a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/ApiGatewayHttpApiHostModule.Configure.cs b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/ApiGatewayHttpApiHostModule.Configure.cs new file mode 100644 index 000000000..f1e4a7e58 --- /dev/null +++ b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/ApiGatewayHttpApiHostModule.Configure.cs @@ -0,0 +1,179 @@ +using DotNetCore.CAP; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.DataProtection; +using Microsoft.Extensions.Caching.StackExchangeRedis; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.OpenApi.Models; +using StackExchange.Redis; +using System; +using System.Text.Encodings.Web; +using System.Text.Unicode; +using Volo.Abp.Auditing; +using Volo.Abp.AutoMapper; +using Volo.Abp.Caching; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Json.SystemTextJson; +using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; +using Volo.Abp.VirtualFileSystem; + +namespace LINGYUN.ApiGateway +{ + public partial class ApiGatewayHttpApiHostModule + { + private void PreConfigureCAP(IConfiguration configuration) + { + PreConfigure(options => + { + options + .UseMySql(configuration.GetConnectionString("Default")) + .UseRabbitMQ(rabbitMQOptions => + { + configuration.GetSection("CAP:RabbitMQ").Bind(rabbitMQOptions); + }); + }); + } + + + private void ConfigureAutoMapper() + { + Configure(options => + { + options.AddProfile(validate: true); + }); + } + + private void ConfigureDbContext() + { + // 配置Ef + Configure(options => + { + options.UseMySQL(); + }); + } + + private void ConfigureJsonSerializer() + { + // 中文序列化的编码问题 + Configure(options => + { + options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); + }); + } + + private void ConfigureCaching(IConfiguration configuration) + { + Configure(options => + { + // 最好统一命名,不然某个缓存变动其他应用服务有例外发生 + options.KeyPrefix = "LINGYUN.Abp.Application"; + // 滑动过期30天 + options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30); + // 绝对过期60天 + options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(60); + }); + + Configure(options => + { + var redisConfig = ConfigurationOptions.Parse(options.Configuration); + options.ConfigurationOptions = redisConfig; + options.InstanceName = configuration["Redis:InstanceName"]; + }); + } + + private void ConfigureVirtualFileSystem() + { + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + } + + private void ConfigureMultiTenancy(IConfiguration configuration) + { + // 多租户 + Configure(options => + { + options.IsEnabled = false; + }); + } + + private void ConfigureAuditing(IConfiguration configuration) + { + Configure(options => + { + options.ApplicationName = "ApiGateWay-Admin"; + // 是否启用实体变更记录 + var entitiesChangedConfig = configuration.GetSection("App:TrackingEntitiesChanged"); + if (entitiesChangedConfig.Exists() && entitiesChangedConfig.Get()) + { + options + .EntityHistorySelectors + .AddAllEntities(); + } + }); + } + + private void ConfigureSwagger(IServiceCollection services) + { + // Swagger + services.AddSwaggerGen( + options => + { + options.SwaggerDoc("v1", new OpenApiInfo { Title = "ApiGateway API", Version = "v1" }); + options.DocInclusionPredicate((docName, description) => true); + options.CustomSchemaIds(type => type.FullName); + options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme + { + Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"", + Name = "Authorization", + In = ParameterLocation.Header, + Scheme = "bearer", + Type = SecuritySchemeType.Http, + BearerFormat = "JWT" + }); + options.AddSecurityRequirement(new OpenApiSecurityRequirement + { + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } + }, + new string[] { } + } + }); + }); + } + + private void ConfigureLocalization() + { + // 支持本地化语言类型 + Configure(options => + { + options.Languages.Add(new LanguageInfo("en", "en", "English")); + options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); + }); + } + + private void ConfigureSecurity(IServiceCollection services, IConfiguration configuration, bool isDevelopment = false) + { + services + .AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(options => + { + options.Authority = configuration["AuthServer:Authority"]; + options.RequireHttpsMetadata = false; + options.Audience = configuration["AuthServer:ApiName"]; + }); + + if (!isDevelopment) + { + var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); + services + .AddDataProtection() + .PersistKeysToStackExchangeRedis(redis, "ApiGatewayAdmin-Protection-Keys"); + } + } + } +} diff --git a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/ApiGatewayHttpApiHostModule.Seeder.cs b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/ApiGatewayHttpApiHostModule.Seeder.cs new file mode 100644 index 000000000..c22171bbe --- /dev/null +++ b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/ApiGatewayHttpApiHostModule.Seeder.cs @@ -0,0 +1,24 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; +using Volo.Abp.Data; +using Volo.Abp.Threading; + +namespace LINGYUN.ApiGateway +{ + public partial class ApiGatewayHttpApiHostModule + { + private void SeedData(ApplicationInitializationContext context) + { + var configuration = context.GetConfiguration(); + if (configuration.GetSection("ApiGateway:SeedInitScript").Get()) + { + AsyncHelper.RunSync(async () => + { + using var scope = context.ServiceProvider.CreateScope(); + await scope.ServiceProvider.GetRequiredService().SeedAsync(); + }); + } + } + } +} diff --git a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/ApiGatewayHttpApiHostModule.cs b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/ApiGatewayHttpApiHostModule.cs index 05726bba1..f4dffc30f 100644 --- a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/ApiGatewayHttpApiHostModule.cs +++ b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/ApiGatewayHttpApiHostModule.cs @@ -1,259 +1,97 @@ -using DotNetCore.CAP; -using LINGYUN.Abp.AspNetCore.HttpOverrides; -using LINGYUN.Abp.EventBus.CAP; -using LINGYUN.Abp.MultiTenancy.DbFinder; -using LINGYUN.ApiGateway.EntityFrameworkCore; -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.DataProtection; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Caching.StackExchangeRedis; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.OpenApi.Models; -using StackExchange.Redis; -using System; -using System.Text; -using System.Text.Encodings.Web; -using System.Text.Unicode; -using Volo.Abp; -using Volo.Abp.AspNetCore.Security.Claims; -using Volo.Abp.Auditing; -using Volo.Abp.AuditLogging.EntityFrameworkCore; -using Volo.Abp.Autofac; -using Volo.Abp.AutoMapper; -using Volo.Abp.Caching; -using Volo.Abp.Caching.StackExchangeRedis; -using Volo.Abp.Data; -using Volo.Abp.EntityFrameworkCore; -using Volo.Abp.EntityFrameworkCore.MySQL; -using Volo.Abp.Json; -using Volo.Abp.Json.SystemTextJson; -using Volo.Abp.Localization; -using Volo.Abp.Modularity; -using Volo.Abp.MultiTenancy; -using Volo.Abp.PermissionManagement.EntityFrameworkCore; -using Volo.Abp.Security.Claims; -using Volo.Abp.Security.Encryption; -using Volo.Abp.SettingManagement.EntityFrameworkCore; -using Volo.Abp.TenantManagement.EntityFrameworkCore; -using Volo.Abp.Threading; - -namespace LINGYUN.ApiGateway -{ - [DependsOn( - typeof(ApiGatewayApplicationModule), - typeof(ApiGatewayEntityFrameworkCoreModule), - typeof(ApiGatewayHttpApiModule), - typeof(AbpEntityFrameworkCoreMySQLModule), - typeof(AbpAuditLoggingEntityFrameworkCoreModule), - typeof(AbpTenantManagementEntityFrameworkCoreModule), - typeof(AbpSettingManagementEntityFrameworkCoreModule), - typeof(AbpPermissionManagementEntityFrameworkCoreModule), - typeof(AbpCAPEventBusModule), - typeof(AbpDbFinderMultiTenancyModule), - typeof(AbpCachingStackExchangeRedisModule), - typeof(AbpAspNetCoreHttpOverridesModule), - typeof(AbpAutofacModule) - )] - public class ApiGatewayHttpApiHostModule : AbpModule - { - public override void PreConfigureServices(ServiceConfigurationContext context) - { - var configuration = context.Services.GetConfiguration(); - - PreConfigure(options => - { - options - .UseMySql(configuration.GetConnectionString("Default")) - .UseRabbitMQ(rabbitMQOptions => - { - configuration.GetSection("CAP:RabbitMQ").Bind(rabbitMQOptions); - }); - }); - } - - public override void ConfigureServices(ServiceConfigurationContext context) - { - var hostingEnvironment = context.Services.GetHostingEnvironment(); - var configuration = hostingEnvironment.BuildConfiguration(); - - // 配置Ef - Configure(options => - { - options.UseMySQL(); - }); - - // 中文序列化的编码问题 - Configure(options => - { - options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); - }); - - // 加解密 - Configure(options => - { - var encryptionConfiguration = configuration.GetSection("Encryption"); - if (encryptionConfiguration.Exists()) - { - options.DefaultPassPhrase = encryptionConfiguration["PassPhrase"] ?? options.DefaultPassPhrase; - options.DefaultSalt = encryptionConfiguration.GetSection("Salt").Exists() - ? Encoding.ASCII.GetBytes(encryptionConfiguration["Salt"]) - : options.DefaultSalt; - options.InitVectorBytes = encryptionConfiguration.GetSection("InitVector").Exists() - ? Encoding.ASCII.GetBytes(encryptionConfiguration["InitVector"]) - : options.InitVectorBytes; - } - }); - - Configure(options => - { - // 最好统一命名,不然某个缓存变动其他应用服务有例外发生 - options.KeyPrefix = "LINGYUN.Abp.Application"; - // 滑动过期30天 - options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30); - // 绝对过期60天 - options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(60); - }); - - Configure(options => - { - var redisConfig = ConfigurationOptions.Parse(options.Configuration); - options.ConfigurationOptions = redisConfig; - options.InstanceName = configuration["Redis:InstanceName"]; - }); - - // 多租户 - Configure(options => - { - options.IsEnabled = false; - }); - - Configure(options => - { - options.ApplicationName = "ApiGateWay-Admin"; - // 是否启用实体变更记录 - var entitiesChangedConfig = configuration.GetSection("App:TrackingEntitiesChanged"); - if (entitiesChangedConfig.Exists() && entitiesChangedConfig.Get()) - { - options - .EntityHistorySelectors - .AddAllEntities(); - } - }); - - //Configure(options => - //{ - // options.TenantResolvers.Insert(0, new AuthorizationTenantResolveContributor()); - //}); - - // Swagger - context.Services.AddSwaggerGen( - options => - { - options.SwaggerDoc("v1", new OpenApiInfo { Title = "ApiGateway API", Version = "v1" }); - options.DocInclusionPredicate((docName, description) => true); - options.CustomSchemaIds(type => type.FullName); - options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme - { - Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"", - Name = "Authorization", - In = ParameterLocation.Header, - Scheme = "bearer", - Type = SecuritySchemeType.Http, - BearerFormat = "JWT" - }); - options.AddSecurityRequirement(new OpenApiSecurityRequirement - { - { - new OpenApiSecurityScheme - { - Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } - }, - new string[] { } - } - }); - }); - - // 支持本地化语言类型 - Configure(options => - { - options.Languages.Add(new LanguageInfo("en", "en", "English")); - options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); - }); - - Configure(options => - { - options.Maps.TryAdd("name", () => AbpClaimTypes.UserName); - }); - - context.Services - .AddAuthentication(JwtBearerDefaults.AuthenticationScheme) - .AddJwtBearer(options => - { - options.Authority = configuration["AuthServer:Authority"]; - options.RequireHttpsMetadata = false; - options.Audience = configuration["AuthServer:ApiName"]; - }); - - if (!hostingEnvironment.IsDevelopment()) - { - var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); - context.Services - .AddDataProtection() - .PersistKeysToStackExchangeRedis(redis, "ApiGatewayAdmin-Protection-Keys"); - } - - Configure(options => - { - options.AddProfile(validate: true); - }); - } - - public override void OnApplicationInitialization(ApplicationInitializationContext context) - { - var app = context.GetApplicationBuilder(); - var configuration = context.GetConfiguration(); - // http调用链 - app.UseCorrelationId(); - // 虚拟文件系统 - app.UseStaticFiles(); - //路由 - app.UseRouting(); - // 认证 - app.UseAuthentication(); - // 多租户 - // app.UseMultiTenancy(); - // 本地化 - app.UseAbpRequestLocalization(); - // 认证 - app.UseAuthorization(); - // Swagger - app.UseSwagger(); - // Swagger可视化界面 - app.UseSwaggerUI(options => - { - options.SwaggerEndpoint("/swagger/v1/swagger.json", "Support ApiGateway API"); - }); - // 审计日志 - app.UseAuditing(); - // 路由 - app.UseConfiguredEndpoints(); - - if (configuration.GetSection("ApiGateway:SeedInitScript").Get()) - { - SeedData(context); - } - } - - private void SeedData(ApplicationInitializationContext context) - { - AsyncHelper.RunSync(async () => - { - using var scope = context.ServiceProvider.CreateScope(); - await scope.ServiceProvider.GetRequiredService().SeedAsync(); - }); - } - } -} +using LINGYUN.Abp.AspNetCore.HttpOverrides; +using LINGYUN.Abp.AuditLogging.Elasticsearch; +using LINGYUN.Abp.EventBus.CAP; +using LINGYUN.Abp.MultiTenancy.DbFinder; +using LINGYUN.ApiGateway.EntityFrameworkCore; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Volo.Abp; +using Volo.Abp.AspNetCore.Serilog; +using Volo.Abp.Autofac; +using Volo.Abp.Caching.StackExchangeRedis; +using Volo.Abp.EntityFrameworkCore.MySQL; +using Volo.Abp.Modularity; +using Volo.Abp.PermissionManagement.EntityFrameworkCore; +using Volo.Abp.SettingManagement.EntityFrameworkCore; +using Volo.Abp.TenantManagement.EntityFrameworkCore; + +namespace LINGYUN.ApiGateway +{ + [DependsOn( + typeof(AbpAspNetCoreSerilogModule), + typeof(AbpAuditLoggingElasticsearchModule), + typeof(ApiGatewayApplicationModule), + typeof(ApiGatewayEntityFrameworkCoreModule), + typeof(ApiGatewayHttpApiModule), + typeof(AbpEntityFrameworkCoreMySQLModule), + typeof(AbpTenantManagementEntityFrameworkCoreModule), + typeof(AbpSettingManagementEntityFrameworkCoreModule), + typeof(AbpPermissionManagementEntityFrameworkCoreModule), + typeof(AbpCAPEventBusModule), + typeof(AbpDbFinderMultiTenancyModule), + typeof(AbpCachingStackExchangeRedisModule), + typeof(AbpAspNetCoreHttpOverridesModule), + typeof(AbpAutofacModule) + )] + public partial class ApiGatewayHttpApiHostModule : AbpModule + { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + + PreConfigureCAP(configuration); + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + var hostingEnvironment = context.Services.GetHostingEnvironment(); + var configuration = hostingEnvironment.BuildConfiguration(); + + ConfigureDbContext(); + ConfigureAutoMapper(); + ConfigureJsonSerializer(); + ConfigureVirtualFileSystem(); + ConfigureCaching(configuration); + ConfigureMultiTenancy(configuration); + ConfigureAuditing(configuration); + ConfigureSwagger(context.Services); + ConfigureLocalization(); + ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment()); + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + var app = context.GetApplicationBuilder(); + // http调用链 + app.UseCorrelationId(); + // 虚拟文件系统 + app.UseStaticFiles(); + //路由 + app.UseRouting(); + // 认证 + app.UseAuthentication(); + // 多租户 + // app.UseMultiTenancy(); + // 本地化 + app.UseAbpRequestLocalization(); + // 认证 + app.UseAuthorization(); + // Swagger + app.UseSwagger(); + // Swagger可视化界面 + app.UseSwaggerUI(options => + { + options.SwaggerEndpoint("/swagger/v1/swagger.json", "Support ApiGateway API"); + }); + // 审计日志 + app.UseAuditing(); + app.UseAbpSerilogEnrichers(); + // 路由 + app.UseConfiguredEndpoints(); + + SeedData(context); + } + } +} diff --git a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/LINGYUN.ApiGateway.HttpApi.Host.csproj b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/LINGYUN.ApiGateway.HttpApi.Host.csproj index 421e02baa..3deb4b7ac 100644 --- a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/LINGYUN.ApiGateway.HttpApi.Host.csproj +++ b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/LINGYUN.ApiGateway.HttpApi.Host.csproj @@ -1,4 +1,4 @@ - + net5.0 @@ -21,16 +21,18 @@ + + + - @@ -40,6 +42,7 @@ + diff --git a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/appsettings.Development.json b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/appsettings.Development.json new file mode 100644 index 000000000..c9bf7bbde --- /dev/null +++ b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/appsettings.Development.json @@ -0,0 +1,72 @@ +{ + "App": { + "TrackingEntitiesChanged": true, + "SelfUrl": "http://localhost:30001/" + }, + "ConnectionStrings": { + "Default": "Server=localhost;Database=ApiGateway;User Id=root;Password=123456", + "ApiGateway": "Server=localhost;Database=ApiGateway;User Id=root;Password=123456", + "AbpTenantManagement": "Server=localhost;Database=Platform;User Id=root;Password=123456", + "AbpSettingManagement": "Server=localhost;Database=Platform;User Id=root;Password=123456", + "AbpPermissionManagement": "Server=localhost;Database=Platform;User Id=root;Password=123456" + }, + "Redis": { + "Configuration": "localhost,defaultDatabase=10", + "InstanceName": "LINGYUN.Abp.Application" + }, + "CAP": { + "EventBus": { + "DefaultGroupName": "ApiGateway-Admin", + "Version": "v1", + "FailedRetryInterval": 300, + "FailedRetryCount": 10 + }, + "MySql": { + "TableNamePrefix": "apa", + "ConnectionString": "Server=localhost;Database=ApiGateway;User Id=root;Password=123456" + }, + "RabbitMQ": { + "HostName": "localhost", + "Port": 5672, + "UserName": "guest", + "Password": "guest", + "ExchangeName": "LINGYUN.ApiGateway", + "VirtualHost": "/" + } + }, + "AuthServer": { + "Authority": "http://localhost:44385/", + "ApiName": "lingyun-abp-application" + }, + "Elasticsearch": { + "NodeUris": "http://localhost:9200" + }, + "Serilog": { + "MinimumLevel": { + "Default": "Debug", + "Override": { + "System": "Warning", + "Microsoft": "Warning", + "DotNetCore": "Debug" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "restrictedToMinimumLevel": "Debug", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "Elasticsearch", + "Args": { + "nodeUris": "http://localhost:9200", + "indexFormat": "lingyun.abp.logging-{0:yyyy.MM.dd}", + "autoRegisterTemplate": true, + "autoRegisterTemplateVersion": "ESv7" + } + } + ] + } +} diff --git a/aspnet-core/configuration/localization/LINGYUN.Abp.LocalizationManagement.HttpApi.Host/appsettings.Development.json b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/appsettings.json similarity index 59% rename from aspnet-core/configuration/localization/LINGYUN.Abp.LocalizationManagement.HttpApi.Host/appsettings.Development.json rename to aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/appsettings.json index c24ab87b6..dfae17b8f 100644 --- a/aspnet-core/configuration/localization/LINGYUN.Abp.LocalizationManagement.HttpApi.Host/appsettings.Development.json +++ b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/appsettings.json @@ -1,91 +1,72 @@ -{ - "ConnectionStrings": { - "Default": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpLocalizationManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpTenantManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpSettingManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpPermissionManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456" - }, - "CAP": { - "EventBus": { - "DefaultGroupName": "Platform", - "Version": "v1", - "FailedRetryInterval": 300, - "FailedRetryCount": 10 - }, - "RabbitMQ": { - "HostName": "Your RabbitMQ server connection address", - "Port": 5672, - "UserName": "Your RabbitMQ server connection user", - "Password": "Your RabbitMQ server connection user password", - "ExchangeName": "The name of your RabbitMQ server switch", - "VirtualHost": "Name of your RabbitMQ server VirtualHost" - } - }, - "Redis": { - "Configuration": "127.0.0.1,defaultDatabase=11", - "InstanceName": "LINGYUN.Abp.Application" - }, - "AuthServer": { - "Authority": "http://localhost:44385/", - "ApiName": "lingyun-abp-application" - }, - "Serilog": { - "MinimumLevel": { - "Default": "Debug", - "Override": { - "Microsoft.EntityFrameworkCore": "Debug", - "System": "Warning", - "Microsoft": "Warning" - } - }, - "Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId" ], - "WriteTo": [ - { - "Name": "File", - "Args": { - "path": "Logs/Debug-.log", - "restrictedToMinimumLevel": "Debug", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Info-.log", - "restrictedToMinimumLevel": "Information", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Warn-.log", - "restrictedToMinimumLevel": "Warning", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Error-.log", - "restrictedToMinimumLevel": "Error", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Fatal-.log", - "restrictedToMinimumLevel": "Fatal", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - } - ] - } -} +{ + "StringEncryption": { + "DefaultPassPhrase": "s46c5q55nxpeS8Ra", + "InitVectorBytes": "s83ng0abvd02js84", + "DefaultSalt": "sf&5)s3#" + }, + "Serilog": { + "MinimumLevel": { + "Default": "Debug", + "Override": { + "System": "Warning", + "Microsoft": "Warning", + "DotNetCore": "Debug" + } + }, + "Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId", "WithEnvironmentName", "WithMachineName" ], + "WriteTo": [ + { + "Name": "Console", + "Args": { + "restrictedToMinimumLevel": "Debug", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Debug-.log", + "restrictedToMinimumLevel": "Debug", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Info-.log", + "restrictedToMinimumLevel": "Information", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Warn-.log", + "restrictedToMinimumLevel": "Warning", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Error-.log", + "restrictedToMinimumLevel": "Error", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Fatal-.log", + "restrictedToMinimumLevel": "Fatal", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + } + ] + } +} diff --git a/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/AbpIdentityServerAdminHttpApiHostModule.Configure.cs b/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/AbpIdentityServerAdminHttpApiHostModule.Configure.cs new file mode 100644 index 000000000..b306de767 --- /dev/null +++ b/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/AbpIdentityServerAdminHttpApiHostModule.Configure.cs @@ -0,0 +1,247 @@ +using DotNetCore.CAP; +using LINGYUN.Abp.ExceptionHandling; +using LINGYUN.Abp.ExceptionHandling.Emailing; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.DataProtection; +using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.Caching.StackExchangeRedis; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.OpenApi.Models; +using StackExchange.Redis; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.Encodings.Web; +using System.Text.Unicode; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Auditing; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Caching; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Identity.Localization; +using Volo.Abp.Json.SystemTextJson; +using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; +using Volo.Abp.PermissionManagement; +using Volo.Abp.VirtualFileSystem; + +namespace LINGYUN.Abp.IdentityServer4 +{ + public partial class AbpIdentityServerAdminHttpApiHostModule + { + private void PreConfigureCAP(IConfiguration configuration) + { + PreConfigure(options => + { + options + .UseMySql(configuration.GetConnectionString("Default")) + .UseRabbitMQ(rabbitMQOptions => + { + configuration.GetSection("CAP:RabbitMQ").Bind(rabbitMQOptions); + }) + .UseDashboard(); + }); + } + + private void PreConfigureIdentity() + { + PreConfigure(builder => + { + builder.AddDefaultTokenProviders(); + }); + } + + private void ConfigureDbContext() + { + // 配置Ef + Configure(options => + { + options.UseMySQL(); + }); + } + + private void ConfigureJsonSerializer() + { + // 中文序列化的编码问题 + Configure(options => + { + options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); + }); + } + + private void ConfigurePermissionManagement() + { + Configure(options => + { + // Rename IdentityServer.Client.ManagePermissions + // See https://github.com/abpframework/abp/blob/dev/modules/identityserver/src/Volo.Abp.PermissionManagement.Domain.IdentityServer/Volo/Abp/PermissionManagement/IdentityServer/AbpPermissionManagementDomainIdentityServerModule.cs + options.ProviderPolicies[ClientPermissionValueProvider.ProviderName] = + LINGYUN.Abp.IdentityServer.AbpIdentityServerPermissions.Clients.ManagePermissions; + }); + } + + private void ConfigreExceptionHandling() + { + // 自定义需要处理的异常 + Configure(options => + { + // 加入需要处理的异常类型 + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + }); + // 自定义需要发送邮件通知的异常类型 + Configure(options => + { + // 是否发送堆栈信息 + options.SendStackTrace = true; + }); + } + + private void ConfigureAuditing(IConfiguration configuration) + { + Configure(options => + { + options.ApplicationName = "Identity-Server-Admin"; + // 是否启用实体变更记录 + var entitiesChangedConfig = configuration.GetSection("App:TrackingEntitiesChanged"); + if (entitiesChangedConfig.Exists() && entitiesChangedConfig.Get()) + { + options + .EntityHistorySelectors + .AddAllEntities(); + } + }); + } + + private void ConfigureCaching(IConfiguration configuration) + { + Configure(options => + { + // 最好统一命名,不然某个缓存变动其他应用服务有例外发生 + options.KeyPrefix = "LINGYUN.Abp.Application"; + // 滑动过期30天 + options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30); + // 绝对过期60天 + options.GlobalCacheEntryOptions.AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(60); + }); + + Configure(options => + { + options.AutoEventSelectors.AddNamespace("Volo.Abp.Identity"); + options.AutoEventSelectors.AddNamespace("Volo.Abp.IdentityServer"); + }); + + Configure(options => + { + var redisConfig = ConfigurationOptions.Parse(options.Configuration); + options.ConfigurationOptions = redisConfig; + options.InstanceName = configuration["Redis:InstanceName"]; + }); + } + + private void ConfigureVirtualFileSystem() + { + Configure(options => + { + options.FileSets.AddEmbedded("LINGYUN.Abp.IdentityServer4"); + }); + } + + private void ConfigureMultiTenancy(IConfiguration configuration) + { + // 多租户 + Configure(options => + { + options.IsEnabled = true; + }); + + var tenantResolveCfg = configuration.GetSection("App:Domains"); + if (tenantResolveCfg.Exists()) + { + Configure(options => + { + var domains = tenantResolveCfg.Get(); + foreach (var domain in domains) + { + options.AddDomainTenantResolver(domain); + } + }); + } + } + + private void ConfigureSwagger(IServiceCollection services) + { + // Swagger + services.AddSwaggerGen( + options => + { + options.SwaggerDoc("v1", new OpenApiInfo { Title = "IdentityServer4 API", Version = "v1" }); + options.DocInclusionPredicate((docName, description) => true); + options.CustomSchemaIds(type => type.FullName); + options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme + { + Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"", + Name = "Authorization", + In = ParameterLocation.Header, + Scheme = "bearer", + Type = SecuritySchemeType.Http, + BearerFormat = "JWT" + }); + options.AddSecurityRequirement(new OpenApiSecurityRequirement + { + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } + }, + new string[] { } + } + }); + }); + } + + private void ConfigureLocalization() + { + // 支持本地化语言类型 + Configure(options => + { + options.Languages.Add(new LanguageInfo("en", "en", "English")); + options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); + + options.Resources + .Get() + .AddVirtualJson("/LINGYUN/Abp/IdentityServer4/Localization"); + + options.Resources.AddDynamic(typeof(IdentityResource)); + }); + } + + private void ConfigureSecurity(IServiceCollection services, IConfiguration configuration, bool isDevelopment = false) + { + services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(options => + { + options.Authority = configuration["AuthServer:Authority"]; + options.RequireHttpsMetadata = false; + options.Audience = configuration["AuthServer:ApiName"]; + }); + + if (!isDevelopment) + { + var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); + services + .AddDataProtection() + .PersistKeysToStackExchangeRedis(redis, "IDS-Admin-Protection-Keys"); + } + } + } +} diff --git a/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/AbpIdentityServerAdminHttpApiHostModule.Seeder.cs b/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/AbpIdentityServerAdminHttpApiHostModule.Seeder.cs new file mode 100644 index 000000000..a4e456e83 --- /dev/null +++ b/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/AbpIdentityServerAdminHttpApiHostModule.Seeder.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.IdentityServer4 +{ + public partial class AbpIdentityServerAdminHttpApiHostModule + { + } +} diff --git a/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/AbpIdentityServerAdminHttpApiHostModule.cs b/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/AbpIdentityServerAdminHttpApiHostModule.cs index 5ffbd2140..8cf3843b3 100644 --- a/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/AbpIdentityServerAdminHttpApiHostModule.cs +++ b/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/AbpIdentityServerAdminHttpApiHostModule.cs @@ -1,311 +1,112 @@ -using DotNetCore.CAP; -using LINGYUN.Abp.AspNetCore.HttpOverrides; -using LINGYUN.Abp.EventBus.CAP; -using LINGYUN.Abp.ExceptionHandling; -using LINGYUN.Abp.ExceptionHandling.Emailing; -using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore; -using LINGYUN.Abp.MultiTenancy.DbFinder; -using LINGYUN.Abp.Sms.Aliyun; -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.DataProtection; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Identity; -using Microsoft.Extensions.Caching.StackExchangeRedis; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.OpenApi.Models; -using StackExchange.Redis; -using System; -using System.Text; -using System.Text.Encodings.Web; -using System.Text.Unicode; -using Volo.Abp; -using Volo.Abp.AspNetCore.Authentication.JwtBearer; -using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy; -using Volo.Abp.AspNetCore.Security.Claims; -using Volo.Abp.Auditing; -using Volo.Abp.AuditLogging.EntityFrameworkCore; -using Volo.Abp.Authorization.Permissions; -using Volo.Abp.Autofac; -using Volo.Abp.Caching; -using Volo.Abp.Caching.StackExchangeRedis; -using Volo.Abp.Domain.Entities.Events.Distributed; -using Volo.Abp.EntityFrameworkCore; -using Volo.Abp.EntityFrameworkCore.MySQL; -using Volo.Abp.Identity.Localization; -using Volo.Abp.Json; -using Volo.Abp.Json.SystemTextJson; -using Volo.Abp.Localization; -using Volo.Abp.Modularity; -using Volo.Abp.MultiTenancy; -using Volo.Abp.PermissionManagement; -using Volo.Abp.PermissionManagement.EntityFrameworkCore; -using Volo.Abp.Security.Claims; -using Volo.Abp.Security.Encryption; -using Volo.Abp.SettingManagement.EntityFrameworkCore; -using Volo.Abp.TenantManagement.EntityFrameworkCore; -using Volo.Abp.VirtualFileSystem; - -namespace LINGYUN.Abp.IdentityServer4 -{ - [DependsOn( - typeof(AbpAspNetCoreMvcUiMultiTenancyModule), - typeof(LINGYUN.Abp.Account.AbpAccountApplicationModule), - typeof(LINGYUN.Abp.Account.AbpAccountHttpApiModule), - typeof(LINGYUN.Abp.Identity.AbpIdentityApplicationModule), - typeof(LINGYUN.Abp.Identity.AbpIdentityHttpApiModule), - typeof(LINGYUN.Abp.IdentityServer.AbpIdentityServerApplicationModule), - typeof(LINGYUN.Abp.IdentityServer.AbpIdentityServerHttpApiModule), - typeof(LINGYUN.Abp.Identity.EntityFrameworkCore.AbpIdentityEntityFrameworkCoreModule), - typeof(LINGYUN.Abp.IdentityServer.EntityFrameworkCore.AbpIdentityServerEntityFrameworkCoreModule), - typeof(AbpEntityFrameworkCoreMySQLModule), - typeof(AbpAuditLoggingEntityFrameworkCoreModule), - typeof(AbpTenantManagementEntityFrameworkCoreModule), - typeof(AbpSettingManagementEntityFrameworkCoreModule), - typeof(AbpPermissionManagementEntityFrameworkCoreModule), - typeof(AbpLocalizationManagementEntityFrameworkCoreModule), - typeof(AbpAspNetCoreAuthenticationJwtBearerModule), - typeof(AbpEmailingExceptionHandlingModule), - typeof(AbpCAPEventBusModule), - typeof(AbpAliyunSmsModule), - typeof(AbpDbFinderMultiTenancyModule), - typeof(AbpCachingStackExchangeRedisModule), - typeof(AbpAspNetCoreHttpOverridesModule), - typeof(AbpAutofacModule) - )] - public class AbpIdentityServerAdminHttpApiHostModule : AbpModule - { - public override void PreConfigureServices(ServiceConfigurationContext context) - { - var configuration = context.Services.GetConfiguration(); - - PreConfigure(options => - { - options - .UseMySql(configuration.GetConnectionString("Default")) - .UseRabbitMQ(rabbitMQOptions => - { - configuration.GetSection("CAP:RabbitMQ").Bind(rabbitMQOptions); - }) - .UseDashboard(); - }); - - PreConfigure(builder => - { - builder.AddDefaultTokenProviders(); - }); - } - - public override void ConfigureServices(ServiceConfigurationContext context) - { - var hostingEnvironment = context.Services.GetHostingEnvironment(); - var configuration = hostingEnvironment.BuildConfiguration(); - - // 配置Ef - Configure(options => - { - options.UseMySQL(); - }); - - // 中文序列化的编码问题 - Configure(options => - { - options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); - }); - - // 加解密 - Configure(options => - { - var encryptionConfiguration = configuration.GetSection("Encryption"); - if (encryptionConfiguration.Exists()) - { - options.DefaultPassPhrase = encryptionConfiguration["PassPhrase"] ?? options.DefaultPassPhrase; - options.DefaultSalt = encryptionConfiguration.GetSection("Salt").Exists() - ? Encoding.ASCII.GetBytes(encryptionConfiguration["Salt"]) - : options.DefaultSalt; - options.InitVectorBytes = encryptionConfiguration.GetSection("InitVector").Exists() - ? Encoding.ASCII.GetBytes(encryptionConfiguration["InitVector"]) - : options.InitVectorBytes; - } - }); - - Configure(options => - { - // Rename IdentityServer.Client.ManagePermissions - // See https://github.com/abpframework/abp/blob/dev/modules/identityserver/src/Volo.Abp.PermissionManagement.Domain.IdentityServer/Volo/Abp/PermissionManagement/IdentityServer/AbpPermissionManagementDomainIdentityServerModule.cs - options.ProviderPolicies[ClientPermissionValueProvider.ProviderName] = - LINGYUN.Abp.IdentityServer.AbpIdentityServerPermissions.Clients.ManagePermissions; - }); - - // 自定义需要处理的异常 - Configure(options => - { - // 加入需要处理的异常类型 - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - }); - // 自定义需要发送邮件通知的异常类型 - Configure(options => - { - // 是否发送堆栈信息 - options.SendStackTrace = true; - }); - - Configure(options => - { - options.ApplicationName = "Identity-Server-Admin"; - // 是否启用实体变更记录 - var entitiesChangedConfig = configuration.GetSection("App:TrackingEntitiesChanged"); - if (entitiesChangedConfig.Exists() && entitiesChangedConfig.Get()) - { - options - .EntityHistorySelectors - .AddAllEntities(); - } - }); - - Configure(options => - { - // 最好统一命名,不然某个缓存变动其他应用服务有例外发生 - options.KeyPrefix = "LINGYUN.Abp.Application"; - // 滑动过期30天 - options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30); - // 绝对过期60天 - options.GlobalCacheEntryOptions.AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(60); - }); - - Configure(options => - { - options.AutoEventSelectors.AddNamespace("Volo.Abp.Identity"); - options.AutoEventSelectors.AddNamespace("Volo.Abp.IdentityServer"); - }); - - Configure(options => - { - var redisConfig = ConfigurationOptions.Parse(options.Configuration); - options.ConfigurationOptions = redisConfig; - options.InstanceName = configuration["Redis:InstanceName"]; - }); - - Configure(options => - { - options.FileSets.AddEmbedded("LINGYUN.Abp.IdentityServer4"); - }); - - // 多租户 - Configure(options => - { - options.IsEnabled = true; - }); - - var tenantResolveCfg = configuration.GetSection("App:Domains"); - if (tenantResolveCfg.Exists()) - { - Configure(options => - { - var domains = tenantResolveCfg.Get(); - foreach (var domain in domains) - { - options.AddDomainTenantResolver(domain); - } - }); - } - - // Swagger - context.Services.AddSwaggerGen( - options => - { - options.SwaggerDoc("v1", new OpenApiInfo { Title = "IdentityServer4 API", Version = "v1" }); - options.DocInclusionPredicate((docName, description) => true); - options.CustomSchemaIds(type => type.FullName); - options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme - { - Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"", - Name = "Authorization", - In = ParameterLocation.Header, - Scheme = "bearer", - Type = SecuritySchemeType.Http, - BearerFormat = "JWT" - }); - options.AddSecurityRequirement(new OpenApiSecurityRequirement - { - { - new OpenApiSecurityScheme - { - Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } - }, - new string[] { } - } - }); - }); - - // 支持本地化语言类型 - Configure(options => - { - options.Languages.Add(new LanguageInfo("en", "en", "English")); - options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); - - options.Resources - .Get() - .AddVirtualJson("/LINGYUN/Abp/IdentityServer4/Localization"); - - options.Resources.AddDynamic(typeof(IdentityResource)); - }); - - context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) - .AddJwtBearer(options => - { - options.Authority = configuration["AuthServer:Authority"]; - options.RequireHttpsMetadata = false; - options.Audience = configuration["AuthServer:ApiName"]; - }); - - if (!hostingEnvironment.IsDevelopment()) - { - var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); - context.Services - .AddDataProtection() - .PersistKeysToStackExchangeRedis(redis, "BackendAdmin-Protection-Keys"); - } - } - - public override void OnApplicationInitialization(ApplicationInitializationContext context) - { - var app = context.GetApplicationBuilder(); - // http调用链 - app.UseCorrelationId(); - // 虚拟文件系统 - app.UseStaticFiles(); - // 本地化 - app.UseAbpRequestLocalization(); - //路由 - app.UseRouting(); - // 认证 - app.UseAuthentication(); - app.UseAbpClaimsMap(); - // jwt - app.UseJwtTokenMiddleware(); - // 多租户 - app.UseMultiTenancy(); - // Swagger - app.UseSwagger(); - // Swagger可视化界面 - app.UseSwaggerUI(options => - { - options.SwaggerEndpoint("/swagger/v1/swagger.json", "Support IdentityServer4 API"); - }); - // 审计日志 - app.UseAuditing(); - // 路由 - app.UseConfiguredEndpoints(); - } - } +using LINGYUN.Abp.AspNetCore.HttpOverrides; +using LINGYUN.Abp.AuditLogging.Elasticsearch; +using LINGYUN.Abp.EventBus.CAP; +using LINGYUN.Abp.ExceptionHandling.Emailing; +using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore; +using LINGYUN.Abp.MultiTenancy.DbFinder; +using LINGYUN.Abp.Sms.Aliyun; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Volo.Abp; +using Volo.Abp.AspNetCore.Authentication.JwtBearer; +using Volo.Abp.AspNetCore.MultiTenancy; +using Volo.Abp.AspNetCore.Serilog; +using Volo.Abp.Autofac; +using Volo.Abp.Caching.StackExchangeRedis; +using Volo.Abp.EntityFrameworkCore.MySQL; +using Volo.Abp.Modularity; +using Volo.Abp.PermissionManagement.EntityFrameworkCore; +using Volo.Abp.SettingManagement.EntityFrameworkCore; +using Volo.Abp.TenantManagement.EntityFrameworkCore; + +namespace LINGYUN.Abp.IdentityServer4 +{ + [DependsOn( + typeof(AbpAspNetCoreSerilogModule), + typeof(AbpAuditLoggingElasticsearchModule), + typeof(AbpAspNetCoreMultiTenancyModule), + typeof(LINGYUN.Abp.Account.AbpAccountApplicationModule), + typeof(LINGYUN.Abp.Account.AbpAccountHttpApiModule), + typeof(LINGYUN.Abp.Identity.AbpIdentityApplicationModule), + typeof(LINGYUN.Abp.Identity.AbpIdentityHttpApiModule), + typeof(LINGYUN.Abp.IdentityServer.AbpIdentityServerApplicationModule), + typeof(LINGYUN.Abp.IdentityServer.AbpIdentityServerHttpApiModule), + typeof(LINGYUN.Abp.Identity.EntityFrameworkCore.AbpIdentityEntityFrameworkCoreModule), + typeof(LINGYUN.Abp.IdentityServer.EntityFrameworkCore.AbpIdentityServerEntityFrameworkCoreModule), + typeof(AbpEntityFrameworkCoreMySQLModule), + typeof(AbpTenantManagementEntityFrameworkCoreModule), + typeof(AbpSettingManagementEntityFrameworkCoreModule), + typeof(AbpPermissionManagementEntityFrameworkCoreModule), + typeof(AbpLocalizationManagementEntityFrameworkCoreModule), + typeof(AbpAspNetCoreAuthenticationJwtBearerModule), + typeof(AbpEmailingExceptionHandlingModule), + typeof(AbpCAPEventBusModule), + typeof(AbpAliyunSmsModule), + typeof(AbpDbFinderMultiTenancyModule), + typeof(AbpCachingStackExchangeRedisModule), + typeof(AbpAspNetCoreHttpOverridesModule), + typeof(AbpAutofacModule) + )] + public partial class AbpIdentityServerAdminHttpApiHostModule : AbpModule + { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + + PreConfigureCAP(configuration); + PreConfigureIdentity(); + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + var hostingEnvironment = context.Services.GetHostingEnvironment(); + var configuration = hostingEnvironment.BuildConfiguration(); + + ConfigureDbContext(); + ConfigureJsonSerializer(); + ConfigurePermissionManagement(); + ConfigreExceptionHandling(); + ConfigureAuditing(configuration); + ConfigureCaching(configuration); + ConfigureVirtualFileSystem(); + ConfigureMultiTenancy(configuration); + ConfigureSwagger(context.Services); + ConfigureLocalization(); + ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment()); + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + var app = context.GetApplicationBuilder(); + // http调用链 + app.UseCorrelationId(); + // 虚拟文件系统 + app.UseStaticFiles(); + // 本地化 + app.UseAbpRequestLocalization(); + //路由 + app.UseRouting(); + // 认证 + app.UseAuthentication(); + app.UseAbpClaimsMap(); + // jwt + app.UseJwtTokenMiddleware(); + // 多租户 + app.UseMultiTenancy(); + // Swagger + app.UseSwagger(); + // Swagger可视化界面 + app.UseSwaggerUI(options => + { + options.SwaggerEndpoint("/swagger/v1/swagger.json", "Support IdentityServer4 API"); + }); + // 审计日志 + app.UseAuditing(); + app.UseAbpSerilogEnrichers(); + // 路由 + app.UseConfiguredEndpoints(); + } + } } \ No newline at end of file diff --git a/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/LINGYUN.Abp.IdentityServer4.HttpApi.Host.csproj b/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/LINGYUN.Abp.IdentityServer4.HttpApi.Host.csproj index a5d9bea2a..d6c6e6dbb 100644 --- a/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/LINGYUN.Abp.IdentityServer4.HttpApi.Host.csproj +++ b/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/LINGYUN.Abp.IdentityServer4.HttpApi.Host.csproj @@ -29,15 +29,18 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - + + + + + + + + + + - + @@ -45,7 +48,6 @@ - @@ -54,6 +56,7 @@ + diff --git a/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/appsettings.Development.json b/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/appsettings.Development.json new file mode 100644 index 000000000..bcff4003a --- /dev/null +++ b/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/appsettings.Development.json @@ -0,0 +1,74 @@ +{ + "App": { + "TrackingEntitiesChanged": true + }, + "ConnectionStrings": { + "Default": "Server=localhost;Database=IdentityServer;User Id=root;Password=123456", + "AbpIdentity": "Server=localhost;Database=IdentityServer;User Id=root;Password=123456", + "AbpIdentityServer": "Server=localhost;Database=IdentityServer;User Id=root;Password=123456", + "AbpTenantManagement": "Server=localhost;Database=Platform;User Id=root;Password=123456", + "AbpSettingManagement": "Server=localhost;Database=Platform;User Id=root;Password=123456", + "AbpFeatureManagement": "Server=localhost;Database=Platform;User Id=root;Password=123456", + "AbpPermissionManagement": "Server=localhost;Database=Platform;User Id=root;Password=123456", + "AbpLocalizationManagement": "Server=localhost;Database=Platform;User Id=root;Password=123456" + }, + "CAP": { + "EventBus": { + "DefaultGroupName": "IdentityServer4Admin", + "Version": "v1", + "FailedRetryInterval": 300, + "FailedRetryCount": 10 + }, + "MySql": { + "TableNamePrefix": "ida", + "ConnectionString": "Server=localhost;Database=IdentityServer;User Id=root;Password=123456" + }, + "RabbitMQ": { + "HostName": "localhost", + "Port": 5672, + "UserName": "guest", + "Password": "guest", + "ExchangeName": "LINGYUN.Abp.Application", + "VirtualHost": "/" + } + }, + "Redis": { + "Configuration": "localhost,defaultDatabase=10", + "InstanceName": "LINGYUN.Abp.Application" + }, + "AuthServer": { + "Authority": "http://localhost:44385/", + "ApiName": "lingyun-abp-application" + }, + "Elasticsearch": { + "NodeUris": "http://localhost:9200" + }, + "Serilog": { + "MinimumLevel": { + "Default": "Debug", + "Override": { + "System": "Warning", + "Microsoft": "Warning", + "DotNetCore": "Debug" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "restrictedToMinimumLevel": "Debug", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "Elasticsearch", + "Args": { + "nodeUris": "http://localhost:9200", + "indexFormat": "lingyun.abp.logging-{0:yyyy.MM.dd}", + "autoRegisterTemplate": true, + "autoRegisterTemplateVersion": "ESv7" + } + } + ] + } +} diff --git a/aspnet-core/configuration/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/appsettings.Development.json b/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/appsettings.json similarity index 55% rename from aspnet-core/configuration/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/appsettings.Development.json rename to aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/appsettings.json index 3d49240ca..ffd956276 100644 --- a/aspnet-core/configuration/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/appsettings.Development.json +++ b/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/appsettings.json @@ -1,97 +1,72 @@ -{ - "App": { - "TrackingEntitiesChanged": true - }, - "ConnectionStrings": { - "Default": "Server=127.0.0.1;Database=IdentityServer;User Id=root;Password=123456", - "AbpIdentity": "Server=127.0.0.1;Database=IdentityServer;User Id=root;Password=123456", - "AbpIdentityServer": "Server=127.0.0.1;Database=IdentityServer;User Id=root;Password=123456", - "AbpTenantManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpSettingManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpFeatureManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpPermissionManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", - "AbpLocalizationManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456" - }, - "CAP": { - "EventBus": { - "DefaultGroupName": "IdentityServer4Admin", - "Version": "v1", - "FailedRetryInterval": 300, - "FailedRetryCount": 10 - }, - "RabbitMQ": { - "HostName": "127.0.0.1", - "Port": 5672, - "UserName": "admin", - "Password": "123456", - "ExchangeName": "LINGYUN.AbpApplication", - "VirtualHost": "multi.service.test" - } - }, - "Redis": { - "Configuration": "127.0.0.1,defaultDatabase=10", - "InstanceName": "LINGYUN.AbpApplication" - }, - "AuthServer": { - "Authority": "http://localhost:44385/", - "ApiName": "lingyun-abp-application" - }, - "Serilog": { - "MinimumLevel": { - "Default": "Debug", - "Override": { - "Microsoft.EntityFrameworkCore": "Debug", - "System": "Warning", - "Microsoft": "Warning" - } - }, - "Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId" ], - "WriteTo": [ - { - "Name": "File", - "Args": { - "path": "Logs/Debug-.log", - "restrictedToMinimumLevel": "Debug", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Info-.log", - "restrictedToMinimumLevel": "Information", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Warn-.log", - "restrictedToMinimumLevel": "Warning", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Error-.log", - "restrictedToMinimumLevel": "Error", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "Logs/Fatal-.log", - "restrictedToMinimumLevel": "Fatal", - "rollingInterval": "Day", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - } - ] - } -} +{ + "StringEncryption": { + "DefaultPassPhrase": "s46c5q55nxpeS8Ra", + "InitVectorBytes": "s83ng0abvd02js84", + "DefaultSalt": "sf&5)s3#" + }, + "Serilog": { + "MinimumLevel": { + "Default": "Debug", + "Override": { + "System": "Warning", + "Microsoft": "Warning", + "DotNetCore": "Debug" + } + }, + "Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId", "WithEnvironmentName", "WithMachineName" ], + "WriteTo": [ + { + "Name": "Console", + "Args": { + "restrictedToMinimumLevel": "Debug", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Debug-.log", + "restrictedToMinimumLevel": "Debug", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Info-.log", + "restrictedToMinimumLevel": "Information", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Warn-.log", + "restrictedToMinimumLevel": "Warning", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Error-.log", + "restrictedToMinimumLevel": "Error", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Fatal-.log", + "restrictedToMinimumLevel": "Fatal", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + } + ] + } +} diff --git a/aspnet-core/services/localization/LINGYUN.Abp.LocalizationManagement.HttpApi.Host/AbpLocalizationManagementHttpApiHostModule.Configure.cs b/aspnet-core/services/localization/LINGYUN.Abp.LocalizationManagement.HttpApi.Host/AbpLocalizationManagementHttpApiHostModule.Configure.cs new file mode 100644 index 000000000..edf1f468a --- /dev/null +++ b/aspnet-core/services/localization/LINGYUN.Abp.LocalizationManagement.HttpApi.Host/AbpLocalizationManagementHttpApiHostModule.Configure.cs @@ -0,0 +1,198 @@ +using DotNetCore.CAP; +using LINGYUN.Abp.ExceptionHandling; +using LINGYUN.Abp.ExceptionHandling.Emailing; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.DataProtection; +using Microsoft.Extensions.Caching.StackExchangeRedis; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.OpenApi.Models; +using StackExchange.Redis; +using System; +using System.Text.Encodings.Web; +using System.Text.Unicode; +using Volo.Abp; +using Volo.Abp.Auditing; +using Volo.Abp.Caching; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Json.SystemTextJson; +using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; +using Volo.Abp.VirtualFileSystem; + + +namespace LINGYUN.Abp.LocalizationManagement +{ + public partial class AbpLocalizationManagementHttpApiHostModule + { + private void PreConfigureCAP(IConfiguration configuration) + { + PreConfigure(options => + { + options + .UseMySql(configuration.GetConnectionString("Default")) + .UseRabbitMQ(rabbitMQOptions => + { + configuration.GetSection("CAP:RabbitMQ").Bind(rabbitMQOptions); + }) + .UseDashboard(); + }); + } + + private void ConfigureDbContext() + { + // 配置Ef + Configure(options => + { + options.UseMySQL(); + }); + } + + private void ConfigureJsonSerializer() + { + // 中文序列化的编码问题 + Configure(options => + { + options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); + }); + } + + private void ConfigreExceptionHandling() + { + // 自定义需要处理的异常 + Configure(options => + { + // 加入需要处理的异常类型 + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + }); + // 自定义需要发送邮件通知的异常类型 + Configure(options => + { + // 是否发送堆栈信息 + options.SendStackTrace = true; + }); + } + + private void ConfigureAuditing(IConfiguration configuration) + { + Configure(options => + { + options.ApplicationName = "Localization"; + // 是否启用实体变更记录 + var entitiesChangedConfig = configuration.GetSection("App:TrackingEntitiesChanged"); + if (entitiesChangedConfig.Exists() && entitiesChangedConfig.Get()) + { + options + .EntityHistorySelectors + .AddAllEntities(); + } + }); + } + + private void ConfigureCaching(IConfiguration configuration) + { + Configure(options => + { + // 最好统一命名,不然某个缓存变动其他应用服务有例外发生 + options.KeyPrefix = "LINGYUN.Abp.Application"; + // 滑动过期30天 + options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30); + // 绝对过期60天 + options.GlobalCacheEntryOptions.AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(60); + }); + + Configure(options => + { + var redisConfig = ConfigurationOptions.Parse(options.Configuration); + options.ConfigurationOptions = redisConfig; + options.InstanceName = configuration["Redis:InstanceName"]; + }); + } + + private void ConfigureVirtualFileSystem() + { + Configure(options => + { + options.FileSets.AddEmbedded("LINGYUN.Abp.LocalizationManagement"); + }); + } + + private void ConfigureMultiTenancy(IConfiguration configuration) + { + // 多租户 + Configure(options => + { + options.IsEnabled = false; + }); + } + + private void ConfigureSwagger(IServiceCollection services) + { + // Swagger + services.AddSwaggerGen( + options => + { + options.SwaggerDoc("v1", new OpenApiInfo { Title = "Localization Management API", Version = "v1" }); + options.DocInclusionPredicate((docName, description) => true); + options.CustomSchemaIds(type => type.FullName); + options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme + { + Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"", + Name = "Authorization", + In = ParameterLocation.Header, + Scheme = "bearer", + Type = SecuritySchemeType.Http, + BearerFormat = "JWT" + }); + options.AddSecurityRequirement(new OpenApiSecurityRequirement + { + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } + }, + new string[] { } + } + }); + }); + } + + private void ConfigureLocalization() + { + // 默认支持的本地化语言类型 + Configure(options => + { + options.Languages.Add(new LanguageInfo("en", "en", "English")); + options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); + + options.Resources.AddDynamic(); + }); + } + + private void ConfigureSecurity(IServiceCollection services, IConfiguration configuration, bool isDevelopment = false) + { + services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(options => + { + options.Authority = configuration["AuthServer:Authority"]; + options.RequireHttpsMetadata = false; + options.Audience = configuration["AuthServer:ApiName"]; + }); + + if (!isDevelopment) + { + var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); + services + .AddDataProtection() + .PersistKeysToStackExchangeRedis(redis, "Localization-Protection-Keys"); + } + } + } +} diff --git a/aspnet-core/services/localization/LINGYUN.Abp.LocalizationManagement.HttpApi.Host/AbpLocalizationManagementHttpApiHostModule.Seeder.cs b/aspnet-core/services/localization/LINGYUN.Abp.LocalizationManagement.HttpApi.Host/AbpLocalizationManagementHttpApiHostModule.Seeder.cs new file mode 100644 index 000000000..52d1f6674 --- /dev/null +++ b/aspnet-core/services/localization/LINGYUN.Abp.LocalizationManagement.HttpApi.Host/AbpLocalizationManagementHttpApiHostModule.Seeder.cs @@ -0,0 +1,21 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Volo.Abp; +using Volo.Abp.Data; +using Volo.Abp.Threading; + +namespace LINGYUN.Abp.LocalizationManagement +{ + public partial class AbpLocalizationManagementHttpApiHostModule + { + private void SeedData(ApplicationInitializationContext context) + { + if (context.GetEnvironment().IsDevelopment()) + { + AsyncHelper.RunSync(async () => + await context.ServiceProvider.GetRequiredService() + .SeedAsync()); + } + } + } +} diff --git a/aspnet-core/services/localization/LINGYUN.Abp.LocalizationManagement.HttpApi.Host/AbpLocalizationManagementHttpApiHostModule.cs b/aspnet-core/services/localization/LINGYUN.Abp.LocalizationManagement.HttpApi.Host/AbpLocalizationManagementHttpApiHostModule.cs index bd646b9b1..6402cc0b4 100644 --- a/aspnet-core/services/localization/LINGYUN.Abp.LocalizationManagement.HttpApi.Host/AbpLocalizationManagementHttpApiHostModule.cs +++ b/aspnet-core/services/localization/LINGYUN.Abp.LocalizationManagement.HttpApi.Host/AbpLocalizationManagementHttpApiHostModule.cs @@ -1,265 +1,104 @@ -using DotNetCore.CAP; -using LINGYUN.Abp.AspNetCore.HttpOverrides; -using LINGYUN.Abp.EventBus.CAP; -using LINGYUN.Abp.ExceptionHandling; -using LINGYUN.Abp.ExceptionHandling.Emailing; -using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore; -using LINGYUN.Abp.MultiTenancy.DbFinder; -using Localization.Resources.AbpUi; -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.DataProtection; -using Microsoft.Extensions.Caching.StackExchangeRedis; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.OpenApi.Models; -using StackExchange.Redis; -using System; -using System.Text; -using System.Text.Encodings.Web; -using System.Text.Unicode; -using Volo.Abp; -using Volo.Abp.AspNetCore.Authentication.JwtBearer; -using Volo.Abp.AspNetCore.MultiTenancy; -using Volo.Abp.Autofac; -using Volo.Abp.Caching; -using Volo.Abp.Caching.StackExchangeRedis; -using Volo.Abp.Data; -using Volo.Abp.EntityFrameworkCore; -using Volo.Abp.EntityFrameworkCore.MySQL; -using Volo.Abp.Json; -using Volo.Abp.Json.SystemTextJson; -using Volo.Abp.Localization; -using Volo.Abp.Modularity; -using Volo.Abp.MultiTenancy; -using Volo.Abp.PermissionManagement.EntityFrameworkCore; -using Volo.Abp.Security.Encryption; -using Volo.Abp.SettingManagement.EntityFrameworkCore; -using Volo.Abp.TenantManagement.EntityFrameworkCore; -using Volo.Abp.Threading; -using Volo.Abp.Validation.Localization; - -namespace LINGYUN.Abp.LocalizationManagement -{ - [DependsOn( - typeof(AbpLocalizationManagementApplicationModule), - typeof(AbpLocalizationManagementHttpApiModule), - typeof(AbpLocalizationManagementEntityFrameworkCoreModule), - typeof(AbpAspNetCoreMultiTenancyModule), - typeof(AbpEntityFrameworkCoreMySQLModule), - typeof(AbpTenantManagementEntityFrameworkCoreModule), - typeof(AbpSettingManagementEntityFrameworkCoreModule), - typeof(AbpPermissionManagementEntityFrameworkCoreModule), - typeof(AbpAspNetCoreAuthenticationJwtBearerModule), - typeof(AbpEmailingExceptionHandlingModule), - typeof(AbpCAPEventBusModule), - typeof(AbpDbFinderMultiTenancyModule), - typeof(AbpCachingStackExchangeRedisModule), - typeof(AbpAspNetCoreHttpOverridesModule), - typeof(AbpAutofacModule) - )] - public class AbpLocalizationManagementHttpApiHostModule : AbpModule - { - public override void PreConfigureServices(ServiceConfigurationContext context) - { - var configuration = context.Services.GetConfiguration(); - - PreConfigure(options => - { - options - .UseMySql(configuration.GetConnectionString("Default")) - .UseRabbitMQ(rabbitMQOptions => - { - configuration.GetSection("CAP:RabbitMQ").Bind(rabbitMQOptions); - }) - .UseDashboard(); - }); - } - - public override void ConfigureServices(ServiceConfigurationContext context) - { - var hostingEnvironment = context.Services.GetHostingEnvironment(); - var configuration = context.Services.GetConfiguration(); - - // 配置Ef - Configure(options => - { - options.UseMySQL(); - }); - - // 中文序列化的编码问题 - Configure(options => - { - options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); - }); - - // 加解密 - Configure(options => - { - var encryptionConfiguration = configuration.GetSection("Encryption"); - if (encryptionConfiguration.Exists()) - { - options.DefaultPassPhrase = encryptionConfiguration["PassPhrase"] ?? options.DefaultPassPhrase; - options.DefaultSalt = encryptionConfiguration.GetSection("Salt").Exists() - ? Encoding.ASCII.GetBytes(encryptionConfiguration["Salt"]) - : options.DefaultSalt; - options.InitVectorBytes = encryptionConfiguration.GetSection("InitVector").Exists() - ? Encoding.ASCII.GetBytes(encryptionConfiguration["InitVector"]) - : options.InitVectorBytes; - } - }); - - // 自定义需要处理的异常 - Configure(options => - { - // 加入需要处理的异常类型 - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - }); - // 自定义需要发送邮件通知的异常类型 - Configure(options => - { - // 是否发送堆栈信息 - options.SendStackTrace = true; - // 未指定异常接收者的默认接收邮件 - // 指定自己的邮件地址 - // options.DefaultReceiveEmail = "colin.in@foxmail.com"; - }); - - Configure(options => - { - // 最好统一命名,不然某个缓存变动其他应用服务有例外发生 - options.KeyPrefix = "LINGYUN.Abp.Application"; - // 滑动过期30天 - options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30); - // 绝对过期60天 - options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60); - }); - - Configure(options => - { - var redisConfig = ConfigurationOptions.Parse(options.Configuration); - options.ConfigurationOptions = redisConfig; - options.InstanceName = configuration["Redis:InstanceName"]; - }); - - // 可以禁用多租户 - Configure(options => - { - options.IsEnabled = false; - }); - - // 添加动态本地化组件 - Configure(options => - { - options.Resources.AddDynamic(); - }); - - // Swagger - context.Services.AddSwaggerGen( - options => - { - options.SwaggerDoc("v1", new OpenApiInfo { Title = "Localization Management API", Version = "v1" }); - options.DocInclusionPredicate((docName, description) => true); - options.CustomSchemaIds(type => type.FullName); - options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme - { - Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"", - Name = "Authorization", - In = ParameterLocation.Header, - Scheme = "bearer", - Type = SecuritySchemeType.Http, - BearerFormat = "JWT" - }); - options.AddSecurityRequirement(new OpenApiSecurityRequirement - { - { - new OpenApiSecurityScheme - { - Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } - }, - new string[] { } - } - }); - }); - - // 默认支持的本地化语言类型 - Configure(options => - { - options.Languages.Add(new LanguageInfo("en", "en", "English")); - options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); - }); - - context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) - .AddJwtBearer(options => - { - options.Authority = configuration["AuthServer:Authority"]; - options.RequireHttpsMetadata = false; - options.Audience = configuration["AuthServer:ApiName"]; - }); - - if (!hostingEnvironment.IsDevelopment()) - { - var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); - context.Services - .AddDataProtection() - .PersistKeysToStackExchangeRedis(redis, "Localization-Management-Protection-Keys"); - } - } - - //public override void OnPostApplicationInitialization(ApplicationInitializationContext context) - //{ - // // 注释代码取消启动时缓存本地化信息 - // var initialize = context.ServiceProvider.GetRequiredService(); - // AsyncHelper.RunSync(async () => await initialize.InitializeAsync()); - //} - - public override void OnApplicationInitialization(ApplicationInitializationContext context) - { - var app = context.GetApplicationBuilder(); - var env = context.GetEnvironment(); - - // http调用链 - app.UseCorrelationId(); - // 虚拟文件系统 - app.UseStaticFiles(); - // 本地化 - app.UseAbpRequestLocalization(); - // 多租户 - // app.UseMultiTenancy(); - //路由 - app.UseRouting(); - // 认证 - app.UseAuthentication(); - // jwt - app.UseJwtTokenMiddleware(); - // 授权 - app.UseAuthorization(); - // Swagger - app.UseSwagger(); - // Swagger可视化界面 - app.UseSwaggerUI(options => - { - options.SwaggerEndpoint("/swagger/v1/swagger.json", "Support Localization Management API"); - }); - // 审计日志 - app.UseAuditing(); - // 路由 - app.UseConfiguredEndpoints(); - - if (env.IsDevelopment()) - { - AsyncHelper.RunSync(async () => - await app.ApplicationServices.GetRequiredService() - .SeedAsync()); - } - } - } -} +using LINGYUN.Abp.AspNetCore.HttpOverrides; +using LINGYUN.Abp.AuditLogging.Elasticsearch; +using LINGYUN.Abp.EventBus.CAP; +using LINGYUN.Abp.ExceptionHandling.Emailing; +using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore; +using LINGYUN.Abp.MultiTenancy.DbFinder; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Volo.Abp; +using Volo.Abp.AspNetCore.Authentication.JwtBearer; +using Volo.Abp.AspNetCore.MultiTenancy; +using Volo.Abp.AspNetCore.Serilog; +using Volo.Abp.Autofac; +using Volo.Abp.Caching.StackExchangeRedis; +using Volo.Abp.EntityFrameworkCore.MySQL; +using Volo.Abp.Modularity; +using Volo.Abp.PermissionManagement.EntityFrameworkCore; +using Volo.Abp.SettingManagement.EntityFrameworkCore; +using Volo.Abp.TenantManagement.EntityFrameworkCore; + +namespace LINGYUN.Abp.LocalizationManagement +{ + [DependsOn( + typeof(AbpAspNetCoreSerilogModule), + typeof(AbpAuditLoggingElasticsearchModule), + typeof(AbpAspNetCoreMultiTenancyModule), + typeof(AbpLocalizationManagementApplicationModule), + typeof(AbpLocalizationManagementHttpApiModule), + typeof(AbpLocalizationManagementEntityFrameworkCoreModule), + typeof(AbpEntityFrameworkCoreMySQLModule), + typeof(AbpTenantManagementEntityFrameworkCoreModule), + typeof(AbpSettingManagementEntityFrameworkCoreModule), + typeof(AbpPermissionManagementEntityFrameworkCoreModule), + typeof(AbpAspNetCoreAuthenticationJwtBearerModule), + typeof(AbpEmailingExceptionHandlingModule), + typeof(AbpCAPEventBusModule), + typeof(AbpDbFinderMultiTenancyModule), + typeof(AbpCachingStackExchangeRedisModule), + typeof(AbpAspNetCoreHttpOverridesModule), + typeof(AbpAutofacModule) + )] + public partial class AbpLocalizationManagementHttpApiHostModule : AbpModule + { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + + PreConfigureCAP(configuration); + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + var hostingEnvironment = context.Services.GetHostingEnvironment(); + var configuration = context.Services.GetConfiguration(); + + ConfigureDbContext(); + ConfigureJsonSerializer(); + ConfigreExceptionHandling(); + ConfigureAuditing(configuration); + ConfigureCaching(configuration); + ConfigureVirtualFileSystem(); + ConfigureMultiTenancy(configuration); + ConfigureLocalization(); + ConfigureSwagger(context.Services); + ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment()); + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + var app = context.GetApplicationBuilder(); + var env = context.GetEnvironment(); + + // http调用链 + app.UseCorrelationId(); + // 虚拟文件系统 + app.UseStaticFiles(); + // 本地化 + app.UseAbpRequestLocalization(); + //路由 + app.UseRouting(); + // 认证 + app.UseAuthentication(); + // jwt + app.UseJwtTokenMiddleware(); + // 授权 + app.UseAuthorization(); + // Swagger + app.UseSwagger(); + // Swagger可视化界面 + app.UseSwaggerUI(options => + { + options.SwaggerEndpoint("/swagger/v1/swagger.json", "Support Localization Management API"); + }); + // 审计日志 + app.UseAuditing(); + app.UseAbpSerilogEnrichers(); + // 路由 + app.UseConfiguredEndpoints(); + + SeedData(context); + } + } +} diff --git a/aspnet-core/services/localization/LINGYUN.Abp.LocalizationManagement.HttpApi.Host/LINGYUN.Abp.LocalizationManagement.HttpApi.Host.csproj b/aspnet-core/services/localization/LINGYUN.Abp.LocalizationManagement.HttpApi.Host/LINGYUN.Abp.LocalizationManagement.HttpApi.Host.csproj index 46bc9e3c1..3a281ef8b 100644 --- a/aspnet-core/services/localization/LINGYUN.Abp.LocalizationManagement.HttpApi.Host/LINGYUN.Abp.LocalizationManagement.HttpApi.Host.csproj +++ b/aspnet-core/services/localization/LINGYUN.Abp.LocalizationManagement.HttpApi.Host/LINGYUN.Abp.LocalizationManagement.HttpApi.Host.csproj @@ -15,12 +15,15 @@ + + + @@ -32,6 +35,7 @@ + diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/AbpMessageServiceHttpApiHostModule.Configure.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/AbpMessageServiceHttpApiHostModule.Configure.cs new file mode 100644 index 000000000..2a7e245b3 --- /dev/null +++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/AbpMessageServiceHttpApiHostModule.Configure.cs @@ -0,0 +1,239 @@ +using DotNetCore.CAP; +using LINGYUN.Abp.ExceptionHandling; +using LINGYUN.Abp.MessageService.Localization; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.Cors; +using Microsoft.AspNetCore.DataProtection; +using Microsoft.Extensions.Caching.StackExchangeRedis; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.OpenApi.Models; +using StackExchange.Redis; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.Encodings.Web; +using System.Text.Unicode; +using Volo.Abp; +using Volo.Abp.AspNetCore.Auditing; +using Volo.Abp.Auditing; +using Volo.Abp.Caching; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Json.SystemTextJson; +using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; +using Volo.Abp.VirtualFileSystem; + +namespace LINGYUN.Abp.MessageService +{ + public partial class AbpMessageServiceHttpApiHostModule + { + private void PreConfigureCAP(IConfiguration configuration) + { + PreConfigure(options => + { + options + .UseMySql(configuration.GetConnectionString("Default")) + .UseRabbitMQ(rabbitMQOptions => + { + configuration.GetSection("CAP:RabbitMQ").Bind(rabbitMQOptions); + }) + .UseDashboard(); + }); + } + + private void ConfigureDbContext() + { + // 配置Ef + Configure(options => + { + options.UseMySQL(); + }); + } + + private void ConfigureJsonSerializer() + { + // 中文序列化的编码问题 + Configure(options => + { + options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); + }); + } + + private void ConfigreExceptionHandling() + { + // 自定义需要处理的异常 + Configure(options => + { + // 加入需要处理的异常类型 + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + }); + } + + private void ConfigureAuditing(IConfiguration configuration) + { + Configure(options => + { + options.IgnoredUrls.AddIfNotContains("/hangfire"); + }); + + Configure(options => + { + options.ApplicationName = "Localization"; + // 是否启用实体变更记录 + var entitiesChangedConfig = configuration.GetSection("App:TrackingEntitiesChanged"); + if (entitiesChangedConfig.Exists() && entitiesChangedConfig.Get()) + { + options + .EntityHistorySelectors + .AddAllEntities(); + } + }); + } + + private void ConfigureCaching(IConfiguration configuration) + { + Configure(options => + { + // 最好统一命名,不然某个缓存变动其他应用服务有例外发生 + options.KeyPrefix = "LINGYUN.Abp.Application"; + // 滑动过期30天 + options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30); + // 绝对过期60天 + options.GlobalCacheEntryOptions.AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(60); + }); + + Configure(options => + { + var redisConfig = ConfigurationOptions.Parse(options.Configuration); + options.ConfigurationOptions = redisConfig; + options.InstanceName = configuration["Redis:InstanceName"]; + }); + } + + private void ConfigureVirtualFileSystem() + { + Configure(options => + { + options.FileSets.AddEmbedded("LINGYUN.Abp.MessageService"); + }); + } + + private void ConfigureMultiTenancy(IConfiguration configuration) + { + // 多租户 + Configure(options => + { + options.IsEnabled = true; + }); + + var tenantResolveCfg = configuration.GetSection("App:Domains"); + if (tenantResolveCfg.Exists()) + { + Configure(options => + { + var domains = tenantResolveCfg.Get(); + foreach (var domain in domains) + { + options.AddDomainTenantResolver(domain); + } + }); + } + } + + private void ConfigureSwagger(IServiceCollection services) + { + // Swagger + services.AddSwaggerGen( + options => + { + options.SwaggerDoc("v1", new OpenApiInfo { Title = "MessageService API", Version = "v1" }); + options.DocInclusionPredicate((docName, description) => true); + options.CustomSchemaIds(type => type.FullName); + options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme + { + Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"", + Name = "Authorization", + In = ParameterLocation.Header, + Scheme = "bearer", + Type = SecuritySchemeType.Http, + BearerFormat = "JWT" + }); + options.AddSecurityRequirement(new OpenApiSecurityRequirement + { + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } + }, + new string[] { } + } + }); + }); + } + + private void ConfigureCors(IServiceCollection services, IConfiguration configuration) + { + services.AddCors(options => + { + options.AddPolicy(DefaultCorsPolicyName, builder => + { + builder + .WithOrigins( + configuration["App:CorsOrigins"] + .Split(",", StringSplitOptions.RemoveEmptyEntries) + .Select(o => o.RemovePostFix("/")) + .ToArray() + ) + .WithAbpExposedHeaders() + .SetIsOriginAllowedToAllowWildcardSubdomains() + .AllowAnyHeader() + .AllowAnyMethod() + .AllowCredentials(); + }); + }); + } + + private void ConfigureLocalization() + { + // 支持本地化语言类型 + Configure(options => + { + options.Languages.Add(new LanguageInfo("en", "en", "English")); + options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); + + options.Resources + .Get() + .AddVirtualJson("/Localization/HttpApiHost"); + + options.Resources.AddDynamic(); + }); + } + + private void ConfigureSecurity(IServiceCollection services, IConfiguration configuration, bool isDevelopment = false) + { + services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(options => + { + options.Authority = configuration["AuthServer:Authority"]; + options.RequireHttpsMetadata = false; + options.Audience = configuration["AuthServer:ApiName"]; + }); + + if (!isDevelopment) + { + var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); + services + .AddDataProtection() + .PersistKeysToStackExchangeRedis(redis, "MessageService-Protection-Keys"); + } + } + } +} diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/AbpMessageServiceHttpApiHostModule.Seeder.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/AbpMessageServiceHttpApiHostModule.Seeder.cs new file mode 100644 index 000000000..e1554665a --- /dev/null +++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/AbpMessageServiceHttpApiHostModule.Seeder.cs @@ -0,0 +1,21 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Volo.Abp; +using Volo.Abp.Data; +using Volo.Abp.Threading; + +namespace LINGYUN.Abp.MessageService +{ + public partial class AbpMessageServiceHttpApiHostModule + { + private void SeedData(ApplicationInitializationContext context) + { + if (context.GetEnvironment().IsDevelopment()) + { + AsyncHelper.RunSync(async () => + await context.ServiceProvider.GetRequiredService() + .SeedAsync()); + } + } + } +} diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/AbpMessageServiceHttpApiHostModule.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/AbpMessageServiceHttpApiHostModule.cs index 99d691dd7..c4383aeae 100644 --- a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/AbpMessageServiceHttpApiHostModule.cs +++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/AbpMessageServiceHttpApiHostModule.cs @@ -1,73 +1,51 @@ -using DotNetCore.CAP; -using Hangfire; +using Hangfire; using LINGYUN.Abp.AspNetCore.HttpOverrides; using LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json; +using LINGYUN.Abp.AuditLogging.Elasticsearch; using LINGYUN.Abp.BackgroundJobs.Hangfire; using LINGYUN.Abp.EventBus.CAP; -using LINGYUN.Abp.ExceptionHandling; using LINGYUN.Abp.ExceptionHandling.Notifications; using LINGYUN.Abp.Hangfire.Storage.MySql; using LINGYUN.Abp.Identity.WeChat; using LINGYUN.Abp.IM.SignalR; +using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore; using LINGYUN.Abp.MessageService.EntityFrameworkCore; -using LINGYUN.Abp.MessageService.Localization; using LINGYUN.Abp.MultiTenancy.DbFinder; using LINGYUN.Abp.Notifications.SignalR; using LINGYUN.Abp.Notifications.Sms; using LINGYUN.Abp.Notifications.WeChat.MiniProgram; -using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Cors; -using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Caching.StackExchangeRedis; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Microsoft.OpenApi.Models; -using StackExchange.Redis; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.Encodings.Web; -using System.Text.Unicode; using Volo.Abp; -using Volo.Abp.AspNetCore.Auditing; using Volo.Abp.AspNetCore.Authentication.JwtBearer; using Volo.Abp.AspNetCore.MultiTenancy; -using Volo.Abp.AspNetCore.Security.Claims; -using Volo.Abp.AspNetCore.Uow; +using Volo.Abp.AspNetCore.Serilog; using Volo.Abp.Autofac; using Volo.Abp.BackgroundWorkers; -using Volo.Abp.Caching; using Volo.Abp.Caching.StackExchangeRedis; -using Volo.Abp.EntityFrameworkCore; using Volo.Abp.Identity.EntityFrameworkCore; -using Volo.Abp.Json; -using Volo.Abp.Json.SystemTextJson; -using Volo.Abp.Localization; using Volo.Abp.Modularity; -using Volo.Abp.MultiTenancy; using Volo.Abp.PermissionManagement.EntityFrameworkCore; -using Volo.Abp.Security.Claims; -using Volo.Abp.Security.Encryption; using Volo.Abp.SettingManagement.EntityFrameworkCore; using Volo.Abp.TenantManagement.EntityFrameworkCore; -using Volo.Abp.VirtualFileSystem; namespace LINGYUN.Abp.MessageService { [DependsOn( + typeof(AbpAspNetCoreSerilogModule), + typeof(AbpAuditLoggingElasticsearchModule), + typeof(AbpAspNetCoreMultiTenancyModule), typeof(AbpMessageServiceApplicationModule), typeof(AbpMessageServiceHttpApiModule), - typeof(AbpAspNetCoreMultiTenancyModule), typeof(AbpIdentityWeChatModule), typeof(AbpMessageServiceEntityFrameworkCoreModule), typeof(AbpIdentityEntityFrameworkCoreModule), typeof(AbpTenantManagementEntityFrameworkCoreModule), typeof(AbpSettingManagementEntityFrameworkCoreModule), typeof(AbpPermissionManagementEntityFrameworkCoreModule), + typeof(AbpLocalizationManagementEntityFrameworkCoreModule), typeof(AbpAspNetCoreAuthenticationJwtBearerModule), typeof(AbpHangfireMySqlStorageModule), typeof(AbpBackgroundJobsHangfireModule), @@ -84,7 +62,7 @@ namespace LINGYUN.Abp.MessageService typeof(AbpAspNetCoreHttpOverridesModule), typeof(AbpAutofacModule) )] - public class AbpMessageServiceHttpApiHostModule : AbpModule + public partial class AbpMessageServiceHttpApiHostModule : AbpModule { private const string DefaultCorsPolicyName = "Default"; @@ -92,16 +70,7 @@ namespace LINGYUN.Abp.MessageService { var configuration = context.Services.GetConfiguration(); - PreConfigure(options => - { - options - .UseMySql(configuration.GetConnectionString("Default")) - .UseRabbitMQ(rabbitMQOptions => - { - configuration.GetSection("CAP:RabbitMQ").Bind(rabbitMQOptions); - }) - .UseDashboard(); - }); + PreConfigureCAP(configuration); } public override void ConfigureServices(ServiceConfigurationContext context) @@ -109,166 +78,17 @@ namespace LINGYUN.Abp.MessageService var hostingEnvironment = context.Services.GetHostingEnvironment(); var configuration = hostingEnvironment.BuildConfiguration(); - // 配置Ef - Configure(options => - { - options.UseMySQL(); - }); - - Configure(options => - { - options.IgnoredUrls.AddIfNotContains("/hangfire"); - }); - - // 中文序列化的编码问题 - Configure(options => - { - options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); - }); - - // 加解密 - Configure(options => - { - var encryptionConfiguration = configuration.GetSection("Encryption"); - if (encryptionConfiguration.Exists()) - { - options.DefaultPassPhrase = encryptionConfiguration["PassPhrase"] ?? options.DefaultPassPhrase; - options.DefaultSalt = encryptionConfiguration.GetSection("Salt").Exists() - ? Encoding.ASCII.GetBytes(encryptionConfiguration["Salt"]) - : options.DefaultSalt; - options.InitVectorBytes = encryptionConfiguration.GetSection("InitVector").Exists() - ? Encoding.ASCII.GetBytes(encryptionConfiguration["InitVector"]) - : options.InitVectorBytes; - } - }); - - Configure(options => - { - // 加入需要处理的异常类型 - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - }); - - Configure(options => - { - options.FileSets.AddEmbedded("LINGYUN.Abp.MessageService"); - }); - - // 多租户 - Configure(options => - { - options.IsEnabled = true; - }); - - var tenantResolveCfg = configuration.GetSection("App:Domains"); - if (tenantResolveCfg.Exists()) - { - Configure(options => - { - var domains = tenantResolveCfg.Get(); - foreach (var domain in domains) - { - options.AddDomainTenantResolver(domain); - } - }); - } - - Configure(options => - { - // 最好统一命名,不然某个缓存变动其他应用服务有例外发生 - options.KeyPrefix = "LINGYUN.Abp.Application"; - // 滑动过期30天 - options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30); - // 绝对过期60天 - options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60); - }); - - Configure(options => - { - var redisConfig = ConfigurationOptions.Parse(options.Configuration); - options.ConfigurationOptions = redisConfig; - options.InstanceName = configuration["Redis:InstanceName"]; - }); - - // Swagger - context.Services.AddSwaggerGen( - options => - { - options.SwaggerDoc("v1", new OpenApiInfo { Title = "MessageService API", Version = "v1" }); - options.DocInclusionPredicate((docName, description) => true); - options.CustomSchemaIds(type => type.FullName); - options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme - { - Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"", - Name = "Authorization", - In = ParameterLocation.Header, - Scheme = "bearer", - Type = SecuritySchemeType.Http, - BearerFormat = "JWT" - }); - options.AddSecurityRequirement(new OpenApiSecurityRequirement - { - { - new OpenApiSecurityScheme - { - Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } - }, - new string[] { } - } - }); - }); - - context.Services.AddCors(options => - { - options.AddPolicy(DefaultCorsPolicyName, builder => - { - builder - .WithOrigins( - configuration["App:CorsOrigins"] - .Split(",", StringSplitOptions.RemoveEmptyEntries) - .Select(o => o.RemovePostFix("/")) - .ToArray() - ) - .WithAbpExposedHeaders() - .SetIsOriginAllowedToAllowWildcardSubdomains() - .AllowAnyHeader() - .AllowAnyMethod() - .AllowCredentials(); - }); - }); - - // 支持本地化语言类型 - Configure(options => - { - options.Languages.Add(new LanguageInfo("en", "en", "English")); - options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); - - options.Resources - .Get() - .AddVirtualJson("/Localization/HttpApiHost"); - }); - - context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) - .AddJwtBearer(options => - { - options.Authority = configuration["AuthServer:Authority"]; - options.RequireHttpsMetadata = false; - options.Audience = configuration["AuthServer:ApiName"]; - }); - - if (!hostingEnvironment.IsDevelopment()) - { - var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); - context.Services - .AddDataProtection() - .PersistKeysToStackExchangeRedis(redis, "MessageService-Protection-Keys"); - } + ConfigureDbContext(); + ConfigureJsonSerializer(); + ConfigreExceptionHandling(); + ConfigureVirtualFileSystem(); + ConfigureMultiTenancy(configuration); + ConfigureCaching(configuration); + ConfigureSwagger(context.Services); + ConfigureCors(context.Services, configuration); + ConfigureLocalization(); + ConfigureAuditing(configuration); + ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment()); } public override void OnApplicationInitialization(ApplicationInitializationContext context) @@ -305,10 +125,13 @@ namespace LINGYUN.Abp.MessageService }); // 审计日志 app.UseAuditing(); + app.UseAbpSerilogEnrichers(); app.UseHangfireServer(); app.UseHangfireDashboard(); // 路由 app.UseConfiguredEndpoints(); + + SeedData(context); } } } diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj index 4834ace66..22577d60d 100644 --- a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj +++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj @@ -1,4 +1,4 @@ - + net5.0 @@ -25,12 +25,15 @@ - - - - - - + + + + + + + + + @@ -43,6 +46,7 @@ + @@ -53,6 +57,7 @@ + diff --git a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.Configure.cs b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.Configure.cs new file mode 100644 index 000000000..0ba978122 --- /dev/null +++ b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.Configure.cs @@ -0,0 +1,243 @@ +using DotNetCore.CAP; +using LINGYUN.Abp.ExceptionHandling; +using LINGYUN.Abp.ExceptionHandling.Emailing; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.DataProtection; +using Microsoft.AspNetCore.Server.Kestrel.Core; +using Microsoft.Extensions.Caching.StackExchangeRedis; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.OpenApi.Models; +using StackExchange.Redis; +using System; +using System.IO; +using System.Text.Encodings.Web; +using System.Text.Unicode; +using Volo.Abp; +using Volo.Abp.Auditing; +using Volo.Abp.BlobStoring; +using Volo.Abp.BlobStoring.FileSystem; +using Volo.Abp.Caching; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Json.SystemTextJson; +using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; +using Volo.Abp.VirtualFileSystem; + +namespace LINGYUN.Platform +{ + public partial class AppPlatformHttpApiHostModule + { + private void PreConfigureCAP(IConfiguration configuration) + { + PreConfigure(options => + { + options + .UseMySql(configuration.GetConnectionString("Default")) + .UseRabbitMQ(rabbitMQOptions => + { + configuration.GetSection("CAP:RabbitMQ").Bind(rabbitMQOptions); + }) + .UseDashboard(); + }); + } + + private void ConfigureDbContext() + { + // 配置Ef + Configure(options => + { + options.UseMySQL(); + }); + } + + private void ConfigureJsonSerializer() + { + // 中文序列化的编码问题 + Configure(options => + { + options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); + }); + } + + private void ConfigureKestrelServer() + { + Configure(options => + { + options.Limits.MaxRequestBodySize = null; + options.Limits.MaxRequestBufferSize = null; + }); + } + + private void ConfigureBlobStoring() + { + Configure(options => + { + options.Containers.ConfigureAll((containerName, containerConfiguration) => + { + containerConfiguration.UseFileSystem(fileSystem => + { + fileSystem.BasePath = Path.Combine(Directory.GetCurrentDirectory(), "file-blob-storing"); + }); + }); + }); + } + + private void ConfigreExceptionHandling() + { + // 自定义需要处理的异常 + Configure(options => + { + // 加入需要处理的异常类型 + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + }); + // 自定义需要发送邮件通知的异常类型 + Configure(options => + { + // 是否发送堆栈信息 + options.SendStackTrace = true; + }); + + Configure(options => + { + // 是否发送错误详情 + options.SendExceptionsDetailsToClients = false; + }); + } + + private void ConfigureAuditing(IConfiguration configuration) + { + Configure(options => + { + options.ApplicationName = "Platform"; + // 是否启用实体变更记录 + var entitiesChangedConfig = configuration.GetSection("App:TrackingEntitiesChanged"); + if (entitiesChangedConfig.Exists() && entitiesChangedConfig.Get()) + { + options + .EntityHistorySelectors + .AddAllEntities(); + } + }); + } + + private void ConfigureCaching(IConfiguration configuration) + { + Configure(options => + { + // 最好统一命名,不然某个缓存变动其他应用服务有例外发生 + options.KeyPrefix = "LINGYUN.Abp.Application"; + // 滑动过期30天 + options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30); + // 绝对过期60天 + options.GlobalCacheEntryOptions.AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(60); + }); + + Configure(options => + { + var redisConfig = ConfigurationOptions.Parse(options.Configuration); + options.ConfigurationOptions = redisConfig; + options.InstanceName = configuration["Redis:InstanceName"]; + }); + } + + private void ConfigureVirtualFileSystem() + { + Configure(options => + { + options.FileSets.AddEmbedded("LINGYUN.Platform"); + }); + } + + private void ConfigureMultiTenancy(IConfiguration configuration) + { + // 多租户 + Configure(options => + { + options.IsEnabled = true; + }); + + var tenantResolveCfg = configuration.GetSection("App:Domains"); + if (tenantResolveCfg.Exists()) + { + Configure(options => + { + var domains = tenantResolveCfg.Get(); + foreach (var domain in domains) + { + options.AddDomainTenantResolver(domain); + } + }); + } + } + + private void ConfigureSwagger(IServiceCollection services) + { + // Swagger + services.AddSwaggerGen( + options => + { + options.SwaggerDoc("v1", new OpenApiInfo { Title = "Platform API", Version = "v1" }); + options.DocInclusionPredicate((docName, description) => true); + options.CustomSchemaIds(type => type.FullName); + options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme + { + Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"", + Name = "Authorization", + In = ParameterLocation.Header, + Scheme = "bearer", + Type = SecuritySchemeType.Http, + BearerFormat = "JWT" + }); + options.AddSecurityRequirement(new OpenApiSecurityRequirement + { + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } + }, + new string[] { } + } + }); + }); + } + + private void ConfigureLocalization() + { + // 支持本地化语言类型 + Configure(options => + { + options.Languages.Add(new LanguageInfo("en", "en", "English")); + options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); + + options.Resources.AddDynamic(); + }); + } + + private void ConfigureSecurity(IServiceCollection services, IConfiguration configuration, bool isDevelopment = false) + { + services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(options => + { + options.Authority = configuration["AuthServer:Authority"]; + options.RequireHttpsMetadata = false; + options.Audience = configuration["AuthServer:ApiName"]; + }); + + if (!isDevelopment) + { + var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); + services + .AddDataProtection() + .PersistKeysToStackExchangeRedis(redis, "Platform-Protection-Keys"); + } + } + } +} diff --git a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.Seeder.cs b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.Seeder.cs new file mode 100644 index 000000000..6616394ad --- /dev/null +++ b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.Seeder.cs @@ -0,0 +1,21 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Volo.Abp; +using Volo.Abp.Data; +using Volo.Abp.Threading; + +namespace LINGYUN.Platform +{ + public partial class AppPlatformHttpApiHostModule + { + private void SeedData(ApplicationInitializationContext context) + { + if (context.GetEnvironment().IsDevelopment()) + { + AsyncHelper.RunSync(async () => + await context.ServiceProvider.GetRequiredService() + .SeedAsync()); + } + } + } +} diff --git a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.cs b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.cs index 48c8d4f9b..a1ee1027f 100644 --- a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.cs +++ b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.cs @@ -1,7 +1,6 @@ -using DotNetCore.CAP; -using LINGYUN.Abp.AspNetCore.HttpOverrides; +using LINGYUN.Abp.AspNetCore.HttpOverrides; +using LINGYUN.Abp.AuditLogging.Elasticsearch; using LINGYUN.Abp.EventBus.CAP; -using LINGYUN.Abp.ExceptionHandling; using LINGYUN.Abp.ExceptionHandling.Emailing; using LINGYUN.Abp.Features.LimitValidation.Redis; using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore; @@ -13,54 +12,31 @@ using LINGYUN.Abp.OssManagement.FileSystem.ImageSharp; using LINGYUN.Abp.OssManagement.SettingManagement; using LINGYUN.Platform.EntityFrameworkCore; using LINGYUN.Platform.HttpApi; -using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Server.Kestrel.Core; -using Microsoft.Extensions.Caching.StackExchangeRedis; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Microsoft.OpenApi.Models; -using StackExchange.Redis; -using System; -using System.IO; -using System.Text; -using System.Text.Encodings.Web; -using System.Text.Unicode; using Volo.Abp; using Volo.Abp.AspNetCore.Authentication.JwtBearer; using Volo.Abp.AspNetCore.MultiTenancy; -using Volo.Abp.AspNetCore.Security.Claims; -using Volo.Abp.Auditing; -using Volo.Abp.AuditLogging.EntityFrameworkCore; +using Volo.Abp.AspNetCore.Serilog; using Volo.Abp.Autofac; using Volo.Abp.BlobStoring; -using Volo.Abp.BlobStoring.FileSystem; -using Volo.Abp.Caching; using Volo.Abp.Caching.StackExchangeRedis; -using Volo.Abp.Data; -using Volo.Abp.EntityFrameworkCore; using Volo.Abp.FeatureManagement.EntityFrameworkCore; using Volo.Abp.Http.Client.IdentityModel.Web; using Volo.Abp.Identity; -using Volo.Abp.Json; -using Volo.Abp.Json.SystemTextJson; -using Volo.Abp.Localization; using Volo.Abp.Modularity; -using Volo.Abp.MultiTenancy; using Volo.Abp.PermissionManagement.EntityFrameworkCore; -using Volo.Abp.Security.Claims; -using Volo.Abp.Security.Encryption; using Volo.Abp.SettingManagement.EntityFrameworkCore; using Volo.Abp.TenantManagement.EntityFrameworkCore; -using Volo.Abp.Threading; -using Volo.Abp.VirtualFileSystem; namespace LINGYUN.Platform { [DependsOn( + typeof(AbpAspNetCoreSerilogModule), + typeof(AbpAuditLoggingElasticsearchModule), + typeof(AbpAspNetCoreMultiTenancyModule), // typeof(AbpOssManagementAliyunModule), typeof(AbpOssManagementFileSystemModule), // 本地文件系统提供者模块 typeof(AbpOssManagementFileSystemImageSharpModule), // 本地文件系统图形处理模块 @@ -72,9 +48,7 @@ namespace LINGYUN.Platform typeof(PlatformEntityFrameworkCoreModule), typeof(AbpIdentityHttpApiClientModule), typeof(AbpHttpClientIdentityModelWebModule), - typeof(AbpAspNetCoreMultiTenancyModule), typeof(AbpFeatureManagementEntityFrameworkCoreModule), - typeof(AbpAuditLoggingEntityFrameworkCoreModule), typeof(AbpTenantManagementEntityFrameworkCoreModule), typeof(AbpSettingManagementEntityFrameworkCoreModule), typeof(AbpPermissionManagementEntityFrameworkCoreModule), @@ -91,22 +65,13 @@ namespace LINGYUN.Platform typeof(AbpAspNetCoreHttpOverridesModule), typeof(AbpAutofacModule) )] - public class AppPlatformHttpApiHostModule : AbpModule + public partial class AppPlatformHttpApiHostModule : AbpModule { public override void PreConfigureServices(ServiceConfigurationContext context) { var configuration = context.Services.GetConfiguration(); - PreConfigure(options => - { - options - .UseMySql(configuration.GetConnectionString("Default")) - .UseRabbitMQ(rabbitMQOptions => - { - configuration.GetSection("CAP:RabbitMQ").Bind(rabbitMQOptions); - }) - .UseDashboard(); - }); + PreConfigureCAP(configuration); } public override void ConfigureServices(ServiceConfigurationContext context) @@ -114,189 +79,20 @@ namespace LINGYUN.Platform var hostingEnvironment = context.Services.GetHostingEnvironment(); var configuration = hostingEnvironment.BuildConfiguration(); - // 配置Ef - Configure(options => - { - options.UseMySQL(); - }); - - //// 中文序列化的编码问题 - Configure(options => - { - options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); - }); - - Configure(options => - { - options.Limits.MaxRequestBodySize = null; - options.Limits.MaxRequestBufferSize = null; - }); - - Configure(options => - { - options.Containers.ConfigureAll((containerName, containerConfiguration) => - { - containerConfiguration.UseFileSystem(fileSystem => - { - fileSystem.BasePath = Path.Combine(Directory.GetCurrentDirectory(), "file-blob-storing"); - }); - }); - }); - - // 加解密 - Configure(options => - { - var encryptionConfiguration = configuration.GetSection("Encryption"); - if (encryptionConfiguration.Exists()) - { - options.DefaultPassPhrase = encryptionConfiguration["PassPhrase"] ?? options.DefaultPassPhrase; - options.DefaultSalt = encryptionConfiguration.GetSection("Salt").Exists() - ? Encoding.ASCII.GetBytes(encryptionConfiguration["Salt"]) - : options.DefaultSalt; - options.InitVectorBytes = encryptionConfiguration.GetSection("InitVector").Exists() - ? Encoding.ASCII.GetBytes(encryptionConfiguration["InitVector"]) - : options.InitVectorBytes; - } - }); - - // 自定义需要处理的异常 - Configure(options => - { - // 加入需要处理的异常类型 - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - }); - - Configure(options => - { - // 是否发送错误详情 - options.SendExceptionsDetailsToClients = false; - }); - - // 自定义需要发送邮件通知的异常类型 - Configure(options => - { - // 是否发送堆栈信息 - options.SendStackTrace = true; - // 未指定异常接收者的默认接收邮件 - // 指定自己的邮件地址 - // options.DefaultReceiveEmail = "colin.in@foxmail.com"; - }); - - Configure(options => - { - // 最好统一命名,不然某个缓存变动其他应用服务有例外发生 - options.KeyPrefix = "LINGYUN.Abp.Application"; - // 滑动过期30天 - options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30); - // 绝对过期60天 - options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60); - }); - - Configure(options => - { - var redisConfig = ConfigurationOptions.Parse(options.Configuration); - options.ConfigurationOptions = redisConfig; - options.InstanceName = configuration["Redis:InstanceName"]; - }); - - Configure(options => - { - options.FileSets.AddEmbedded("LINGYUN.Platform"); - }); - - // 多租户 - Configure(options => - { - options.IsEnabled = true; - }); - - Configure(options => - { - options.ApplicationName = "Platform"; - // 是否启用实体变更记录 - var entitiesChangedConfig = configuration.GetSection("App:TrackingEntitiesChanged"); - if (entitiesChangedConfig.Exists() && entitiesChangedConfig.Get()) - { - options - .EntityHistorySelectors - .AddAllEntities(); - } - }); - - // Swagger - context.Services.AddSwaggerGen( - options => - { - options.SwaggerDoc("v1", new OpenApiInfo { Title = "Platform API", Version = "v1" }); - options.DocInclusionPredicate((docName, description) => true); - options.CustomSchemaIds(type => type.FullName); - options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme - { - Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"", - Name = "Authorization", - In = ParameterLocation.Header, - Scheme = "bearer", - Type = SecuritySchemeType.Http, - BearerFormat = "JWT" - }); - options.AddSecurityRequirement(new OpenApiSecurityRequirement - { - { - new OpenApiSecurityScheme - { - Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } - }, - new string[] { } - } - }); - }); - - // 支持本地化语言类型 - Configure(options => - { - options.Languages.Add(new LanguageInfo("en", "en", "English")); - options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); - - options.Resources.AddDynamic(); - }); - - Configure(options => - { - options.Maps.TryAdd("name", () => AbpClaimTypes.UserName); - }); - - context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) - .AddJwtBearer(options => - { - options.Authority = configuration["AuthServer:Authority"]; - options.RequireHttpsMetadata = false; - options.Audience = configuration["AuthServer:ApiName"]; - }); - - if (!hostingEnvironment.IsDevelopment()) - { - var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); - context.Services - .AddDataProtection() - .PersistKeysToStackExchangeRedis(redis, "Platform-Protection-Keys"); - } + ConfigureDbContext(); + ConfigureJsonSerializer(); + ConfigureKestrelServer(); + ConfigureBlobStoring(); + ConfigreExceptionHandling(); + ConfigureCaching(configuration); + ConfigureVirtualFileSystem(); + ConfigureMultiTenancy(configuration); + ConfigureAuditing(configuration); + ConfigureSwagger(context.Services); + ConfigureLocalization(); + ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment()); } - //public override void OnPostApplicationInitialization(ApplicationInitializationContext context) - //{ - // var backgroundJobManager = context.ServiceProvider.GetRequiredService(); - // // 五分钟执行一次的定时任务 - // AsyncHelper.RunSync(async () => await - // backgroundJobManager.EnqueueAsync(CronGenerator.Minute(5), new NotificationCleanupExpritionJobArgs(200))); - //} - public override void OnApplicationInitialization(ApplicationInitializationContext context) { var app = context.GetApplicationBuilder(); @@ -326,17 +122,13 @@ namespace LINGYUN.Platform }); // 审计日志 app.UseAuditing(); + app.UseAbpSerilogEnrichers(); // 工作单元 app.UseUnitOfWork(); // 路由 app.UseConfiguredEndpoints(); - if (env.IsDevelopment()) - { - AsyncHelper.RunSync(async () => - await app.ApplicationServices.GetRequiredService() - .SeedAsync()); - } + SeedData(context); } } } diff --git a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj index 5b7ce4cd5..12769d5d8 100644 --- a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj +++ b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj @@ -1,4 +1,4 @@ - + net5.0 @@ -28,13 +28,16 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - + + + + + + + + + + @@ -43,7 +46,6 @@ - @@ -51,6 +53,7 @@ +