diff --git a/aspnet-core/LINGYUN.MicroService.IdentityServer.sln b/aspnet-core/LINGYUN.MicroService.IdentityServer.sln
index a3680bbc4..28a924727 100644
--- a/aspnet-core/LINGYUN.MicroService.IdentityServer.sln
+++ b/aspnet-core/LINGYUN.MicroService.IdentityServer.sln
@@ -59,6 +59,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "theming", "theming", "{1D7C
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AspNetCore.Components.WebAssembly.AntDesign", "theming\Volo.Abp.AspNetCore.Components.WebAssembly.AntDesign\Volo.Abp.AspNetCore.Components.WebAssembly.AntDesign.csproj", "{596BB67C-7765-4481-9C8B-EAE0D9726B75}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.WeChat", "modules\wechat\LINGYUN.Abp.Identity.WeChat\LINGYUN.Abp.Identity.WeChat.csproj", "{46C3E5D2-7738-4C0F-AC51-C61A024CAF23}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -141,6 +143,10 @@ Global
{596BB67C-7765-4481-9C8B-EAE0D9726B75}.Debug|Any CPU.Build.0 = Debug|Any CPU
{596BB67C-7765-4481-9C8B-EAE0D9726B75}.Release|Any CPU.ActiveCfg = Release|Any CPU
{596BB67C-7765-4481-9C8B-EAE0D9726B75}.Release|Any CPU.Build.0 = Release|Any CPU
+ {46C3E5D2-7738-4C0F-AC51-C61A024CAF23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {46C3E5D2-7738-4C0F-AC51-C61A024CAF23}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {46C3E5D2-7738-4C0F-AC51-C61A024CAF23}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {46C3E5D2-7738-4C0F-AC51-C61A024CAF23}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -171,6 +177,7 @@ Global
{D63C0CA8-554D-43F2-8DB4-8B464E4C1CDA} = {98887A8F-7040-4FA1-842F-A4C77A61ED09}
{79CAF2CA-E9E1-48A5-A21F-3786383C12E0} = {98887A8F-7040-4FA1-842F-A4C77A61ED09}
{596BB67C-7765-4481-9C8B-EAE0D9726B75} = {1D7CE7E0-37AB-477B-919B-B1EB2899A17E}
+ {46C3E5D2-7738-4C0F-AC51-C61A024CAF23} = {AF8AECC8-0F42-4FC5-B3C0-00987BA8279F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FCB77471-9ECB-4666-A316-1D6A6285A468}
diff --git a/aspnet-core/LINGYUN.MicroService.IdentityServerAdmin.sln b/aspnet-core/LINGYUN.MicroService.IdentityServerAdmin.sln
index 97c6dcb92..0facd7b1d 100644
--- a/aspnet-core/LINGYUN.MicroService.IdentityServerAdmin.sln
+++ b/aspnet-core/LINGYUN.MicroService.IdentityServerAdmin.sln
@@ -1,239 +1,239 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.30011.22
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "modules", "modules", "{14B8F528-C649-4FAD-9BBB-6C979ED403E1}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer.Domain", "modules\identityServer\LINGYUN.Abp.IdentityServer.Domain\LINGYUN.Abp.IdentityServer.Domain.csproj", "{DC379D12-77E1-4600-8E99-AAD9B92C3A1B}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer.Application.Contracts", "modules\identityServer\LINGYUN.Abp.IdentityServer.Application.Contracts\LINGYUN.Abp.IdentityServer.Application.Contracts.csproj", "{3265F0C5-2D16-4CA8-A980-1B4B3CB928BB}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer.Application", "modules\identityServer\LINGYUN.Abp.IdentityServer.Application\LINGYUN.Abp.IdentityServer.Application.csproj", "{DBC8DC97-06DD-4496-9D2A-F28FDD379AE4}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer.EntityFrameworkCore", "modules\identityServer\LINGYUN.Abp.IdentityServer.EntityFrameworkCore\LINGYUN.Abp.IdentityServer.EntityFrameworkCore.csproj", "{DA57672C-501D-4CAF-8BF2-4D93B2D460BF}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer.HttpApi", "modules\identityServer\LINGYUN.Abp.IdentityServer.HttpApi\LINGYUN.Abp.IdentityServer.HttpApi.csproj", "{9C505703-C073-4E7F-9BB5-9DE0631C95AB}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "services", "services", "{0CA2F891-7E8E-453B-9FEF-ADCBEB7795DD}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer4.HttpApi.Host", "services\identity-server\LINGYUN.Abp.IdentityServer4.HttpApi.Host\LINGYUN.Abp.IdentityServer4.HttpApi.Host.csproj", "{DE9E58E2-268C-4DF0-85AA-FF7F328B62F0}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "account", "account", "{4F06C65B-22CC-466E-B3FD-3F695DD38191}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "identity-server", "identity-server", "{7AB942D5-D139-4F9F-9342-71534AA3A5AC}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "identity", "identity", "{BD964040-90B2-4179-A5EB-5830F5C7E073}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Account.Application.Contracts", "modules\account\LINGYUN.Abp.Account.Application.Contracts\LINGYUN.Abp.Account.Application.Contracts.csproj", "{A4DFDE21-1931-46B5-8381-36B6EB6E51E1}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Account.Application", "modules\account\LINGYUN.Abp.Account.Application\LINGYUN.Abp.Account.Application.csproj", "{6EE4D85F-6035-4AB5-B650-9E3D3A2AA8D2}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Account.HttpApi", "modules\account\LINGYUN.Abp.Account.HttpApi\LINGYUN.Abp.Account.HttpApi.csproj", "{BB1124C0-79F4-4E72-8854-945B3F0AD76D}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Domain", "modules\identity\LINGYUN.Abp.Identity.Domain\LINGYUN.Abp.Identity.Domain.csproj", "{E22445B9-7039-4DA1-B547-BAB437D6D2B3}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Application.Contracts", "modules\identity\LINGYUN.Abp.Identity.Application.Contracts\LINGYUN.Abp.Identity.Application.Contracts.csproj", "{116D9D69-ED2C-4F23-9445-3981D8EA0EB7}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Application", "modules\identity\LINGYUN.Abp.Identity.Application\LINGYUN.Abp.Identity.Application.csproj", "{B07A1763-1B37-4416-8F0C-B938C175A56D}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.HttpApi", "modules\identity\LINGYUN.Abp.Identity.HttpApi\LINGYUN.Abp.Identity.HttpApi.csproj", "{0F87C16B-8E91-4B25-B501-AD81F8EC599E}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.EntityFrameworkCore", "modules\identity\LINGYUN.Abp.Identity.EntityFrameworkCore\LINGYUN.Abp.Identity.EntityFrameworkCore.csproj", "{BF059F48-C8C0-4E17-AC4F-A1D1ADE405C7}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.HttpApi.Client", "modules\identity\LINGYUN.Abp.Identity.HttpApi.Client\LINGYUN.Abp.Identity.HttpApi.Client.csproj", "{6679A09F-124A-470A-81F5-A94302CEFEE4}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.PermissionManagement.Domain.Identity", "modules\identity\LINGYUN.Abp.PermissionManagement.Domain.Identity\LINGYUN.Abp.PermissionManagement.Domain.Identity.csproj", "{177B6CD3-1690-416D-9B37-A821093DEFBD}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wechat", "wechat", "{7EE9651C-17B0-4343-A2ED-92439F8C9019}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "common", "common", "{FD2DDD48-8F84-4924-BBAF-52080AB32267}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Settings", "modules\common\LINGYUN.Abp.Settings\LINGYUN.Abp.Settings.csproj", "{A8C83B9C-C9BF-48EF-80FF-D4FE2C936EFC}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Domain.Shared", "modules\identity\LINGYUN.Abp.Identity.Domain.Shared\LINGYUN.Abp.Identity.Domain.Shared.csproj", "{23536755-4F00-4929-9C5E-D4CABD1CC513}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.ExceptionHandling", "modules\common\LINGYUN.Abp.ExceptionHandling\LINGYUN.Abp.ExceptionHandling.csproj", "{80A418EB-6149-4684-80EF-D8574B91FE2B}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.ExceptionHandling.Emailing", "modules\common\LINGYUN.Abp.ExceptionHandling.Emailing\LINGYUN.Abp.ExceptionHandling.Emailing.csproj", "{986B0610-4AC3-499A-AB81-DF15EA06F4D1}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat", "modules\wechat\LINGYUN.Abp.WeChat\LINGYUN.Abp.WeChat.csproj", "{53E90646-2933-4381-9386-6BC6ED16E71A}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Aliyun.Authorization", "modules\common\LINGYUN.Abp.Aliyun.Authorization\LINGYUN.Abp.Aliyun.Authorization.csproj", "{720120B4-76F6-4701-9426-611BB8F84515}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Sms.Aliyun", "modules\common\LINGYUN.Abp.Sms.Aliyun\LINGYUN.Abp.Sms.Aliyun.csproj", "{D89ECB96-3349-4E77-B884-C18B30289D0D}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.EventBus.CAP", "modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.csproj", "{39B77454-52AB-43BE-AB33-7680719415A6}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tenants", "tenants", "{89BA9708-62E5-4FD6-A28A-CF9E1C26DCAE}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MultiTenancy", "modules\tenants\LINGYUN.Abp.MultiTenancy\LINGYUN.Abp.MultiTenancy.csproj", "{99B60A42-29DA-4D91-9255-B90F53BC6D6E}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MultiTenancy.DbFinder", "modules\tenants\LINGYUN.Abp.MultiTenancy.DbFinder\LINGYUN.Abp.MultiTenancy.DbFinder.csproj", "{70C4FA43-0526-48E3-B852-A21395502604}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AspNetCore.Mvc.Validation", "modules\common\LINGYUN.Abp.AspNetCore.Mvc.Validation\LINGYUN.Abp.AspNetCore.Mvc.Validation.csproj", "{B3181D37-F379-4E16-8621-5E739C519393}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat.MiniProgram", "modules\wechat\LINGYUN.Abp.WeChat.MiniProgram\LINGYUN.Abp.WeChat.MiniProgram.csproj", "{AD1C3335-A2A1-49C1-A6DB-817C54859B65}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {DC379D12-77E1-4600-8E99-AAD9B92C3A1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {DC379D12-77E1-4600-8E99-AAD9B92C3A1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {DC379D12-77E1-4600-8E99-AAD9B92C3A1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {DC379D12-77E1-4600-8E99-AAD9B92C3A1B}.Release|Any CPU.Build.0 = Release|Any CPU
- {3265F0C5-2D16-4CA8-A980-1B4B3CB928BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {3265F0C5-2D16-4CA8-A980-1B4B3CB928BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {3265F0C5-2D16-4CA8-A980-1B4B3CB928BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {3265F0C5-2D16-4CA8-A980-1B4B3CB928BB}.Release|Any CPU.Build.0 = Release|Any CPU
- {DBC8DC97-06DD-4496-9D2A-F28FDD379AE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {DBC8DC97-06DD-4496-9D2A-F28FDD379AE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {DBC8DC97-06DD-4496-9D2A-F28FDD379AE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {DBC8DC97-06DD-4496-9D2A-F28FDD379AE4}.Release|Any CPU.Build.0 = Release|Any CPU
- {DA57672C-501D-4CAF-8BF2-4D93B2D460BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {DA57672C-501D-4CAF-8BF2-4D93B2D460BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {DA57672C-501D-4CAF-8BF2-4D93B2D460BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {DA57672C-501D-4CAF-8BF2-4D93B2D460BF}.Release|Any CPU.Build.0 = Release|Any CPU
- {9C505703-C073-4E7F-9BB5-9DE0631C95AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {9C505703-C073-4E7F-9BB5-9DE0631C95AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {9C505703-C073-4E7F-9BB5-9DE0631C95AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {9C505703-C073-4E7F-9BB5-9DE0631C95AB}.Release|Any CPU.Build.0 = Release|Any CPU
- {DE9E58E2-268C-4DF0-85AA-FF7F328B62F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {DE9E58E2-268C-4DF0-85AA-FF7F328B62F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {DE9E58E2-268C-4DF0-85AA-FF7F328B62F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {DE9E58E2-268C-4DF0-85AA-FF7F328B62F0}.Release|Any CPU.Build.0 = Release|Any CPU
- {A4DFDE21-1931-46B5-8381-36B6EB6E51E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A4DFDE21-1931-46B5-8381-36B6EB6E51E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A4DFDE21-1931-46B5-8381-36B6EB6E51E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A4DFDE21-1931-46B5-8381-36B6EB6E51E1}.Release|Any CPU.Build.0 = Release|Any CPU
- {6EE4D85F-6035-4AB5-B650-9E3D3A2AA8D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6EE4D85F-6035-4AB5-B650-9E3D3A2AA8D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6EE4D85F-6035-4AB5-B650-9E3D3A2AA8D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6EE4D85F-6035-4AB5-B650-9E3D3A2AA8D2}.Release|Any CPU.Build.0 = Release|Any CPU
- {BB1124C0-79F4-4E72-8854-945B3F0AD76D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {BB1124C0-79F4-4E72-8854-945B3F0AD76D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {BB1124C0-79F4-4E72-8854-945B3F0AD76D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {BB1124C0-79F4-4E72-8854-945B3F0AD76D}.Release|Any CPU.Build.0 = Release|Any CPU
- {E22445B9-7039-4DA1-B547-BAB437D6D2B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E22445B9-7039-4DA1-B547-BAB437D6D2B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {E22445B9-7039-4DA1-B547-BAB437D6D2B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {E22445B9-7039-4DA1-B547-BAB437D6D2B3}.Release|Any CPU.Build.0 = Release|Any CPU
- {116D9D69-ED2C-4F23-9445-3981D8EA0EB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {116D9D69-ED2C-4F23-9445-3981D8EA0EB7}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {116D9D69-ED2C-4F23-9445-3981D8EA0EB7}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {116D9D69-ED2C-4F23-9445-3981D8EA0EB7}.Release|Any CPU.Build.0 = Release|Any CPU
- {B07A1763-1B37-4416-8F0C-B938C175A56D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {B07A1763-1B37-4416-8F0C-B938C175A56D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {B07A1763-1B37-4416-8F0C-B938C175A56D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {B07A1763-1B37-4416-8F0C-B938C175A56D}.Release|Any CPU.Build.0 = Release|Any CPU
- {0F87C16B-8E91-4B25-B501-AD81F8EC599E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0F87C16B-8E91-4B25-B501-AD81F8EC599E}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0F87C16B-8E91-4B25-B501-AD81F8EC599E}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0F87C16B-8E91-4B25-B501-AD81F8EC599E}.Release|Any CPU.Build.0 = Release|Any CPU
- {BF059F48-C8C0-4E17-AC4F-A1D1ADE405C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {BF059F48-C8C0-4E17-AC4F-A1D1ADE405C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {BF059F48-C8C0-4E17-AC4F-A1D1ADE405C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {BF059F48-C8C0-4E17-AC4F-A1D1ADE405C7}.Release|Any CPU.Build.0 = Release|Any CPU
- {6679A09F-124A-470A-81F5-A94302CEFEE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6679A09F-124A-470A-81F5-A94302CEFEE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6679A09F-124A-470A-81F5-A94302CEFEE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6679A09F-124A-470A-81F5-A94302CEFEE4}.Release|Any CPU.Build.0 = Release|Any CPU
- {177B6CD3-1690-416D-9B37-A821093DEFBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {177B6CD3-1690-416D-9B37-A821093DEFBD}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {177B6CD3-1690-416D-9B37-A821093DEFBD}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {177B6CD3-1690-416D-9B37-A821093DEFBD}.Release|Any CPU.Build.0 = Release|Any CPU
- {A8C83B9C-C9BF-48EF-80FF-D4FE2C936EFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A8C83B9C-C9BF-48EF-80FF-D4FE2C936EFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A8C83B9C-C9BF-48EF-80FF-D4FE2C936EFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A8C83B9C-C9BF-48EF-80FF-D4FE2C936EFC}.Release|Any CPU.Build.0 = Release|Any CPU
- {23536755-4F00-4929-9C5E-D4CABD1CC513}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {23536755-4F00-4929-9C5E-D4CABD1CC513}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {23536755-4F00-4929-9C5E-D4CABD1CC513}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {23536755-4F00-4929-9C5E-D4CABD1CC513}.Release|Any CPU.Build.0 = Release|Any CPU
- {80A418EB-6149-4684-80EF-D8574B91FE2B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {80A418EB-6149-4684-80EF-D8574B91FE2B}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {80A418EB-6149-4684-80EF-D8574B91FE2B}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {80A418EB-6149-4684-80EF-D8574B91FE2B}.Release|Any CPU.Build.0 = Release|Any CPU
- {986B0610-4AC3-499A-AB81-DF15EA06F4D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {986B0610-4AC3-499A-AB81-DF15EA06F4D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {986B0610-4AC3-499A-AB81-DF15EA06F4D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {986B0610-4AC3-499A-AB81-DF15EA06F4D1}.Release|Any CPU.Build.0 = Release|Any CPU
- {53E90646-2933-4381-9386-6BC6ED16E71A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {53E90646-2933-4381-9386-6BC6ED16E71A}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {53E90646-2933-4381-9386-6BC6ED16E71A}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {53E90646-2933-4381-9386-6BC6ED16E71A}.Release|Any CPU.Build.0 = Release|Any CPU
- {720120B4-76F6-4701-9426-611BB8F84515}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {720120B4-76F6-4701-9426-611BB8F84515}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {720120B4-76F6-4701-9426-611BB8F84515}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {720120B4-76F6-4701-9426-611BB8F84515}.Release|Any CPU.Build.0 = Release|Any CPU
- {D89ECB96-3349-4E77-B884-C18B30289D0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D89ECB96-3349-4E77-B884-C18B30289D0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D89ECB96-3349-4E77-B884-C18B30289D0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D89ECB96-3349-4E77-B884-C18B30289D0D}.Release|Any CPU.Build.0 = Release|Any CPU
- {39B77454-52AB-43BE-AB33-7680719415A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {39B77454-52AB-43BE-AB33-7680719415A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {39B77454-52AB-43BE-AB33-7680719415A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {39B77454-52AB-43BE-AB33-7680719415A6}.Release|Any CPU.Build.0 = Release|Any CPU
- {99B60A42-29DA-4D91-9255-B90F53BC6D6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {99B60A42-29DA-4D91-9255-B90F53BC6D6E}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {99B60A42-29DA-4D91-9255-B90F53BC6D6E}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {99B60A42-29DA-4D91-9255-B90F53BC6D6E}.Release|Any CPU.Build.0 = Release|Any CPU
- {70C4FA43-0526-48E3-B852-A21395502604}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {70C4FA43-0526-48E3-B852-A21395502604}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {70C4FA43-0526-48E3-B852-A21395502604}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {70C4FA43-0526-48E3-B852-A21395502604}.Release|Any CPU.Build.0 = Release|Any CPU
- {B3181D37-F379-4E16-8621-5E739C519393}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {B3181D37-F379-4E16-8621-5E739C519393}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {B3181D37-F379-4E16-8621-5E739C519393}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {B3181D37-F379-4E16-8621-5E739C519393}.Release|Any CPU.Build.0 = Release|Any CPU
- {AD1C3335-A2A1-49C1-A6DB-817C54859B65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {AD1C3335-A2A1-49C1-A6DB-817C54859B65}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {AD1C3335-A2A1-49C1-A6DB-817C54859B65}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {AD1C3335-A2A1-49C1-A6DB-817C54859B65}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {DC379D12-77E1-4600-8E99-AAD9B92C3A1B} = {7AB942D5-D139-4F9F-9342-71534AA3A5AC}
- {3265F0C5-2D16-4CA8-A980-1B4B3CB928BB} = {7AB942D5-D139-4F9F-9342-71534AA3A5AC}
- {DBC8DC97-06DD-4496-9D2A-F28FDD379AE4} = {7AB942D5-D139-4F9F-9342-71534AA3A5AC}
- {DA57672C-501D-4CAF-8BF2-4D93B2D460BF} = {7AB942D5-D139-4F9F-9342-71534AA3A5AC}
- {9C505703-C073-4E7F-9BB5-9DE0631C95AB} = {7AB942D5-D139-4F9F-9342-71534AA3A5AC}
- {DE9E58E2-268C-4DF0-85AA-FF7F328B62F0} = {0CA2F891-7E8E-453B-9FEF-ADCBEB7795DD}
- {4F06C65B-22CC-466E-B3FD-3F695DD38191} = {14B8F528-C649-4FAD-9BBB-6C979ED403E1}
- {7AB942D5-D139-4F9F-9342-71534AA3A5AC} = {14B8F528-C649-4FAD-9BBB-6C979ED403E1}
- {BD964040-90B2-4179-A5EB-5830F5C7E073} = {14B8F528-C649-4FAD-9BBB-6C979ED403E1}
- {A4DFDE21-1931-46B5-8381-36B6EB6E51E1} = {4F06C65B-22CC-466E-B3FD-3F695DD38191}
- {6EE4D85F-6035-4AB5-B650-9E3D3A2AA8D2} = {4F06C65B-22CC-466E-B3FD-3F695DD38191}
- {BB1124C0-79F4-4E72-8854-945B3F0AD76D} = {4F06C65B-22CC-466E-B3FD-3F695DD38191}
- {E22445B9-7039-4DA1-B547-BAB437D6D2B3} = {BD964040-90B2-4179-A5EB-5830F5C7E073}
- {116D9D69-ED2C-4F23-9445-3981D8EA0EB7} = {BD964040-90B2-4179-A5EB-5830F5C7E073}
- {B07A1763-1B37-4416-8F0C-B938C175A56D} = {BD964040-90B2-4179-A5EB-5830F5C7E073}
- {0F87C16B-8E91-4B25-B501-AD81F8EC599E} = {BD964040-90B2-4179-A5EB-5830F5C7E073}
- {BF059F48-C8C0-4E17-AC4F-A1D1ADE405C7} = {BD964040-90B2-4179-A5EB-5830F5C7E073}
- {6679A09F-124A-470A-81F5-A94302CEFEE4} = {BD964040-90B2-4179-A5EB-5830F5C7E073}
- {177B6CD3-1690-416D-9B37-A821093DEFBD} = {BD964040-90B2-4179-A5EB-5830F5C7E073}
- {7EE9651C-17B0-4343-A2ED-92439F8C9019} = {14B8F528-C649-4FAD-9BBB-6C979ED403E1}
- {FD2DDD48-8F84-4924-BBAF-52080AB32267} = {14B8F528-C649-4FAD-9BBB-6C979ED403E1}
- {A8C83B9C-C9BF-48EF-80FF-D4FE2C936EFC} = {FD2DDD48-8F84-4924-BBAF-52080AB32267}
- {23536755-4F00-4929-9C5E-D4CABD1CC513} = {BD964040-90B2-4179-A5EB-5830F5C7E073}
- {80A418EB-6149-4684-80EF-D8574B91FE2B} = {FD2DDD48-8F84-4924-BBAF-52080AB32267}
- {986B0610-4AC3-499A-AB81-DF15EA06F4D1} = {FD2DDD48-8F84-4924-BBAF-52080AB32267}
- {53E90646-2933-4381-9386-6BC6ED16E71A} = {7EE9651C-17B0-4343-A2ED-92439F8C9019}
- {720120B4-76F6-4701-9426-611BB8F84515} = {FD2DDD48-8F84-4924-BBAF-52080AB32267}
- {D89ECB96-3349-4E77-B884-C18B30289D0D} = {FD2DDD48-8F84-4924-BBAF-52080AB32267}
- {39B77454-52AB-43BE-AB33-7680719415A6} = {FD2DDD48-8F84-4924-BBAF-52080AB32267}
- {89BA9708-62E5-4FD6-A28A-CF9E1C26DCAE} = {14B8F528-C649-4FAD-9BBB-6C979ED403E1}
- {99B60A42-29DA-4D91-9255-B90F53BC6D6E} = {89BA9708-62E5-4FD6-A28A-CF9E1C26DCAE}
- {70C4FA43-0526-48E3-B852-A21395502604} = {89BA9708-62E5-4FD6-A28A-CF9E1C26DCAE}
- {B3181D37-F379-4E16-8621-5E739C519393} = {FD2DDD48-8F84-4924-BBAF-52080AB32267}
- {AD1C3335-A2A1-49C1-A6DB-817C54859B65} = {7EE9651C-17B0-4343-A2ED-92439F8C9019}
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {785FFF4D-BC59-499E-88A3-7CB7A7667228}
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30011.22
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "modules", "modules", "{14B8F528-C649-4FAD-9BBB-6C979ED403E1}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer.Domain", "modules\identityServer\LINGYUN.Abp.IdentityServer.Domain\LINGYUN.Abp.IdentityServer.Domain.csproj", "{DC379D12-77E1-4600-8E99-AAD9B92C3A1B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer.Application.Contracts", "modules\identityServer\LINGYUN.Abp.IdentityServer.Application.Contracts\LINGYUN.Abp.IdentityServer.Application.Contracts.csproj", "{3265F0C5-2D16-4CA8-A980-1B4B3CB928BB}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer.Application", "modules\identityServer\LINGYUN.Abp.IdentityServer.Application\LINGYUN.Abp.IdentityServer.Application.csproj", "{DBC8DC97-06DD-4496-9D2A-F28FDD379AE4}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer.EntityFrameworkCore", "modules\identityServer\LINGYUN.Abp.IdentityServer.EntityFrameworkCore\LINGYUN.Abp.IdentityServer.EntityFrameworkCore.csproj", "{DA57672C-501D-4CAF-8BF2-4D93B2D460BF}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer.HttpApi", "modules\identityServer\LINGYUN.Abp.IdentityServer.HttpApi\LINGYUN.Abp.IdentityServer.HttpApi.csproj", "{9C505703-C073-4E7F-9BB5-9DE0631C95AB}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "services", "services", "{0CA2F891-7E8E-453B-9FEF-ADCBEB7795DD}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer4.HttpApi.Host", "services\identity-server\LINGYUN.Abp.IdentityServer4.HttpApi.Host\LINGYUN.Abp.IdentityServer4.HttpApi.Host.csproj", "{DE9E58E2-268C-4DF0-85AA-FF7F328B62F0}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "account", "account", "{4F06C65B-22CC-466E-B3FD-3F695DD38191}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "identity-server", "identity-server", "{7AB942D5-D139-4F9F-9342-71534AA3A5AC}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "identity", "identity", "{BD964040-90B2-4179-A5EB-5830F5C7E073}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Account.Application.Contracts", "modules\account\LINGYUN.Abp.Account.Application.Contracts\LINGYUN.Abp.Account.Application.Contracts.csproj", "{A4DFDE21-1931-46B5-8381-36B6EB6E51E1}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Account.Application", "modules\account\LINGYUN.Abp.Account.Application\LINGYUN.Abp.Account.Application.csproj", "{6EE4D85F-6035-4AB5-B650-9E3D3A2AA8D2}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Account.HttpApi", "modules\account\LINGYUN.Abp.Account.HttpApi\LINGYUN.Abp.Account.HttpApi.csproj", "{BB1124C0-79F4-4E72-8854-945B3F0AD76D}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Domain", "modules\identity\LINGYUN.Abp.Identity.Domain\LINGYUN.Abp.Identity.Domain.csproj", "{E22445B9-7039-4DA1-B547-BAB437D6D2B3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Application.Contracts", "modules\identity\LINGYUN.Abp.Identity.Application.Contracts\LINGYUN.Abp.Identity.Application.Contracts.csproj", "{116D9D69-ED2C-4F23-9445-3981D8EA0EB7}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Application", "modules\identity\LINGYUN.Abp.Identity.Application\LINGYUN.Abp.Identity.Application.csproj", "{B07A1763-1B37-4416-8F0C-B938C175A56D}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.HttpApi", "modules\identity\LINGYUN.Abp.Identity.HttpApi\LINGYUN.Abp.Identity.HttpApi.csproj", "{0F87C16B-8E91-4B25-B501-AD81F8EC599E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.EntityFrameworkCore", "modules\identity\LINGYUN.Abp.Identity.EntityFrameworkCore\LINGYUN.Abp.Identity.EntityFrameworkCore.csproj", "{BF059F48-C8C0-4E17-AC4F-A1D1ADE405C7}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.HttpApi.Client", "modules\identity\LINGYUN.Abp.Identity.HttpApi.Client\LINGYUN.Abp.Identity.HttpApi.Client.csproj", "{6679A09F-124A-470A-81F5-A94302CEFEE4}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.PermissionManagement.Domain.Identity", "modules\identity\LINGYUN.Abp.PermissionManagement.Domain.Identity\LINGYUN.Abp.PermissionManagement.Domain.Identity.csproj", "{177B6CD3-1690-416D-9B37-A821093DEFBD}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wechat", "wechat", "{7EE9651C-17B0-4343-A2ED-92439F8C9019}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "common", "common", "{FD2DDD48-8F84-4924-BBAF-52080AB32267}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Settings", "modules\common\LINGYUN.Abp.Settings\LINGYUN.Abp.Settings.csproj", "{A8C83B9C-C9BF-48EF-80FF-D4FE2C936EFC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Domain.Shared", "modules\identity\LINGYUN.Abp.Identity.Domain.Shared\LINGYUN.Abp.Identity.Domain.Shared.csproj", "{23536755-4F00-4929-9C5E-D4CABD1CC513}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.ExceptionHandling", "modules\common\LINGYUN.Abp.ExceptionHandling\LINGYUN.Abp.ExceptionHandling.csproj", "{80A418EB-6149-4684-80EF-D8574B91FE2B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.ExceptionHandling.Emailing", "modules\common\LINGYUN.Abp.ExceptionHandling.Emailing\LINGYUN.Abp.ExceptionHandling.Emailing.csproj", "{986B0610-4AC3-499A-AB81-DF15EA06F4D1}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat", "modules\wechat\LINGYUN.Abp.WeChat\LINGYUN.Abp.WeChat.csproj", "{53E90646-2933-4381-9386-6BC6ED16E71A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Aliyun.Authorization", "modules\common\LINGYUN.Abp.Aliyun.Authorization\LINGYUN.Abp.Aliyun.Authorization.csproj", "{720120B4-76F6-4701-9426-611BB8F84515}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Sms.Aliyun", "modules\common\LINGYUN.Abp.Sms.Aliyun\LINGYUN.Abp.Sms.Aliyun.csproj", "{D89ECB96-3349-4E77-B884-C18B30289D0D}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.EventBus.CAP", "modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.csproj", "{39B77454-52AB-43BE-AB33-7680719415A6}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tenants", "tenants", "{89BA9708-62E5-4FD6-A28A-CF9E1C26DCAE}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MultiTenancy", "modules\tenants\LINGYUN.Abp.MultiTenancy\LINGYUN.Abp.MultiTenancy.csproj", "{99B60A42-29DA-4D91-9255-B90F53BC6D6E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MultiTenancy.DbFinder", "modules\tenants\LINGYUN.Abp.MultiTenancy.DbFinder\LINGYUN.Abp.MultiTenancy.DbFinder.csproj", "{70C4FA43-0526-48E3-B852-A21395502604}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AspNetCore.Mvc.Validation", "modules\common\LINGYUN.Abp.AspNetCore.Mvc.Validation\LINGYUN.Abp.AspNetCore.Mvc.Validation.csproj", "{B3181D37-F379-4E16-8621-5E739C519393}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat.MiniProgram", "modules\wechat\LINGYUN.Abp.WeChat.MiniProgram\LINGYUN.Abp.WeChat.MiniProgram.csproj", "{AD1C3335-A2A1-49C1-A6DB-817C54859B65}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {DC379D12-77E1-4600-8E99-AAD9B92C3A1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DC379D12-77E1-4600-8E99-AAD9B92C3A1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DC379D12-77E1-4600-8E99-AAD9B92C3A1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DC379D12-77E1-4600-8E99-AAD9B92C3A1B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3265F0C5-2D16-4CA8-A980-1B4B3CB928BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3265F0C5-2D16-4CA8-A980-1B4B3CB928BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3265F0C5-2D16-4CA8-A980-1B4B3CB928BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3265F0C5-2D16-4CA8-A980-1B4B3CB928BB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DBC8DC97-06DD-4496-9D2A-F28FDD379AE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DBC8DC97-06DD-4496-9D2A-F28FDD379AE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DBC8DC97-06DD-4496-9D2A-F28FDD379AE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DBC8DC97-06DD-4496-9D2A-F28FDD379AE4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DA57672C-501D-4CAF-8BF2-4D93B2D460BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DA57672C-501D-4CAF-8BF2-4D93B2D460BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DA57672C-501D-4CAF-8BF2-4D93B2D460BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DA57672C-501D-4CAF-8BF2-4D93B2D460BF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9C505703-C073-4E7F-9BB5-9DE0631C95AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9C505703-C073-4E7F-9BB5-9DE0631C95AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9C505703-C073-4E7F-9BB5-9DE0631C95AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9C505703-C073-4E7F-9BB5-9DE0631C95AB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DE9E58E2-268C-4DF0-85AA-FF7F328B62F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DE9E58E2-268C-4DF0-85AA-FF7F328B62F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DE9E58E2-268C-4DF0-85AA-FF7F328B62F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DE9E58E2-268C-4DF0-85AA-FF7F328B62F0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A4DFDE21-1931-46B5-8381-36B6EB6E51E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A4DFDE21-1931-46B5-8381-36B6EB6E51E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A4DFDE21-1931-46B5-8381-36B6EB6E51E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A4DFDE21-1931-46B5-8381-36B6EB6E51E1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6EE4D85F-6035-4AB5-B650-9E3D3A2AA8D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6EE4D85F-6035-4AB5-B650-9E3D3A2AA8D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6EE4D85F-6035-4AB5-B650-9E3D3A2AA8D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6EE4D85F-6035-4AB5-B650-9E3D3A2AA8D2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BB1124C0-79F4-4E72-8854-945B3F0AD76D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BB1124C0-79F4-4E72-8854-945B3F0AD76D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BB1124C0-79F4-4E72-8854-945B3F0AD76D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BB1124C0-79F4-4E72-8854-945B3F0AD76D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E22445B9-7039-4DA1-B547-BAB437D6D2B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E22445B9-7039-4DA1-B547-BAB437D6D2B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E22445B9-7039-4DA1-B547-BAB437D6D2B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E22445B9-7039-4DA1-B547-BAB437D6D2B3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {116D9D69-ED2C-4F23-9445-3981D8EA0EB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {116D9D69-ED2C-4F23-9445-3981D8EA0EB7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {116D9D69-ED2C-4F23-9445-3981D8EA0EB7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {116D9D69-ED2C-4F23-9445-3981D8EA0EB7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B07A1763-1B37-4416-8F0C-B938C175A56D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B07A1763-1B37-4416-8F0C-B938C175A56D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B07A1763-1B37-4416-8F0C-B938C175A56D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B07A1763-1B37-4416-8F0C-B938C175A56D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0F87C16B-8E91-4B25-B501-AD81F8EC599E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0F87C16B-8E91-4B25-B501-AD81F8EC599E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0F87C16B-8E91-4B25-B501-AD81F8EC599E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0F87C16B-8E91-4B25-B501-AD81F8EC599E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BF059F48-C8C0-4E17-AC4F-A1D1ADE405C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BF059F48-C8C0-4E17-AC4F-A1D1ADE405C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BF059F48-C8C0-4E17-AC4F-A1D1ADE405C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BF059F48-C8C0-4E17-AC4F-A1D1ADE405C7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6679A09F-124A-470A-81F5-A94302CEFEE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6679A09F-124A-470A-81F5-A94302CEFEE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6679A09F-124A-470A-81F5-A94302CEFEE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6679A09F-124A-470A-81F5-A94302CEFEE4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {177B6CD3-1690-416D-9B37-A821093DEFBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {177B6CD3-1690-416D-9B37-A821093DEFBD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {177B6CD3-1690-416D-9B37-A821093DEFBD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {177B6CD3-1690-416D-9B37-A821093DEFBD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A8C83B9C-C9BF-48EF-80FF-D4FE2C936EFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A8C83B9C-C9BF-48EF-80FF-D4FE2C936EFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A8C83B9C-C9BF-48EF-80FF-D4FE2C936EFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A8C83B9C-C9BF-48EF-80FF-D4FE2C936EFC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {23536755-4F00-4929-9C5E-D4CABD1CC513}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {23536755-4F00-4929-9C5E-D4CABD1CC513}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {23536755-4F00-4929-9C5E-D4CABD1CC513}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {23536755-4F00-4929-9C5E-D4CABD1CC513}.Release|Any CPU.Build.0 = Release|Any CPU
+ {80A418EB-6149-4684-80EF-D8574B91FE2B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {80A418EB-6149-4684-80EF-D8574B91FE2B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {80A418EB-6149-4684-80EF-D8574B91FE2B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {80A418EB-6149-4684-80EF-D8574B91FE2B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {986B0610-4AC3-499A-AB81-DF15EA06F4D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {986B0610-4AC3-499A-AB81-DF15EA06F4D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {986B0610-4AC3-499A-AB81-DF15EA06F4D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {986B0610-4AC3-499A-AB81-DF15EA06F4D1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {53E90646-2933-4381-9386-6BC6ED16E71A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {53E90646-2933-4381-9386-6BC6ED16E71A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {53E90646-2933-4381-9386-6BC6ED16E71A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {53E90646-2933-4381-9386-6BC6ED16E71A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {720120B4-76F6-4701-9426-611BB8F84515}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {720120B4-76F6-4701-9426-611BB8F84515}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {720120B4-76F6-4701-9426-611BB8F84515}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {720120B4-76F6-4701-9426-611BB8F84515}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D89ECB96-3349-4E77-B884-C18B30289D0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D89ECB96-3349-4E77-B884-C18B30289D0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D89ECB96-3349-4E77-B884-C18B30289D0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D89ECB96-3349-4E77-B884-C18B30289D0D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {39B77454-52AB-43BE-AB33-7680719415A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {39B77454-52AB-43BE-AB33-7680719415A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {39B77454-52AB-43BE-AB33-7680719415A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {39B77454-52AB-43BE-AB33-7680719415A6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {99B60A42-29DA-4D91-9255-B90F53BC6D6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {99B60A42-29DA-4D91-9255-B90F53BC6D6E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {99B60A42-29DA-4D91-9255-B90F53BC6D6E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {99B60A42-29DA-4D91-9255-B90F53BC6D6E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {70C4FA43-0526-48E3-B852-A21395502604}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {70C4FA43-0526-48E3-B852-A21395502604}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {70C4FA43-0526-48E3-B852-A21395502604}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {70C4FA43-0526-48E3-B852-A21395502604}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B3181D37-F379-4E16-8621-5E739C519393}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B3181D37-F379-4E16-8621-5E739C519393}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B3181D37-F379-4E16-8621-5E739C519393}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B3181D37-F379-4E16-8621-5E739C519393}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AD1C3335-A2A1-49C1-A6DB-817C54859B65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AD1C3335-A2A1-49C1-A6DB-817C54859B65}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AD1C3335-A2A1-49C1-A6DB-817C54859B65}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AD1C3335-A2A1-49C1-A6DB-817C54859B65}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {DC379D12-77E1-4600-8E99-AAD9B92C3A1B} = {7AB942D5-D139-4F9F-9342-71534AA3A5AC}
+ {3265F0C5-2D16-4CA8-A980-1B4B3CB928BB} = {7AB942D5-D139-4F9F-9342-71534AA3A5AC}
+ {DBC8DC97-06DD-4496-9D2A-F28FDD379AE4} = {7AB942D5-D139-4F9F-9342-71534AA3A5AC}
+ {DA57672C-501D-4CAF-8BF2-4D93B2D460BF} = {7AB942D5-D139-4F9F-9342-71534AA3A5AC}
+ {9C505703-C073-4E7F-9BB5-9DE0631C95AB} = {7AB942D5-D139-4F9F-9342-71534AA3A5AC}
+ {DE9E58E2-268C-4DF0-85AA-FF7F328B62F0} = {0CA2F891-7E8E-453B-9FEF-ADCBEB7795DD}
+ {4F06C65B-22CC-466E-B3FD-3F695DD38191} = {14B8F528-C649-4FAD-9BBB-6C979ED403E1}
+ {7AB942D5-D139-4F9F-9342-71534AA3A5AC} = {14B8F528-C649-4FAD-9BBB-6C979ED403E1}
+ {BD964040-90B2-4179-A5EB-5830F5C7E073} = {14B8F528-C649-4FAD-9BBB-6C979ED403E1}
+ {A4DFDE21-1931-46B5-8381-36B6EB6E51E1} = {4F06C65B-22CC-466E-B3FD-3F695DD38191}
+ {6EE4D85F-6035-4AB5-B650-9E3D3A2AA8D2} = {4F06C65B-22CC-466E-B3FD-3F695DD38191}
+ {BB1124C0-79F4-4E72-8854-945B3F0AD76D} = {4F06C65B-22CC-466E-B3FD-3F695DD38191}
+ {E22445B9-7039-4DA1-B547-BAB437D6D2B3} = {BD964040-90B2-4179-A5EB-5830F5C7E073}
+ {116D9D69-ED2C-4F23-9445-3981D8EA0EB7} = {BD964040-90B2-4179-A5EB-5830F5C7E073}
+ {B07A1763-1B37-4416-8F0C-B938C175A56D} = {BD964040-90B2-4179-A5EB-5830F5C7E073}
+ {0F87C16B-8E91-4B25-B501-AD81F8EC599E} = {BD964040-90B2-4179-A5EB-5830F5C7E073}
+ {BF059F48-C8C0-4E17-AC4F-A1D1ADE405C7} = {BD964040-90B2-4179-A5EB-5830F5C7E073}
+ {6679A09F-124A-470A-81F5-A94302CEFEE4} = {BD964040-90B2-4179-A5EB-5830F5C7E073}
+ {177B6CD3-1690-416D-9B37-A821093DEFBD} = {BD964040-90B2-4179-A5EB-5830F5C7E073}
+ {7EE9651C-17B0-4343-A2ED-92439F8C9019} = {14B8F528-C649-4FAD-9BBB-6C979ED403E1}
+ {FD2DDD48-8F84-4924-BBAF-52080AB32267} = {14B8F528-C649-4FAD-9BBB-6C979ED403E1}
+ {A8C83B9C-C9BF-48EF-80FF-D4FE2C936EFC} = {FD2DDD48-8F84-4924-BBAF-52080AB32267}
+ {23536755-4F00-4929-9C5E-D4CABD1CC513} = {BD964040-90B2-4179-A5EB-5830F5C7E073}
+ {80A418EB-6149-4684-80EF-D8574B91FE2B} = {FD2DDD48-8F84-4924-BBAF-52080AB32267}
+ {986B0610-4AC3-499A-AB81-DF15EA06F4D1} = {FD2DDD48-8F84-4924-BBAF-52080AB32267}
+ {53E90646-2933-4381-9386-6BC6ED16E71A} = {7EE9651C-17B0-4343-A2ED-92439F8C9019}
+ {720120B4-76F6-4701-9426-611BB8F84515} = {FD2DDD48-8F84-4924-BBAF-52080AB32267}
+ {D89ECB96-3349-4E77-B884-C18B30289D0D} = {FD2DDD48-8F84-4924-BBAF-52080AB32267}
+ {39B77454-52AB-43BE-AB33-7680719415A6} = {FD2DDD48-8F84-4924-BBAF-52080AB32267}
+ {89BA9708-62E5-4FD6-A28A-CF9E1C26DCAE} = {14B8F528-C649-4FAD-9BBB-6C979ED403E1}
+ {99B60A42-29DA-4D91-9255-B90F53BC6D6E} = {89BA9708-62E5-4FD6-A28A-CF9E1C26DCAE}
+ {70C4FA43-0526-48E3-B852-A21395502604} = {89BA9708-62E5-4FD6-A28A-CF9E1C26DCAE}
+ {B3181D37-F379-4E16-8621-5E739C519393} = {FD2DDD48-8F84-4924-BBAF-52080AB32267}
+ {AD1C3335-A2A1-49C1-A6DB-817C54859B65} = {7EE9651C-17B0-4343-A2ED-92439F8C9019}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {785FFF4D-BC59-499E-88A3-7CB7A7667228}
+ EndGlobalSection
+EndGlobal
diff --git a/aspnet-core/LINGYUN.MicroService.Messages.sln b/aspnet-core/LINGYUN.MicroService.Messages.sln
index 87dd3b544..c4981c4ea 100644
--- a/aspnet-core/LINGYUN.MicroService.Messages.sln
+++ b/aspnet-core/LINGYUN.MicroService.Messages.sln
@@ -1,267 +1,274 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.30011.22
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "modules", "modules", "{0C7AA298-2957-4D71-A8F1-1C3C7932A1B3}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "services", "services", "{E7A821D8-85B5-4098-897D-5A814BD8131D}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "common", "common", "{C00828FB-E7D5-4086-BA50-02022594AB73}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.RealTime", "modules\common\LINGYUN.Abp.RealTime\LINGYUN.Abp.RealTime.csproj", "{07BCD006-F2F2-4685-8887-E8BEB18745FD}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.RealTime.SignalR", "modules\common\LINGYUN.Abp.RealTime.SignalR\LINGYUN.Abp.RealTime.SignalR.csproj", "{60E37E86-ACA6-4464-9592-B0D8EFB629BD}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AspNetCore.SignalR.JwtToken", "modules\common\LINGYUN.Abp.AspNetCore.SignalR\LINGYUN.Abp.AspNetCore.SignalR.JwtToken.csproj", "{85B39FCE-6778-497C-A12E-6777C7FE651A}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json", "modules\common\LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json\LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json.csproj", "{8C973655-DF59-40D8-B206-82344575A8CF}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IM", "modules\common\LINGYUN.Abp.IM\LINGYUN.Abp.IM.csproj", "{55B9F554-1754-4EF9-B325-B33421D4F6A9}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IM.SignalR", "modules\common\LINGYUN.Abp.IM.SignalR\LINGYUN.Abp.IM.SignalR.csproj", "{7AC8C076-87E2-48ED-8AB3-C1F737F55DD1}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications", "modules\common\LINGYUN.Abp.Notifications\LINGYUN.Abp.Notifications.csproj", "{C6F494D3-2C41-46DF-BCAD-F74D3E53CDE1}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.SignalR", "modules\common\LINGYUN.Abp.Notifications.SignalR\LINGYUN.Abp.Notifications.SignalR.csproj", "{3531699A-9FF9-4F8C-BEAD-9D114FE8E519}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.Domain.Shared", "modules\message\LINGYUN.Abp.MessageService.Domain.Shared\LINGYUN.Abp.MessageService.Domain.Shared.csproj", "{50DE8ABF-B50A-4AAB-A69B-4E727AFDB6B5}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.Domain", "modules\message\LINGYUN.Abp.MessageService.Domain\LINGYUN.Abp.MessageService.Domain.csproj", "{2094F03B-FC73-4B3F-88CB-F7951E22FED5}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.EntityFrameworkCore", "modules\message\LINGYUN.Abp.MessageService.EntityFrameworkCore\LINGYUN.Abp.MessageService.EntityFrameworkCore.csproj", "{554E5BCA-7F88-4E7C-86ED-8B6DE3A3A802}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.Application.Contracts", "modules\message\LINGYUN.Abp.MessageService.Application.Contracts\LINGYUN.Abp.MessageService.Application.Contracts.csproj", "{92E4CAD4-F5B9-4B16-B7BC-4A40DC1E93F1}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.Application", "modules\message\LINGYUN.Abp.MessageService.Application\LINGYUN.Abp.MessageService.Application.csproj", "{DB8CE5AF-1888-4C51-97C3-2188BE50FAF9}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.HttpApi", "modules\message\LINGYUN.Abp.MessageService.HttpApi\LINGYUN.Abp.MessageService.HttpApi.csproj", "{54395254-0383-4932-B2E4-50932DAD7D10}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.HttpApi.Client", "modules\message\LINGYUN.Abp.MessageService.HttpApi.Client\LINGYUN.Abp.MessageService.HttpApi.Client.csproj", "{3E9CCC0A-DAD5-4F32-8EAE-654D67DEE2B9}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.HttpApi.Host", "services\messages\LINGYUN.Abp.MessageService.HttpApi.Host\LINGYUN.Abp.MessageService.HttpApi.Host.csproj", "{8168B7B4-9F6B-4658-A28C-D0F9D10AB93D}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wechat", "wechat", "{78164C5C-63B9-4FB6-ACC9-6496E236C946}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Features.LimitValidation", "modules\common\LINGYUN.Abp.Features.LimitValidation\LINGYUN.Abp.Features.LimitValidation.csproj", "{93971F1F-F6AC-4F83-8119-21260FCE2828}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat", "modules\wechat\LINGYUN.Abp.WeChat\LINGYUN.Abp.WeChat.csproj", "{3B87330F-A303-4413-B653-1C9536C74109}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "message", "message", "{D58F1DF5-2DFE-40A2-B136-7606D4CDE903}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat.MiniProgram", "modules\wechat\LINGYUN.Abp.WeChat.MiniProgram\LINGYUN.Abp.WeChat.MiniProgram.csproj", "{3A4601FE-B091-43A3-AEE6-6440BB37B277}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.Sms", "modules\common\LINGYUN.Abp.Notifications.Sms\LINGYUN.Abp.Notifications.Sms.csproj", "{454059F7-D087-439A-A724-80BDFE94776F}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.WeChat.MiniProgram", "modules\wechat\LINGYUN.Abp.Notifications.WeChat.MiniProgram\LINGYUN.Abp.Notifications.WeChat.MiniProgram.csproj", "{64E2622A-611D-4056-9497-0B52A91DC59C}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{42800C56-9473-4B96-BF29-1B0F25C867F4}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.Sms.Tests", "tests\LINGYUN.Abp.Notifications.Sms.Tests\LINGYUN.Abp.Notifications.Sms.Tests.csproj", "{5714481A-BDF5-4860-9158-3B18D3018EC5}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.TestsBase", "tests\LINGYUN.Abp.TestBase\LINGYUN.Abp.TestsBase.csproj", "{B5E23AED-3068-4CFE-84B0-3B7725665506}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.Tests", "tests\LINGYUN.Abp.Notifications.Tests\LINGYUN.Abp.Notifications.Tests.csproj", "{E5257008-A0AD-473F-91B0-864FC601B84B}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests", "tests\LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests\LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests.csproj", "{DB425943-CEE6-4FF6-A0EE-233B6ADA3BD7}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.EntityFrameworkCore.Tests", "tests\LINGYUN.Abp.EntityFrameworkCore.Tests\LINGYUN.Abp.EntityFrameworkCore.Tests.csproj", "{25267137-08BE-44A6-9F7E-7783CC8C62E8}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.EntityFrameworkCore.Tests", "tests\LINGYUN.Abp.MessageService.EntityFrameworkCore.Tests\LINGYUN.Abp.MessageService.EntityFrameworkCore.Tests.csproj", "{CB6D56DA-539B-4D4F-81CD-D683ADEBFB5F}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.Domain.Tests", "tests\LINGYUN.Abp.MessageService.Domain.Tests\LINGYUN.Abp.MessageService.Domain.Tests.csproj", "{097319B9-D062-4A54-8F8C-001C180E2CB3}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.BackgroundJobs.Hangfire", "modules\common\LINGYUN.Abp.BackgroundJobs.Hangfire\LINGYUN.Abp.BackgroundJobs.Hangfire.csproj", "{737EF17D-477F-4C73-A4CC-0DA6CBD3BB97}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Hangfire.Storage.MySql", "modules\common\LINGYUN.Abp.Hangfire.MySqlStorage\LINGYUN.Abp.Hangfire.Storage.MySql.csproj", "{0B6AAACE-A1DE-4063-8DA8-E7EBA30186E4}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Hangfire.Dashboard", "modules\common\LINGYUN.Abp.Hangfire.Dashboard\LINGYUN.Abp.Hangfire.Dashboard.csproj", "{05DCBA6B-480A-4D2F-9855-F66F5B7F3A48}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.BackgroundWorkers.Hangfire", "modules\common\LINGYUN.Abp.BackgroundWorkers.Hangfire\LINGYUN.Abp.BackgroundWorkers.Hangfire.csproj", "{32D4DB5D-74D1-4166-85EA-B2D8F14B8058}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.EventBus.CAP", "modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.csproj", "{C49B50D4-5D63-47E6-82F7-E742181CF9DE}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {07BCD006-F2F2-4685-8887-E8BEB18745FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {07BCD006-F2F2-4685-8887-E8BEB18745FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {07BCD006-F2F2-4685-8887-E8BEB18745FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {07BCD006-F2F2-4685-8887-E8BEB18745FD}.Release|Any CPU.Build.0 = Release|Any CPU
- {60E37E86-ACA6-4464-9592-B0D8EFB629BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {60E37E86-ACA6-4464-9592-B0D8EFB629BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {60E37E86-ACA6-4464-9592-B0D8EFB629BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {60E37E86-ACA6-4464-9592-B0D8EFB629BD}.Release|Any CPU.Build.0 = Release|Any CPU
- {85B39FCE-6778-497C-A12E-6777C7FE651A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {85B39FCE-6778-497C-A12E-6777C7FE651A}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {85B39FCE-6778-497C-A12E-6777C7FE651A}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {85B39FCE-6778-497C-A12E-6777C7FE651A}.Release|Any CPU.Build.0 = Release|Any CPU
- {8C973655-DF59-40D8-B206-82344575A8CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {8C973655-DF59-40D8-B206-82344575A8CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {8C973655-DF59-40D8-B206-82344575A8CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {8C973655-DF59-40D8-B206-82344575A8CF}.Release|Any CPU.Build.0 = Release|Any CPU
- {55B9F554-1754-4EF9-B325-B33421D4F6A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {55B9F554-1754-4EF9-B325-B33421D4F6A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {55B9F554-1754-4EF9-B325-B33421D4F6A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {55B9F554-1754-4EF9-B325-B33421D4F6A9}.Release|Any CPU.Build.0 = Release|Any CPU
- {7AC8C076-87E2-48ED-8AB3-C1F737F55DD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {7AC8C076-87E2-48ED-8AB3-C1F737F55DD1}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {7AC8C076-87E2-48ED-8AB3-C1F737F55DD1}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {7AC8C076-87E2-48ED-8AB3-C1F737F55DD1}.Release|Any CPU.Build.0 = Release|Any CPU
- {C6F494D3-2C41-46DF-BCAD-F74D3E53CDE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {C6F494D3-2C41-46DF-BCAD-F74D3E53CDE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {C6F494D3-2C41-46DF-BCAD-F74D3E53CDE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C6F494D3-2C41-46DF-BCAD-F74D3E53CDE1}.Release|Any CPU.Build.0 = Release|Any CPU
- {3531699A-9FF9-4F8C-BEAD-9D114FE8E519}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {3531699A-9FF9-4F8C-BEAD-9D114FE8E519}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {3531699A-9FF9-4F8C-BEAD-9D114FE8E519}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {3531699A-9FF9-4F8C-BEAD-9D114FE8E519}.Release|Any CPU.Build.0 = Release|Any CPU
- {50DE8ABF-B50A-4AAB-A69B-4E727AFDB6B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {50DE8ABF-B50A-4AAB-A69B-4E727AFDB6B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {50DE8ABF-B50A-4AAB-A69B-4E727AFDB6B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {50DE8ABF-B50A-4AAB-A69B-4E727AFDB6B5}.Release|Any CPU.Build.0 = Release|Any CPU
- {2094F03B-FC73-4B3F-88CB-F7951E22FED5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {2094F03B-FC73-4B3F-88CB-F7951E22FED5}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {2094F03B-FC73-4B3F-88CB-F7951E22FED5}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {2094F03B-FC73-4B3F-88CB-F7951E22FED5}.Release|Any CPU.Build.0 = Release|Any CPU
- {554E5BCA-7F88-4E7C-86ED-8B6DE3A3A802}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {554E5BCA-7F88-4E7C-86ED-8B6DE3A3A802}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {554E5BCA-7F88-4E7C-86ED-8B6DE3A3A802}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {554E5BCA-7F88-4E7C-86ED-8B6DE3A3A802}.Release|Any CPU.Build.0 = Release|Any CPU
- {92E4CAD4-F5B9-4B16-B7BC-4A40DC1E93F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {92E4CAD4-F5B9-4B16-B7BC-4A40DC1E93F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {92E4CAD4-F5B9-4B16-B7BC-4A40DC1E93F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {92E4CAD4-F5B9-4B16-B7BC-4A40DC1E93F1}.Release|Any CPU.Build.0 = Release|Any CPU
- {DB8CE5AF-1888-4C51-97C3-2188BE50FAF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {DB8CE5AF-1888-4C51-97C3-2188BE50FAF9}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {DB8CE5AF-1888-4C51-97C3-2188BE50FAF9}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {DB8CE5AF-1888-4C51-97C3-2188BE50FAF9}.Release|Any CPU.Build.0 = Release|Any CPU
- {54395254-0383-4932-B2E4-50932DAD7D10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {54395254-0383-4932-B2E4-50932DAD7D10}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {54395254-0383-4932-B2E4-50932DAD7D10}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {54395254-0383-4932-B2E4-50932DAD7D10}.Release|Any CPU.Build.0 = Release|Any CPU
- {3E9CCC0A-DAD5-4F32-8EAE-654D67DEE2B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {3E9CCC0A-DAD5-4F32-8EAE-654D67DEE2B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {3E9CCC0A-DAD5-4F32-8EAE-654D67DEE2B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {3E9CCC0A-DAD5-4F32-8EAE-654D67DEE2B9}.Release|Any CPU.Build.0 = Release|Any CPU
- {8168B7B4-9F6B-4658-A28C-D0F9D10AB93D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {8168B7B4-9F6B-4658-A28C-D0F9D10AB93D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {8168B7B4-9F6B-4658-A28C-D0F9D10AB93D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {8168B7B4-9F6B-4658-A28C-D0F9D10AB93D}.Release|Any CPU.Build.0 = Release|Any CPU
- {93971F1F-F6AC-4F83-8119-21260FCE2828}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {93971F1F-F6AC-4F83-8119-21260FCE2828}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {93971F1F-F6AC-4F83-8119-21260FCE2828}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {93971F1F-F6AC-4F83-8119-21260FCE2828}.Release|Any CPU.Build.0 = Release|Any CPU
- {3B87330F-A303-4413-B653-1C9536C74109}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {3B87330F-A303-4413-B653-1C9536C74109}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {3B87330F-A303-4413-B653-1C9536C74109}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {3B87330F-A303-4413-B653-1C9536C74109}.Release|Any CPU.Build.0 = Release|Any CPU
- {3A4601FE-B091-43A3-AEE6-6440BB37B277}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {3A4601FE-B091-43A3-AEE6-6440BB37B277}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {3A4601FE-B091-43A3-AEE6-6440BB37B277}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {3A4601FE-B091-43A3-AEE6-6440BB37B277}.Release|Any CPU.Build.0 = Release|Any CPU
- {454059F7-D087-439A-A724-80BDFE94776F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {454059F7-D087-439A-A724-80BDFE94776F}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {454059F7-D087-439A-A724-80BDFE94776F}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {454059F7-D087-439A-A724-80BDFE94776F}.Release|Any CPU.Build.0 = Release|Any CPU
- {64E2622A-611D-4056-9497-0B52A91DC59C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {64E2622A-611D-4056-9497-0B52A91DC59C}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {64E2622A-611D-4056-9497-0B52A91DC59C}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {64E2622A-611D-4056-9497-0B52A91DC59C}.Release|Any CPU.Build.0 = Release|Any CPU
- {5714481A-BDF5-4860-9158-3B18D3018EC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {5714481A-BDF5-4860-9158-3B18D3018EC5}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {5714481A-BDF5-4860-9158-3B18D3018EC5}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {5714481A-BDF5-4860-9158-3B18D3018EC5}.Release|Any CPU.Build.0 = Release|Any CPU
- {B5E23AED-3068-4CFE-84B0-3B7725665506}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {B5E23AED-3068-4CFE-84B0-3B7725665506}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {B5E23AED-3068-4CFE-84B0-3B7725665506}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {B5E23AED-3068-4CFE-84B0-3B7725665506}.Release|Any CPU.Build.0 = Release|Any CPU
- {E5257008-A0AD-473F-91B0-864FC601B84B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E5257008-A0AD-473F-91B0-864FC601B84B}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {E5257008-A0AD-473F-91B0-864FC601B84B}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {E5257008-A0AD-473F-91B0-864FC601B84B}.Release|Any CPU.Build.0 = Release|Any CPU
- {DB425943-CEE6-4FF6-A0EE-233B6ADA3BD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {DB425943-CEE6-4FF6-A0EE-233B6ADA3BD7}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {DB425943-CEE6-4FF6-A0EE-233B6ADA3BD7}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {DB425943-CEE6-4FF6-A0EE-233B6ADA3BD7}.Release|Any CPU.Build.0 = Release|Any CPU
- {25267137-08BE-44A6-9F7E-7783CC8C62E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {25267137-08BE-44A6-9F7E-7783CC8C62E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {25267137-08BE-44A6-9F7E-7783CC8C62E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {25267137-08BE-44A6-9F7E-7783CC8C62E8}.Release|Any CPU.Build.0 = Release|Any CPU
- {CB6D56DA-539B-4D4F-81CD-D683ADEBFB5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {CB6D56DA-539B-4D4F-81CD-D683ADEBFB5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {CB6D56DA-539B-4D4F-81CD-D683ADEBFB5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {CB6D56DA-539B-4D4F-81CD-D683ADEBFB5F}.Release|Any CPU.Build.0 = Release|Any CPU
- {097319B9-D062-4A54-8F8C-001C180E2CB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {097319B9-D062-4A54-8F8C-001C180E2CB3}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {097319B9-D062-4A54-8F8C-001C180E2CB3}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {097319B9-D062-4A54-8F8C-001C180E2CB3}.Release|Any CPU.Build.0 = Release|Any CPU
- {737EF17D-477F-4C73-A4CC-0DA6CBD3BB97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {737EF17D-477F-4C73-A4CC-0DA6CBD3BB97}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {737EF17D-477F-4C73-A4CC-0DA6CBD3BB97}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {737EF17D-477F-4C73-A4CC-0DA6CBD3BB97}.Release|Any CPU.Build.0 = Release|Any CPU
- {0B6AAACE-A1DE-4063-8DA8-E7EBA30186E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0B6AAACE-A1DE-4063-8DA8-E7EBA30186E4}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0B6AAACE-A1DE-4063-8DA8-E7EBA30186E4}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0B6AAACE-A1DE-4063-8DA8-E7EBA30186E4}.Release|Any CPU.Build.0 = Release|Any CPU
- {05DCBA6B-480A-4D2F-9855-F66F5B7F3A48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {05DCBA6B-480A-4D2F-9855-F66F5B7F3A48}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {05DCBA6B-480A-4D2F-9855-F66F5B7F3A48}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {05DCBA6B-480A-4D2F-9855-F66F5B7F3A48}.Release|Any CPU.Build.0 = Release|Any CPU
- {32D4DB5D-74D1-4166-85EA-B2D8F14B8058}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {32D4DB5D-74D1-4166-85EA-B2D8F14B8058}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {32D4DB5D-74D1-4166-85EA-B2D8F14B8058}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {32D4DB5D-74D1-4166-85EA-B2D8F14B8058}.Release|Any CPU.Build.0 = Release|Any CPU
- {C49B50D4-5D63-47E6-82F7-E742181CF9DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {C49B50D4-5D63-47E6-82F7-E742181CF9DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {C49B50D4-5D63-47E6-82F7-E742181CF9DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C49B50D4-5D63-47E6-82F7-E742181CF9DE}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {C00828FB-E7D5-4086-BA50-02022594AB73} = {0C7AA298-2957-4D71-A8F1-1C3C7932A1B3}
- {07BCD006-F2F2-4685-8887-E8BEB18745FD} = {C00828FB-E7D5-4086-BA50-02022594AB73}
- {60E37E86-ACA6-4464-9592-B0D8EFB629BD} = {C00828FB-E7D5-4086-BA50-02022594AB73}
- {85B39FCE-6778-497C-A12E-6777C7FE651A} = {C00828FB-E7D5-4086-BA50-02022594AB73}
- {8C973655-DF59-40D8-B206-82344575A8CF} = {C00828FB-E7D5-4086-BA50-02022594AB73}
- {55B9F554-1754-4EF9-B325-B33421D4F6A9} = {C00828FB-E7D5-4086-BA50-02022594AB73}
- {7AC8C076-87E2-48ED-8AB3-C1F737F55DD1} = {C00828FB-E7D5-4086-BA50-02022594AB73}
- {C6F494D3-2C41-46DF-BCAD-F74D3E53CDE1} = {C00828FB-E7D5-4086-BA50-02022594AB73}
- {3531699A-9FF9-4F8C-BEAD-9D114FE8E519} = {C00828FB-E7D5-4086-BA50-02022594AB73}
- {50DE8ABF-B50A-4AAB-A69B-4E727AFDB6B5} = {D58F1DF5-2DFE-40A2-B136-7606D4CDE903}
- {2094F03B-FC73-4B3F-88CB-F7951E22FED5} = {D58F1DF5-2DFE-40A2-B136-7606D4CDE903}
- {554E5BCA-7F88-4E7C-86ED-8B6DE3A3A802} = {D58F1DF5-2DFE-40A2-B136-7606D4CDE903}
- {92E4CAD4-F5B9-4B16-B7BC-4A40DC1E93F1} = {D58F1DF5-2DFE-40A2-B136-7606D4CDE903}
- {DB8CE5AF-1888-4C51-97C3-2188BE50FAF9} = {D58F1DF5-2DFE-40A2-B136-7606D4CDE903}
- {54395254-0383-4932-B2E4-50932DAD7D10} = {D58F1DF5-2DFE-40A2-B136-7606D4CDE903}
- {3E9CCC0A-DAD5-4F32-8EAE-654D67DEE2B9} = {D58F1DF5-2DFE-40A2-B136-7606D4CDE903}
- {8168B7B4-9F6B-4658-A28C-D0F9D10AB93D} = {E7A821D8-85B5-4098-897D-5A814BD8131D}
- {78164C5C-63B9-4FB6-ACC9-6496E236C946} = {0C7AA298-2957-4D71-A8F1-1C3C7932A1B3}
- {93971F1F-F6AC-4F83-8119-21260FCE2828} = {C00828FB-E7D5-4086-BA50-02022594AB73}
- {3B87330F-A303-4413-B653-1C9536C74109} = {78164C5C-63B9-4FB6-ACC9-6496E236C946}
- {D58F1DF5-2DFE-40A2-B136-7606D4CDE903} = {0C7AA298-2957-4D71-A8F1-1C3C7932A1B3}
- {3A4601FE-B091-43A3-AEE6-6440BB37B277} = {78164C5C-63B9-4FB6-ACC9-6496E236C946}
- {454059F7-D087-439A-A724-80BDFE94776F} = {C00828FB-E7D5-4086-BA50-02022594AB73}
- {64E2622A-611D-4056-9497-0B52A91DC59C} = {78164C5C-63B9-4FB6-ACC9-6496E236C946}
- {5714481A-BDF5-4860-9158-3B18D3018EC5} = {42800C56-9473-4B96-BF29-1B0F25C867F4}
- {B5E23AED-3068-4CFE-84B0-3B7725665506} = {42800C56-9473-4B96-BF29-1B0F25C867F4}
- {E5257008-A0AD-473F-91B0-864FC601B84B} = {42800C56-9473-4B96-BF29-1B0F25C867F4}
- {DB425943-CEE6-4FF6-A0EE-233B6ADA3BD7} = {42800C56-9473-4B96-BF29-1B0F25C867F4}
- {25267137-08BE-44A6-9F7E-7783CC8C62E8} = {42800C56-9473-4B96-BF29-1B0F25C867F4}
- {CB6D56DA-539B-4D4F-81CD-D683ADEBFB5F} = {42800C56-9473-4B96-BF29-1B0F25C867F4}
- {097319B9-D062-4A54-8F8C-001C180E2CB3} = {42800C56-9473-4B96-BF29-1B0F25C867F4}
- {737EF17D-477F-4C73-A4CC-0DA6CBD3BB97} = {C00828FB-E7D5-4086-BA50-02022594AB73}
- {0B6AAACE-A1DE-4063-8DA8-E7EBA30186E4} = {C00828FB-E7D5-4086-BA50-02022594AB73}
- {05DCBA6B-480A-4D2F-9855-F66F5B7F3A48} = {C00828FB-E7D5-4086-BA50-02022594AB73}
- {32D4DB5D-74D1-4166-85EA-B2D8F14B8058} = {C00828FB-E7D5-4086-BA50-02022594AB73}
- {C49B50D4-5D63-47E6-82F7-E742181CF9DE} = {C00828FB-E7D5-4086-BA50-02022594AB73}
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {6238659A-7267-49B9-A499-8746BDEED6B8}
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30011.22
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "modules", "modules", "{0C7AA298-2957-4D71-A8F1-1C3C7932A1B3}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "services", "services", "{E7A821D8-85B5-4098-897D-5A814BD8131D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "common", "common", "{C00828FB-E7D5-4086-BA50-02022594AB73}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.RealTime", "modules\common\LINGYUN.Abp.RealTime\LINGYUN.Abp.RealTime.csproj", "{07BCD006-F2F2-4685-8887-E8BEB18745FD}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.RealTime.SignalR", "modules\common\LINGYUN.Abp.RealTime.SignalR\LINGYUN.Abp.RealTime.SignalR.csproj", "{60E37E86-ACA6-4464-9592-B0D8EFB629BD}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AspNetCore.SignalR.JwtToken", "modules\common\LINGYUN.Abp.AspNetCore.SignalR\LINGYUN.Abp.AspNetCore.SignalR.JwtToken.csproj", "{85B39FCE-6778-497C-A12E-6777C7FE651A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json", "modules\common\LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json\LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json.csproj", "{8C973655-DF59-40D8-B206-82344575A8CF}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IM", "modules\common\LINGYUN.Abp.IM\LINGYUN.Abp.IM.csproj", "{55B9F554-1754-4EF9-B325-B33421D4F6A9}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IM.SignalR", "modules\common\LINGYUN.Abp.IM.SignalR\LINGYUN.Abp.IM.SignalR.csproj", "{7AC8C076-87E2-48ED-8AB3-C1F737F55DD1}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications", "modules\common\LINGYUN.Abp.Notifications\LINGYUN.Abp.Notifications.csproj", "{C6F494D3-2C41-46DF-BCAD-F74D3E53CDE1}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.SignalR", "modules\common\LINGYUN.Abp.Notifications.SignalR\LINGYUN.Abp.Notifications.SignalR.csproj", "{3531699A-9FF9-4F8C-BEAD-9D114FE8E519}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.Domain.Shared", "modules\message\LINGYUN.Abp.MessageService.Domain.Shared\LINGYUN.Abp.MessageService.Domain.Shared.csproj", "{50DE8ABF-B50A-4AAB-A69B-4E727AFDB6B5}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.Domain", "modules\message\LINGYUN.Abp.MessageService.Domain\LINGYUN.Abp.MessageService.Domain.csproj", "{2094F03B-FC73-4B3F-88CB-F7951E22FED5}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.EntityFrameworkCore", "modules\message\LINGYUN.Abp.MessageService.EntityFrameworkCore\LINGYUN.Abp.MessageService.EntityFrameworkCore.csproj", "{554E5BCA-7F88-4E7C-86ED-8B6DE3A3A802}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.Application.Contracts", "modules\message\LINGYUN.Abp.MessageService.Application.Contracts\LINGYUN.Abp.MessageService.Application.Contracts.csproj", "{92E4CAD4-F5B9-4B16-B7BC-4A40DC1E93F1}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.Application", "modules\message\LINGYUN.Abp.MessageService.Application\LINGYUN.Abp.MessageService.Application.csproj", "{DB8CE5AF-1888-4C51-97C3-2188BE50FAF9}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.HttpApi", "modules\message\LINGYUN.Abp.MessageService.HttpApi\LINGYUN.Abp.MessageService.HttpApi.csproj", "{54395254-0383-4932-B2E4-50932DAD7D10}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.HttpApi.Client", "modules\message\LINGYUN.Abp.MessageService.HttpApi.Client\LINGYUN.Abp.MessageService.HttpApi.Client.csproj", "{3E9CCC0A-DAD5-4F32-8EAE-654D67DEE2B9}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.HttpApi.Host", "services\messages\LINGYUN.Abp.MessageService.HttpApi.Host\LINGYUN.Abp.MessageService.HttpApi.Host.csproj", "{8168B7B4-9F6B-4658-A28C-D0F9D10AB93D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wechat", "wechat", "{78164C5C-63B9-4FB6-ACC9-6496E236C946}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Features.LimitValidation", "modules\common\LINGYUN.Abp.Features.LimitValidation\LINGYUN.Abp.Features.LimitValidation.csproj", "{93971F1F-F6AC-4F83-8119-21260FCE2828}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat", "modules\wechat\LINGYUN.Abp.WeChat\LINGYUN.Abp.WeChat.csproj", "{3B87330F-A303-4413-B653-1C9536C74109}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "message", "message", "{D58F1DF5-2DFE-40A2-B136-7606D4CDE903}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat.MiniProgram", "modules\wechat\LINGYUN.Abp.WeChat.MiniProgram\LINGYUN.Abp.WeChat.MiniProgram.csproj", "{3A4601FE-B091-43A3-AEE6-6440BB37B277}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.Sms", "modules\common\LINGYUN.Abp.Notifications.Sms\LINGYUN.Abp.Notifications.Sms.csproj", "{454059F7-D087-439A-A724-80BDFE94776F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.WeChat.MiniProgram", "modules\wechat\LINGYUN.Abp.Notifications.WeChat.MiniProgram\LINGYUN.Abp.Notifications.WeChat.MiniProgram.csproj", "{64E2622A-611D-4056-9497-0B52A91DC59C}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{42800C56-9473-4B96-BF29-1B0F25C867F4}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.Sms.Tests", "tests\LINGYUN.Abp.Notifications.Sms.Tests\LINGYUN.Abp.Notifications.Sms.Tests.csproj", "{5714481A-BDF5-4860-9158-3B18D3018EC5}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.TestsBase", "tests\LINGYUN.Abp.TestBase\LINGYUN.Abp.TestsBase.csproj", "{B5E23AED-3068-4CFE-84B0-3B7725665506}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.Tests", "tests\LINGYUN.Abp.Notifications.Tests\LINGYUN.Abp.Notifications.Tests.csproj", "{E5257008-A0AD-473F-91B0-864FC601B84B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests", "tests\LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests\LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests.csproj", "{DB425943-CEE6-4FF6-A0EE-233B6ADA3BD7}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.EntityFrameworkCore.Tests", "tests\LINGYUN.Abp.EntityFrameworkCore.Tests\LINGYUN.Abp.EntityFrameworkCore.Tests.csproj", "{25267137-08BE-44A6-9F7E-7783CC8C62E8}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.EntityFrameworkCore.Tests", "tests\LINGYUN.Abp.MessageService.EntityFrameworkCore.Tests\LINGYUN.Abp.MessageService.EntityFrameworkCore.Tests.csproj", "{CB6D56DA-539B-4D4F-81CD-D683ADEBFB5F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.Domain.Tests", "tests\LINGYUN.Abp.MessageService.Domain.Tests\LINGYUN.Abp.MessageService.Domain.Tests.csproj", "{097319B9-D062-4A54-8F8C-001C180E2CB3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.BackgroundJobs.Hangfire", "modules\common\LINGYUN.Abp.BackgroundJobs.Hangfire\LINGYUN.Abp.BackgroundJobs.Hangfire.csproj", "{737EF17D-477F-4C73-A4CC-0DA6CBD3BB97}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Hangfire.Storage.MySql", "modules\common\LINGYUN.Abp.Hangfire.MySqlStorage\LINGYUN.Abp.Hangfire.Storage.MySql.csproj", "{0B6AAACE-A1DE-4063-8DA8-E7EBA30186E4}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Hangfire.Dashboard", "modules\common\LINGYUN.Abp.Hangfire.Dashboard\LINGYUN.Abp.Hangfire.Dashboard.csproj", "{05DCBA6B-480A-4D2F-9855-F66F5B7F3A48}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.BackgroundWorkers.Hangfire", "modules\common\LINGYUN.Abp.BackgroundWorkers.Hangfire\LINGYUN.Abp.BackgroundWorkers.Hangfire.csproj", "{32D4DB5D-74D1-4166-85EA-B2D8F14B8058}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.EventBus.CAP", "modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.csproj", "{C49B50D4-5D63-47E6-82F7-E742181CF9DE}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.WeChat", "modules\wechat\LINGYUN.Abp.Identity.WeChat\LINGYUN.Abp.Identity.WeChat.csproj", "{DC71289C-18A7-4E4B-A653-E66941EB19AE}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {07BCD006-F2F2-4685-8887-E8BEB18745FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {07BCD006-F2F2-4685-8887-E8BEB18745FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {07BCD006-F2F2-4685-8887-E8BEB18745FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {07BCD006-F2F2-4685-8887-E8BEB18745FD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {60E37E86-ACA6-4464-9592-B0D8EFB629BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {60E37E86-ACA6-4464-9592-B0D8EFB629BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {60E37E86-ACA6-4464-9592-B0D8EFB629BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {60E37E86-ACA6-4464-9592-B0D8EFB629BD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {85B39FCE-6778-497C-A12E-6777C7FE651A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {85B39FCE-6778-497C-A12E-6777C7FE651A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {85B39FCE-6778-497C-A12E-6777C7FE651A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {85B39FCE-6778-497C-A12E-6777C7FE651A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8C973655-DF59-40D8-B206-82344575A8CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8C973655-DF59-40D8-B206-82344575A8CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8C973655-DF59-40D8-B206-82344575A8CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8C973655-DF59-40D8-B206-82344575A8CF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {55B9F554-1754-4EF9-B325-B33421D4F6A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {55B9F554-1754-4EF9-B325-B33421D4F6A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {55B9F554-1754-4EF9-B325-B33421D4F6A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {55B9F554-1754-4EF9-B325-B33421D4F6A9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7AC8C076-87E2-48ED-8AB3-C1F737F55DD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7AC8C076-87E2-48ED-8AB3-C1F737F55DD1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7AC8C076-87E2-48ED-8AB3-C1F737F55DD1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7AC8C076-87E2-48ED-8AB3-C1F737F55DD1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C6F494D3-2C41-46DF-BCAD-F74D3E53CDE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C6F494D3-2C41-46DF-BCAD-F74D3E53CDE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C6F494D3-2C41-46DF-BCAD-F74D3E53CDE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C6F494D3-2C41-46DF-BCAD-F74D3E53CDE1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3531699A-9FF9-4F8C-BEAD-9D114FE8E519}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3531699A-9FF9-4F8C-BEAD-9D114FE8E519}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3531699A-9FF9-4F8C-BEAD-9D114FE8E519}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3531699A-9FF9-4F8C-BEAD-9D114FE8E519}.Release|Any CPU.Build.0 = Release|Any CPU
+ {50DE8ABF-B50A-4AAB-A69B-4E727AFDB6B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {50DE8ABF-B50A-4AAB-A69B-4E727AFDB6B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {50DE8ABF-B50A-4AAB-A69B-4E727AFDB6B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {50DE8ABF-B50A-4AAB-A69B-4E727AFDB6B5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2094F03B-FC73-4B3F-88CB-F7951E22FED5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2094F03B-FC73-4B3F-88CB-F7951E22FED5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2094F03B-FC73-4B3F-88CB-F7951E22FED5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2094F03B-FC73-4B3F-88CB-F7951E22FED5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {554E5BCA-7F88-4E7C-86ED-8B6DE3A3A802}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {554E5BCA-7F88-4E7C-86ED-8B6DE3A3A802}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {554E5BCA-7F88-4E7C-86ED-8B6DE3A3A802}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {554E5BCA-7F88-4E7C-86ED-8B6DE3A3A802}.Release|Any CPU.Build.0 = Release|Any CPU
+ {92E4CAD4-F5B9-4B16-B7BC-4A40DC1E93F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {92E4CAD4-F5B9-4B16-B7BC-4A40DC1E93F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {92E4CAD4-F5B9-4B16-B7BC-4A40DC1E93F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {92E4CAD4-F5B9-4B16-B7BC-4A40DC1E93F1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DB8CE5AF-1888-4C51-97C3-2188BE50FAF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DB8CE5AF-1888-4C51-97C3-2188BE50FAF9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DB8CE5AF-1888-4C51-97C3-2188BE50FAF9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DB8CE5AF-1888-4C51-97C3-2188BE50FAF9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {54395254-0383-4932-B2E4-50932DAD7D10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {54395254-0383-4932-B2E4-50932DAD7D10}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {54395254-0383-4932-B2E4-50932DAD7D10}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {54395254-0383-4932-B2E4-50932DAD7D10}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3E9CCC0A-DAD5-4F32-8EAE-654D67DEE2B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3E9CCC0A-DAD5-4F32-8EAE-654D67DEE2B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3E9CCC0A-DAD5-4F32-8EAE-654D67DEE2B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3E9CCC0A-DAD5-4F32-8EAE-654D67DEE2B9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8168B7B4-9F6B-4658-A28C-D0F9D10AB93D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8168B7B4-9F6B-4658-A28C-D0F9D10AB93D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8168B7B4-9F6B-4658-A28C-D0F9D10AB93D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8168B7B4-9F6B-4658-A28C-D0F9D10AB93D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {93971F1F-F6AC-4F83-8119-21260FCE2828}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {93971F1F-F6AC-4F83-8119-21260FCE2828}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {93971F1F-F6AC-4F83-8119-21260FCE2828}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {93971F1F-F6AC-4F83-8119-21260FCE2828}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3B87330F-A303-4413-B653-1C9536C74109}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3B87330F-A303-4413-B653-1C9536C74109}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3B87330F-A303-4413-B653-1C9536C74109}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3B87330F-A303-4413-B653-1C9536C74109}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3A4601FE-B091-43A3-AEE6-6440BB37B277}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3A4601FE-B091-43A3-AEE6-6440BB37B277}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3A4601FE-B091-43A3-AEE6-6440BB37B277}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3A4601FE-B091-43A3-AEE6-6440BB37B277}.Release|Any CPU.Build.0 = Release|Any CPU
+ {454059F7-D087-439A-A724-80BDFE94776F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {454059F7-D087-439A-A724-80BDFE94776F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {454059F7-D087-439A-A724-80BDFE94776F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {454059F7-D087-439A-A724-80BDFE94776F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {64E2622A-611D-4056-9497-0B52A91DC59C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {64E2622A-611D-4056-9497-0B52A91DC59C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {64E2622A-611D-4056-9497-0B52A91DC59C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {64E2622A-611D-4056-9497-0B52A91DC59C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5714481A-BDF5-4860-9158-3B18D3018EC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5714481A-BDF5-4860-9158-3B18D3018EC5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5714481A-BDF5-4860-9158-3B18D3018EC5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5714481A-BDF5-4860-9158-3B18D3018EC5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B5E23AED-3068-4CFE-84B0-3B7725665506}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B5E23AED-3068-4CFE-84B0-3B7725665506}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B5E23AED-3068-4CFE-84B0-3B7725665506}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B5E23AED-3068-4CFE-84B0-3B7725665506}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E5257008-A0AD-473F-91B0-864FC601B84B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E5257008-A0AD-473F-91B0-864FC601B84B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E5257008-A0AD-473F-91B0-864FC601B84B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E5257008-A0AD-473F-91B0-864FC601B84B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DB425943-CEE6-4FF6-A0EE-233B6ADA3BD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DB425943-CEE6-4FF6-A0EE-233B6ADA3BD7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DB425943-CEE6-4FF6-A0EE-233B6ADA3BD7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DB425943-CEE6-4FF6-A0EE-233B6ADA3BD7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {25267137-08BE-44A6-9F7E-7783CC8C62E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {25267137-08BE-44A6-9F7E-7783CC8C62E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {25267137-08BE-44A6-9F7E-7783CC8C62E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {25267137-08BE-44A6-9F7E-7783CC8C62E8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CB6D56DA-539B-4D4F-81CD-D683ADEBFB5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CB6D56DA-539B-4D4F-81CD-D683ADEBFB5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CB6D56DA-539B-4D4F-81CD-D683ADEBFB5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CB6D56DA-539B-4D4F-81CD-D683ADEBFB5F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {097319B9-D062-4A54-8F8C-001C180E2CB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {097319B9-D062-4A54-8F8C-001C180E2CB3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {097319B9-D062-4A54-8F8C-001C180E2CB3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {097319B9-D062-4A54-8F8C-001C180E2CB3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {737EF17D-477F-4C73-A4CC-0DA6CBD3BB97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {737EF17D-477F-4C73-A4CC-0DA6CBD3BB97}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {737EF17D-477F-4C73-A4CC-0DA6CBD3BB97}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {737EF17D-477F-4C73-A4CC-0DA6CBD3BB97}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0B6AAACE-A1DE-4063-8DA8-E7EBA30186E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0B6AAACE-A1DE-4063-8DA8-E7EBA30186E4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0B6AAACE-A1DE-4063-8DA8-E7EBA30186E4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0B6AAACE-A1DE-4063-8DA8-E7EBA30186E4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {05DCBA6B-480A-4D2F-9855-F66F5B7F3A48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {05DCBA6B-480A-4D2F-9855-F66F5B7F3A48}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {05DCBA6B-480A-4D2F-9855-F66F5B7F3A48}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {05DCBA6B-480A-4D2F-9855-F66F5B7F3A48}.Release|Any CPU.Build.0 = Release|Any CPU
+ {32D4DB5D-74D1-4166-85EA-B2D8F14B8058}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {32D4DB5D-74D1-4166-85EA-B2D8F14B8058}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {32D4DB5D-74D1-4166-85EA-B2D8F14B8058}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {32D4DB5D-74D1-4166-85EA-B2D8F14B8058}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C49B50D4-5D63-47E6-82F7-E742181CF9DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C49B50D4-5D63-47E6-82F7-E742181CF9DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C49B50D4-5D63-47E6-82F7-E742181CF9DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C49B50D4-5D63-47E6-82F7-E742181CF9DE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DC71289C-18A7-4E4B-A653-E66941EB19AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DC71289C-18A7-4E4B-A653-E66941EB19AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DC71289C-18A7-4E4B-A653-E66941EB19AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DC71289C-18A7-4E4B-A653-E66941EB19AE}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {C00828FB-E7D5-4086-BA50-02022594AB73} = {0C7AA298-2957-4D71-A8F1-1C3C7932A1B3}
+ {07BCD006-F2F2-4685-8887-E8BEB18745FD} = {C00828FB-E7D5-4086-BA50-02022594AB73}
+ {60E37E86-ACA6-4464-9592-B0D8EFB629BD} = {C00828FB-E7D5-4086-BA50-02022594AB73}
+ {85B39FCE-6778-497C-A12E-6777C7FE651A} = {C00828FB-E7D5-4086-BA50-02022594AB73}
+ {8C973655-DF59-40D8-B206-82344575A8CF} = {C00828FB-E7D5-4086-BA50-02022594AB73}
+ {55B9F554-1754-4EF9-B325-B33421D4F6A9} = {C00828FB-E7D5-4086-BA50-02022594AB73}
+ {7AC8C076-87E2-48ED-8AB3-C1F737F55DD1} = {C00828FB-E7D5-4086-BA50-02022594AB73}
+ {C6F494D3-2C41-46DF-BCAD-F74D3E53CDE1} = {C00828FB-E7D5-4086-BA50-02022594AB73}
+ {3531699A-9FF9-4F8C-BEAD-9D114FE8E519} = {C00828FB-E7D5-4086-BA50-02022594AB73}
+ {50DE8ABF-B50A-4AAB-A69B-4E727AFDB6B5} = {D58F1DF5-2DFE-40A2-B136-7606D4CDE903}
+ {2094F03B-FC73-4B3F-88CB-F7951E22FED5} = {D58F1DF5-2DFE-40A2-B136-7606D4CDE903}
+ {554E5BCA-7F88-4E7C-86ED-8B6DE3A3A802} = {D58F1DF5-2DFE-40A2-B136-7606D4CDE903}
+ {92E4CAD4-F5B9-4B16-B7BC-4A40DC1E93F1} = {D58F1DF5-2DFE-40A2-B136-7606D4CDE903}
+ {DB8CE5AF-1888-4C51-97C3-2188BE50FAF9} = {D58F1DF5-2DFE-40A2-B136-7606D4CDE903}
+ {54395254-0383-4932-B2E4-50932DAD7D10} = {D58F1DF5-2DFE-40A2-B136-7606D4CDE903}
+ {3E9CCC0A-DAD5-4F32-8EAE-654D67DEE2B9} = {D58F1DF5-2DFE-40A2-B136-7606D4CDE903}
+ {8168B7B4-9F6B-4658-A28C-D0F9D10AB93D} = {E7A821D8-85B5-4098-897D-5A814BD8131D}
+ {78164C5C-63B9-4FB6-ACC9-6496E236C946} = {0C7AA298-2957-4D71-A8F1-1C3C7932A1B3}
+ {93971F1F-F6AC-4F83-8119-21260FCE2828} = {C00828FB-E7D5-4086-BA50-02022594AB73}
+ {3B87330F-A303-4413-B653-1C9536C74109} = {78164C5C-63B9-4FB6-ACC9-6496E236C946}
+ {D58F1DF5-2DFE-40A2-B136-7606D4CDE903} = {0C7AA298-2957-4D71-A8F1-1C3C7932A1B3}
+ {3A4601FE-B091-43A3-AEE6-6440BB37B277} = {78164C5C-63B9-4FB6-ACC9-6496E236C946}
+ {454059F7-D087-439A-A724-80BDFE94776F} = {C00828FB-E7D5-4086-BA50-02022594AB73}
+ {64E2622A-611D-4056-9497-0B52A91DC59C} = {78164C5C-63B9-4FB6-ACC9-6496E236C946}
+ {5714481A-BDF5-4860-9158-3B18D3018EC5} = {42800C56-9473-4B96-BF29-1B0F25C867F4}
+ {B5E23AED-3068-4CFE-84B0-3B7725665506} = {42800C56-9473-4B96-BF29-1B0F25C867F4}
+ {E5257008-A0AD-473F-91B0-864FC601B84B} = {42800C56-9473-4B96-BF29-1B0F25C867F4}
+ {DB425943-CEE6-4FF6-A0EE-233B6ADA3BD7} = {42800C56-9473-4B96-BF29-1B0F25C867F4}
+ {25267137-08BE-44A6-9F7E-7783CC8C62E8} = {42800C56-9473-4B96-BF29-1B0F25C867F4}
+ {CB6D56DA-539B-4D4F-81CD-D683ADEBFB5F} = {42800C56-9473-4B96-BF29-1B0F25C867F4}
+ {097319B9-D062-4A54-8F8C-001C180E2CB3} = {42800C56-9473-4B96-BF29-1B0F25C867F4}
+ {737EF17D-477F-4C73-A4CC-0DA6CBD3BB97} = {C00828FB-E7D5-4086-BA50-02022594AB73}
+ {0B6AAACE-A1DE-4063-8DA8-E7EBA30186E4} = {C00828FB-E7D5-4086-BA50-02022594AB73}
+ {05DCBA6B-480A-4D2F-9855-F66F5B7F3A48} = {C00828FB-E7D5-4086-BA50-02022594AB73}
+ {32D4DB5D-74D1-4166-85EA-B2D8F14B8058} = {C00828FB-E7D5-4086-BA50-02022594AB73}
+ {C49B50D4-5D63-47E6-82F7-E742181CF9DE} = {C00828FB-E7D5-4086-BA50-02022594AB73}
+ {DC71289C-18A7-4E4B-A653-E66941EB19AE} = {78164C5C-63B9-4FB6-ACC9-6496E236C946}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {6238659A-7267-49B9-A499-8746BDEED6B8}
+ EndGlobalSection
+EndGlobal
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN.Abp.IdentityServer.WeChat.csproj b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN.Abp.IdentityServer.WeChat.csproj
index 6fa4aa8e4..3f7dff199 100644
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN.Abp.IdentityServer.WeChat.csproj
+++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN.Abp.IdentityServer.WeChat.csproj
@@ -17,6 +17,7 @@
+
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/AbpIdentityServerWeChatModule.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/AbpIdentityServerWeChatModule.cs
index 8ab734a42..cb4621c31 100644
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/AbpIdentityServerWeChatModule.cs
+++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/AbpIdentityServerWeChatModule.cs
@@ -1,54 +1,56 @@
-using LINGYUN.Abp.IdentityServer.WeChat.MiniProgram;
-using LINGYUN.Abp.IdentityServer.WeChat.Official;
-using LINGYUN.Abp.WeChat.MiniProgram;
-using LINGYUN.Abp.WeChat.Official;
-using Microsoft.AspNetCore.Authentication;
-using Microsoft.Extensions.DependencyInjection;
-using Volo.Abp.IdentityServer;
-using Volo.Abp.IdentityServer.Localization;
-using Volo.Abp.Localization;
-using Volo.Abp.Modularity;
-using Volo.Abp.VirtualFileSystem;
-
-namespace LINGYUN.Abp.IdentityServer.WeChat
-{
- [DependsOn(
- typeof(AbpWeChatOfficialModule),
- typeof(AbpWeChatMiniProgramModule),
- typeof(AbpIdentityServerDomainModule))]
- public class AbpIdentityServerWeChatModule : AbpModule
- {
- public override void PreConfigureServices(ServiceConfigurationContext context)
- {
- var configuration = context.Services.GetConfiguration();
-
- PreConfigure(builder =>
- {
- builder.AddProfileService();
-
- // TODO: 两个类型不通用配置项,不然只需要一个
- builder.AddExtensionGrantValidator();
- builder.AddExtensionGrantValidator();
- });
- }
-
- public override void ConfigureServices(ServiceConfigurationContext context)
- {
- Configure(options =>
- {
- options.FileSets.AddEmbedded();
- });
-
- Configure(options =>
- {
- options.Resources
- .Get()
- .AddVirtualJson("/LINGYUN/Abp/IdentityServer/WeChat/Localization");
- });
-
- context.Services
- .AddAuthentication()
- .AddWeChat();
- }
- }
-}
+using LINGYUN.Abp.Identity.WeChat;
+using LINGYUN.Abp.IdentityServer.WeChat.MiniProgram;
+using LINGYUN.Abp.IdentityServer.WeChat.Official;
+using LINGYUN.Abp.WeChat.MiniProgram;
+using LINGYUN.Abp.WeChat.Official;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.IdentityServer;
+using Volo.Abp.IdentityServer.Localization;
+using Volo.Abp.Localization;
+using Volo.Abp.Modularity;
+using Volo.Abp.VirtualFileSystem;
+
+namespace LINGYUN.Abp.IdentityServer.WeChat
+{
+ [DependsOn(
+ typeof(AbpWeChatOfficialModule),
+ typeof(AbpWeChatMiniProgramModule),
+ typeof(AbpIdentityWeChatModule),
+ typeof(AbpIdentityServerDomainModule))]
+ public class AbpIdentityServerWeChatModule : AbpModule
+ {
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ var configuration = context.Services.GetConfiguration();
+
+ PreConfigure(builder =>
+ {
+ builder.AddProfileService();
+
+ // TODO: 两个类型不通用配置项,不然只需要一个
+ builder.AddExtensionGrantValidator();
+ builder.AddExtensionGrantValidator();
+ });
+ }
+
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options =>
+ {
+ options.FileSets.AddEmbedded();
+ });
+
+ Configure(options =>
+ {
+ options.Resources
+ .Get()
+ .AddVirtualJson("/LINGYUN/Abp/IdentityServer/WeChat/Localization");
+ });
+
+ context.Services
+ .AddAuthentication()
+ .AddWeChat();
+ }
+ }
+}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/MiniProgram/WeChatMiniProgramGrantValidator.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/MiniProgram/WeChatMiniProgramGrantValidator.cs
index 3ecd61730..7a050e70a 100644
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/MiniProgram/WeChatMiniProgramGrantValidator.cs
+++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/MiniProgram/WeChatMiniProgramGrantValidator.cs
@@ -1,47 +1,47 @@
-using IdentityServer4.Services;
-using LINGYUN.Abp.WeChat.MiniProgram;
-using LINGYUN.Abp.WeChat.OpenId;
-using Microsoft.AspNetCore.Identity;
-using Microsoft.Extensions.Localization;
-using Microsoft.Extensions.Options;
-using System.Threading.Tasks;
-using Volo.Abp.Identity;
-using Volo.Abp.IdentityServer.Localization;
-using IdentityUser = Volo.Abp.Identity.IdentityUser;
-
-namespace LINGYUN.Abp.IdentityServer.WeChat.MiniProgram
-{
- ///
- /// 对于小程序绑定用户的扩展授权验证器
- ///
- public class WeChatMiniProgramGrantValidator : WeChatGrantValidator
- {
- public override string GrantType => AbpWeChatMiniProgramConsts.GrantType;
-
- public override string LoginProviderKey => AbpWeChatMiniProgramConsts.ProviderKey;
-
- public override string AuthenticationMethod => AbpWeChatMiniProgramConsts.AuthenticationMethod;
-
- protected AbpWeChatMiniProgramOptionsFactory MiniProgramOptionsFactory { get; }
-
- public WeChatMiniProgramGrantValidator(
- IEventService eventService,
- IWeChatOpenIdFinder weChatOpenIdFinder,
- UserManager userManager,
- IIdentityUserRepository userRepository,
- IStringLocalizer identityLocalizer,
- IStringLocalizer identityServerLocalizer,
- AbpWeChatMiniProgramOptionsFactory miniProgramOptionsFactory)
- : base(eventService, weChatOpenIdFinder, userManager, userRepository, identityLocalizer, identityServerLocalizer)
- {
- MiniProgramOptionsFactory = miniProgramOptionsFactory;
- }
-
- protected override async Task FindOpenIdAsync(string code)
- {
- var options = await MiniProgramOptionsFactory.CreateAsync();
-
- return await WeChatOpenIdFinder.FindAsync(code, options.AppId, options.AppSecret);
- }
- }
-}
+using IdentityServer4.Services;
+using LINGYUN.Abp.WeChat.MiniProgram;
+using LINGYUN.Abp.WeChat.OpenId;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.Extensions.Localization;
+using Microsoft.Extensions.Options;
+using System.Threading.Tasks;
+using Volo.Abp.Identity;
+using Volo.Abp.IdentityServer.Localization;
+using IdentityUser = Volo.Abp.Identity.IdentityUser;
+
+namespace LINGYUN.Abp.IdentityServer.WeChat.MiniProgram
+{
+ ///
+ /// 对于小程序绑定用户的扩展授权验证器
+ ///
+ public class WeChatMiniProgramGrantValidator : WeChatGrantValidator
+ {
+ public override string GrantType => AbpWeChatMiniProgramConsts.GrantType;
+
+ public override string LoginProvider => AbpWeChatMiniProgramConsts.ProviderName;
+
+ public override string AuthenticationMethod => AbpWeChatMiniProgramConsts.AuthenticationMethod;
+
+ protected AbpWeChatMiniProgramOptionsFactory MiniProgramOptionsFactory { get; }
+
+ public WeChatMiniProgramGrantValidator(
+ IEventService eventService,
+ IWeChatOpenIdFinder weChatOpenIdFinder,
+ UserManager userManager,
+ IIdentityUserRepository userRepository,
+ IStringLocalizer identityLocalizer,
+ IStringLocalizer identityServerLocalizer,
+ AbpWeChatMiniProgramOptionsFactory miniProgramOptionsFactory)
+ : base(eventService, weChatOpenIdFinder, userManager, userRepository, identityLocalizer, identityServerLocalizer)
+ {
+ MiniProgramOptionsFactory = miniProgramOptionsFactory;
+ }
+
+ protected override async Task FindOpenIdAsync(string code)
+ {
+ var options = await MiniProgramOptionsFactory.CreateAsync();
+
+ return await WeChatOpenIdFinder.FindAsync(code, options.AppId, options.AppSecret);
+ }
+ }
+}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialGrantValidator.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialGrantValidator.cs
index dc43b6e78..660f958c7 100644
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialGrantValidator.cs
+++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialGrantValidator.cs
@@ -1,46 +1,46 @@
-using IdentityServer4.Services;
-using LINGYUN.Abp.WeChat.Official;
-using LINGYUN.Abp.WeChat.OpenId;
-using Microsoft.AspNetCore.Identity;
-using Microsoft.Extensions.Localization;
-using System.Threading.Tasks;
-using Volo.Abp.Identity;
-using Volo.Abp.IdentityServer.Localization;
-using IdentityUser = Volo.Abp.Identity.IdentityUser;
-
-namespace LINGYUN.Abp.IdentityServer.WeChat.Official
-{
- ///
- /// 对于公众平台绑定用户的扩展授权验证器
- ///
- public class WeChatOfficialGrantValidator : WeChatGrantValidator
- {
- public override string GrantType => AbpWeChatOfficialConsts.GrantType;
-
- public override string LoginProviderKey => AbpWeChatOfficialConsts.ProviderKey;
-
- public override string AuthenticationMethod => AbpWeChatOfficialConsts.AuthenticationMethod;
-
- protected AbpWeChatOfficialOptionsFactory WeChatOfficialOptionsFactory { get; }
-
- public WeChatOfficialGrantValidator(
- IEventService eventService,
- IWeChatOpenIdFinder weChatOpenIdFinder,
- UserManager userManager,
- IIdentityUserRepository userRepository,
- IStringLocalizer identityLocalizer,
- IStringLocalizer identityServerLocalizer,
- AbpWeChatOfficialOptionsFactory weChatOfficialOptionsFactory)
- : base(eventService, weChatOpenIdFinder, userManager, userRepository, identityLocalizer, identityServerLocalizer)
- {
- WeChatOfficialOptionsFactory = weChatOfficialOptionsFactory;
- }
-
- protected override async Task FindOpenIdAsync(string code)
- {
- var options = await WeChatOfficialOptionsFactory.CreateAsync();
-
- return await WeChatOpenIdFinder.FindAsync(code, options.AppId, options.AppSecret);
- }
- }
-}
+using IdentityServer4.Services;
+using LINGYUN.Abp.WeChat.Official;
+using LINGYUN.Abp.WeChat.OpenId;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.Extensions.Localization;
+using System.Threading.Tasks;
+using Volo.Abp.Identity;
+using Volo.Abp.IdentityServer.Localization;
+using IdentityUser = Volo.Abp.Identity.IdentityUser;
+
+namespace LINGYUN.Abp.IdentityServer.WeChat.Official
+{
+ ///
+ /// 对于公众平台绑定用户的扩展授权验证器
+ ///
+ public class WeChatOfficialGrantValidator : WeChatGrantValidator
+ {
+ public override string GrantType => AbpWeChatOfficialConsts.GrantType;
+
+ public override string LoginProvider => AbpWeChatOfficialConsts.ProviderName;
+
+ public override string AuthenticationMethod => AbpWeChatOfficialConsts.AuthenticationMethod;
+
+ protected AbpWeChatOfficialOptionsFactory WeChatOfficialOptionsFactory { get; }
+
+ public WeChatOfficialGrantValidator(
+ IEventService eventService,
+ IWeChatOpenIdFinder weChatOpenIdFinder,
+ UserManager userManager,
+ IIdentityUserRepository userRepository,
+ IStringLocalizer identityLocalizer,
+ IStringLocalizer identityServerLocalizer,
+ AbpWeChatOfficialOptionsFactory weChatOfficialOptionsFactory)
+ : base(eventService, weChatOpenIdFinder, userManager, userRepository, identityLocalizer, identityServerLocalizer)
+ {
+ WeChatOfficialOptionsFactory = weChatOfficialOptionsFactory;
+ }
+
+ protected override async Task FindOpenIdAsync(string code)
+ {
+ var options = await WeChatOfficialOptionsFactory.CreateAsync();
+
+ return await WeChatOpenIdFinder.FindAsync(code, options.AppId, options.AppSecret);
+ }
+ }
+}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialOAuthConsts.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialOAuthConsts.cs
index bb632a84d..d4c3bb108 100644
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialOAuthConsts.cs
+++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialOAuthConsts.cs
@@ -1,71 +1,71 @@
-using LINGYUN.Abp.WeChat;
-using LINGYUN.Abp.WeChat.Official;
-
-namespace LINGYUN.Abp.IdentityServer.WeChat.Official
-{
- ///
- /// 与微信公众号认证相关的静态(可变)常量
- ///
- public static class WeChatOfficialOAuthConsts
- {
- ///
- /// 微信个人信息标识
- ///
- public static string ProfileKey { get; set; } = "wechat.profile";
- ///
- /// 微信提供者标识
- ///
- public static string ProviderKey => AbpWeChatOfficialConsts.ProviderKey;
- ///
- /// 微信提供者显示名称
- ///
- public static string DisplayName => AbpWeChatGlobalConsts.DisplayName;
- ///
- /// 回调地址
- ///
- public static string CallbackPath { get; set; } = "/signin-wechat";
-
- ///
- /// 微信客户端外的网页登录
- ///
- public const string QrConnectEndpoint = "https://open.weixin.qq.com/connect/qrconnect";
-
- ///
- /// 微信客户端内的网页登录
- ///
- public const string AuthorizationEndpoint = "https://open.weixin.qq.com/connect/oauth2/authorize";
-
- ///
- /// 用户允许授权后通过返回的code换取access_token地址
- ///
- public const string TokenEndpoint = "https://api.weixin.qq.com/sns/oauth2/access_token";
-
- ///
- /// 使用access_token获取用户个人信息地址
- ///
- public const string UserInformationEndpoint = "https://api.weixin.qq.com/sns/userinfo";
- ///
- /// 弹出授权页面,可通过openid拿到昵称、性别、所在地。
- /// 并且, 即使在未关注的情况下,只要用户授权,也能获取其信息
- ///
- ///
- /// 详询:
- ///
- ///
- /// 以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。
- /// 但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息
- ///
- public const string UserInfoScope = "snsapi_userinfo";
- ///
- /// 不弹出授权页面,直接跳转,只能获取用户openid
- ///
- ///
- /// 详询:
- ///
- ///
- /// 以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。
- /// 用户感知的就是直接进入了回调页(往往是业务页面)
- ///
- public const string LoginScope = "snsapi_login";
- }
-}
+using LINGYUN.Abp.WeChat;
+using LINGYUN.Abp.WeChat.Official;
+
+namespace LINGYUN.Abp.IdentityServer.WeChat.Official
+{
+ ///
+ /// 与微信公众号认证相关的静态(可变)常量
+ ///
+ public static class WeChatOfficialOAuthConsts
+ {
+ ///
+ /// 微信个人信息标识
+ ///
+ public static string ProfileKey { get; set; } = "wechat.profile";
+ ///
+ /// 微信提供者标识
+ ///
+ public static string ProviderKey => AbpWeChatOfficialConsts.ProviderName;
+ ///
+ /// 微信提供者显示名称
+ ///
+ public static string DisplayName => AbpWeChatGlobalConsts.DisplayName;
+ ///
+ /// 回调地址
+ ///
+ public static string CallbackPath { get; set; } = "/signin-wechat";
+
+ ///
+ /// 微信客户端外的网页登录
+ ///
+ public const string QrConnectEndpoint = "https://open.weixin.qq.com/connect/qrconnect";
+
+ ///
+ /// 微信客户端内的网页登录
+ ///
+ public const string AuthorizationEndpoint = "https://open.weixin.qq.com/connect/oauth2/authorize";
+
+ ///
+ /// 用户允许授权后通过返回的code换取access_token地址
+ ///
+ public const string TokenEndpoint = "https://api.weixin.qq.com/sns/oauth2/access_token";
+
+ ///
+ /// 使用access_token获取用户个人信息地址
+ ///
+ public const string UserInformationEndpoint = "https://api.weixin.qq.com/sns/userinfo";
+ ///
+ /// 弹出授权页面,可通过openid拿到昵称、性别、所在地。
+ /// 并且, 即使在未关注的情况下,只要用户授权,也能获取其信息
+ ///
+ ///
+ /// 详询:
+ ///
+ ///
+ /// 以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。
+ /// 但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息
+ ///
+ public const string UserInfoScope = "snsapi_userinfo";
+ ///
+ /// 不弹出授权页面,直接跳转,只能获取用户openid
+ ///
+ ///
+ /// 详询:
+ ///
+ ///
+ /// 以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。
+ /// 用户感知的就是直接进入了回调页(往往是业务页面)
+ ///
+ public const string LoginScope = "snsapi_login";
+ }
+}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/WeChatGrantValidator.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/WeChatGrantValidator.cs
index f0b14daae..f24fcd0ab 100644
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/WeChatGrantValidator.cs
+++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/WeChatGrantValidator.cs
@@ -1,116 +1,143 @@
-
-using IdentityModel;
-using IdentityServer4.Events;
-using IdentityServer4.Models;
-using IdentityServer4.Services;
-using IdentityServer4.Validation;
-using LINGYUN.Abp.WeChat;
-using LINGYUN.Abp.WeChat.OpenId;
-using LINGYUN.Abp.WeChat.Security.Claims;
-using Microsoft.AspNetCore.Identity;
-using Microsoft.Extensions.Localization;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Logging.Abstractions;
-using System;
-using System.Collections.Generic;
-using System.Security.Claims;
-using System.Threading.Tasks;
-using Volo.Abp.Identity;
-using Volo.Abp.IdentityServer.Localization;
-using Volo.Abp.Security.Claims;
-using IdentityResource = Volo.Abp.Identity.Localization.IdentityResource;
-using IdentityUser = Volo.Abp.Identity.IdentityUser;
-
-namespace LINGYUN.Abp.IdentityServer.WeChat
-{
- public abstract class WeChatGrantValidator : IExtensionGrantValidator
- {
- public abstract string GrantType { get; }
- public abstract string LoginProviderKey { get; }
- public abstract string AuthenticationMethod { get; }
-
- public ILogger Logger { protected get; set; }
- protected IEventService EventService { get; }
- protected IWeChatOpenIdFinder WeChatOpenIdFinder { get; }
- protected IIdentityUserRepository UserRepository { get; }
- protected UserManager UserManager { get; }
- protected IStringLocalizer IdentityLocalizer { get; }
- protected IStringLocalizer IdentityServerLocalizer { get; }
-
- public WeChatGrantValidator(
- IEventService eventService,
- IWeChatOpenIdFinder weChatOpenIdFinder,
- UserManager userManager,
- IIdentityUserRepository userRepository,
- IStringLocalizer identityLocalizer,
- IStringLocalizer identityServerLocalizer)
- {
- EventService = eventService;
- UserManager = userManager;
- UserRepository = userRepository;
- WeChatOpenIdFinder = weChatOpenIdFinder;
- IdentityLocalizer = identityLocalizer;
- IdentityServerLocalizer = identityServerLocalizer;
-
- Logger = NullLogger.Instance;
- }
-
- protected abstract Task FindOpenIdAsync(string code);
-
- public async Task ValidateAsync(ExtensionGrantValidationContext context)
- {
- var raw = context.Request.Raw;
- var credential = raw.Get(OidcConstants.TokenRequest.GrantType);
- if (credential == null || !credential.Equals(GrantType))
- {
- Logger.LogWarning("Invalid grant type: not allowed");
- context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, IdentityServerLocalizer["InvalidGrant:GrantTypeInvalid"]);
- return;
- }
- // TODO: 统一命名规范, 微信认证传递的 code 改为 WeChatOpenIdConsts.WeCahtCodeKey
- var wechatCode = raw.Get(AbpWeChatGlobalConsts.TokenName);
- if (wechatCode.IsNullOrWhiteSpace() || wechatCode.IsNullOrWhiteSpace())
- {
- Logger.LogWarning("Invalid grant type: wechat code not found");
- context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, IdentityServerLocalizer["InvalidGrant:WeChatCodeNotFound"]);
- return;
- }
-
- var wechatOpenId = await FindOpenIdAsync(wechatCode);
- var currentUser = await UserManager.FindByLoginAsync(LoginProviderKey, wechatOpenId.OpenId);
- if (currentUser == null)
- {
- Logger.LogWarning("Invalid grant type: wechat openid not register", wechatOpenId.OpenId);
- context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, IdentityServerLocalizer["InvalidGrant:WeChatNotRegister"]);
- return;
- }
-
- if (await UserManager.IsLockedOutAsync(currentUser))
- {
- Logger.LogInformation("Authentication failed for username: {username}, reason: locked out", currentUser.UserName);
- context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, IdentityLocalizer["Volo.Abp.Identity:UserLockedOut"]);
- return;
- }
-
- var sub = await UserManager.GetUserIdAsync(currentUser);
-
- var additionalClaims = new List();
- if (currentUser.TenantId.HasValue)
- {
- additionalClaims.Add(new Claim(AbpClaimTypes.TenantId, currentUser.TenantId?.ToString()));
- }
- additionalClaims.Add(new Claim(AbpWeChatClaimTypes.OpenId, wechatOpenId.OpenId));
- if (!wechatOpenId.UnionId.IsNullOrWhiteSpace())
- {
- additionalClaims.Add(new Claim(AbpWeChatClaimTypes.UnionId, wechatOpenId.UnionId));
- }
-
- await EventService.RaiseAsync(new UserLoginSuccessEvent(currentUser.UserName, wechatOpenId.OpenId, null));
-
- context.Result = new GrantValidationResult(sub, AuthenticationMethod, additionalClaims.ToArray());
-
- // 登录之后需要更新安全令牌
- (await UserManager.UpdateSecurityStampAsync(currentUser)).CheckErrors();
- }
- }
-}
+
+using IdentityModel;
+using IdentityServer4.Events;
+using IdentityServer4.Models;
+using IdentityServer4.Services;
+using IdentityServer4.Validation;
+using LINGYUN.Abp.WeChat;
+using LINGYUN.Abp.WeChat.OpenId;
+using LINGYUN.Abp.WeChat.Security.Claims;
+using LINGYUN.Abp.WeChat.Settings;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.Extensions.Localization;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using System;
+using System.Collections.Generic;
+using System.Security.Claims;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Guids;
+using Volo.Abp.Identity;
+using Volo.Abp.IdentityServer.Localization;
+using Volo.Abp.MultiTenancy;
+using Volo.Abp.Security.Claims;
+using Volo.Abp.Settings;
+using Volo.Abp.Uow;
+using IdentityResource = Volo.Abp.Identity.Localization.IdentityResource;
+using IdentityUser = Volo.Abp.Identity.IdentityUser;
+
+namespace LINGYUN.Abp.IdentityServer.WeChat
+{
+ public abstract class WeChatGrantValidator : IExtensionGrantValidator
+ {
+ public abstract string GrantType { get; }
+ public abstract string LoginProvider { get; }
+ public abstract string AuthenticationMethod { get; }
+
+ public ILogger Logger { protected get; set; }
+ public IAbpLazyServiceProvider ServiceProvider { protected get; set; }
+
+ protected IEventService EventService { get; }
+ protected IWeChatOpenIdFinder WeChatOpenIdFinder { get; }
+ protected IIdentityUserRepository UserRepository { get; }
+ protected UserManager UserManager { get; }
+ protected IStringLocalizer IdentityLocalizer { get; }
+ protected IStringLocalizer IdentityServerLocalizer { get; }
+
+ public WeChatGrantValidator(
+ IEventService eventService,
+ IWeChatOpenIdFinder weChatOpenIdFinder,
+ UserManager userManager,
+ IIdentityUserRepository userRepository,
+ IStringLocalizer identityLocalizer,
+ IStringLocalizer identityServerLocalizer)
+ {
+ EventService = eventService;
+ UserManager = userManager;
+ UserRepository = userRepository;
+ WeChatOpenIdFinder = weChatOpenIdFinder;
+ IdentityLocalizer = identityLocalizer;
+ IdentityServerLocalizer = identityServerLocalizer;
+
+ Logger = NullLogger.Instance;
+ }
+
+ protected abstract Task FindOpenIdAsync(string code);
+
+ [UnitOfWork]
+ public async Task ValidateAsync(ExtensionGrantValidationContext context)
+ {
+ var raw = context.Request.Raw;
+ var credential = raw.Get(OidcConstants.TokenRequest.GrantType);
+ if (credential == null || !credential.Equals(GrantType))
+ {
+ Logger.LogWarning("Invalid grant type: not allowed");
+ context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, IdentityServerLocalizer["InvalidGrant:GrantTypeInvalid"]);
+ return;
+ }
+ // TODO: 统一命名规范, 微信认证传递的 code 改为 WeChatOpenIdConsts.WeCahtCodeKey
+ var wechatCode = raw.Get(AbpWeChatGlobalConsts.TokenName);
+ if (wechatCode.IsNullOrWhiteSpace() || wechatCode.IsNullOrWhiteSpace())
+ {
+ Logger.LogWarning("Invalid grant type: wechat code not found");
+ context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, IdentityServerLocalizer["InvalidGrant:WeChatCodeNotFound"]);
+ return;
+ }
+
+ var wechatOpenId = await FindOpenIdAsync(wechatCode);
+ var currentUser = await UserManager.FindByLoginAsync(LoginProvider, wechatOpenId.OpenId);
+ if (currentUser == null)
+ {
+ var settingProvider = ServiceProvider.LazyGetRequiredService();
+ // TODO 检查启用用户注册是否有必要引用账户模块
+ if (! await settingProvider.IsTrueAsync("Abp.Account.IsSelfRegistrationEnabled") ||
+ ! await settingProvider.IsTrueAsync(WeChatSettingNames.EnabledQuickLogin))
+ {
+ Logger.LogWarning("Invalid grant type: wechat openid not register", wechatOpenId.OpenId);
+ context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, IdentityServerLocalizer["InvalidGrant:WeChatNotRegister"]);
+ return;
+ }
+ var guiGenerator = ServiceProvider.LazyGetRequiredService();
+ var currentTenant = ServiceProvider.LazyGetRequiredService();
+ var userName = "wxid-" + wechatOpenId.OpenId.ToMd5().ToLower();
+ var userEmail = $"{userName}@{currentTenant.Name ?? "default"}.io";
+ currentUser = new IdentityUser(guiGenerator.Create(), userName, userEmail, currentTenant.Id);
+ (await UserManager.CreateAsync(currentUser)).CheckErrors();
+ (await UserManager.AddLoginAsync(
+ currentUser,
+ new UserLoginInfo(
+ LoginProvider,
+ wechatOpenId.OpenId,
+ LoginProvider))).CheckErrors();
+ }
+
+ if (await UserManager.IsLockedOutAsync(currentUser))
+ {
+ Logger.LogInformation("Authentication failed for username: {username}, reason: locked out", currentUser.UserName);
+ context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, IdentityLocalizer["Volo.Abp.Identity:UserLockedOut"]);
+ return;
+ }
+
+ var sub = await UserManager.GetUserIdAsync(currentUser);
+
+ var additionalClaims = new List();
+ if (currentUser.TenantId.HasValue)
+ {
+ additionalClaims.Add(new Claim(AbpClaimTypes.TenantId, currentUser.TenantId?.ToString()));
+ }
+ additionalClaims.Add(new Claim(AbpWeChatClaimTypes.OpenId, wechatOpenId.OpenId));
+ if (!wechatOpenId.UnionId.IsNullOrWhiteSpace())
+ {
+ additionalClaims.Add(new Claim(AbpWeChatClaimTypes.UnionId, wechatOpenId.UnionId));
+ }
+
+ await EventService.RaiseAsync(new UserLoginSuccessEvent(currentUser.UserName, wechatOpenId.OpenId, null));
+
+ context.Result = new GrantValidationResult(sub, AuthenticationMethod, additionalClaims.ToArray());
+
+ // 登录之后需要更新安全令牌
+ (await UserManager.UpdateSecurityStampAsync(currentUser)).CheckErrors();
+ }
+ }
+}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN.Abp.IdentityServer.WeChatValidator.csproj b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN.Abp.IdentityServer.WeChatValidator.csproj
deleted file mode 100644
index 0d1a56f13..000000000
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN.Abp.IdentityServer.WeChatValidator.csproj
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
- netcoreapp3.1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/AbpIdentityServerWeChatValidatorModule.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/AbpIdentityServerWeChatValidatorModule.cs
deleted file mode 100644
index 000356b5c..000000000
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/AbpIdentityServerWeChatValidatorModule.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using LINGYUN.Abp.IdentityServer.AspNetIdentity;
-using LINGYUN.Abp.IdentityServer.WeChatValidator;
-using LINGYUN.Abp.WeChat.Authorization;
-using Microsoft.AspNetCore.Authentication;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using Volo.Abp.IdentityServer;
-using Volo.Abp.IdentityServer.Localization;
-using Volo.Abp.Localization;
-using Volo.Abp.Modularity;
-using Volo.Abp.VirtualFileSystem;
-
-namespace LINGYUN.Abp.IdentityServer
-{
- [DependsOn(
- typeof(AbpWeChatAuthorizationModule),
- typeof(AbpIdentityServerDomainModule))]
- public class AbpIdentityServerWeChatValidatorModule : AbpModule
- {
- public override void PreConfigureServices(ServiceConfigurationContext context)
- {
- var configuration = context.Services.GetConfiguration();
-
- PreConfigure(builder =>
- {
- builder.AddProfileService();
- builder.AddExtensionGrantValidator();
- });
- }
-
- public override void ConfigureServices(ServiceConfigurationContext context)
- {
- var configuration = context.Services.GetConfiguration();
-
- Configure(configuration.GetSection("WeChat:Signature"));
-
- context.Services
- .AddAuthentication()
- .AddWeChat(options => // 加入微信认证登录
- {
- configuration.GetSection("WeChat:Auth")?.Bind(options);
- });
-
- Configure(options =>
- {
- options.FileSets.AddEmbedded();
- });
-
- Configure(options =>
- {
- options.Resources
- .Get()
- .AddVirtualJson("/LINGYUN/Abp/IdentityServer/Localization/WeChatValidator");
- });
- }
- }
-}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/AspNetIdentity/AbpWeChatProfileService.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/AspNetIdentity/AbpWeChatProfileService.cs
deleted file mode 100644
index 11246cab3..000000000
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/AspNetIdentity/AbpWeChatProfileService.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-using IdentityServer4.AspNetIdentity;
-using IdentityServer4.Models;
-using LINGYUN.Abp.WeChat.Authorization;
-using Microsoft.AspNetCore.Identity;
-using System.Linq;
-using System.Security.Principal;
-using System.Threading.Tasks;
-using Volo.Abp.Identity;
-using Volo.Abp.MultiTenancy;
-using Volo.Abp.Security.Claims;
-using Volo.Abp.Uow;
-using IdentityUser = Volo.Abp.Identity.IdentityUser;
-
-namespace LINGYUN.Abp.IdentityServer.AspNetIdentity
-{
- public class AbpWeChatProfileServicee : ProfileService
- {
- protected ICurrentTenant CurrentTenant { get; }
- public AbpWeChatProfileServicee(
- IdentityUserManager userManager,
- IUserClaimsPrincipalFactory claimsFactory,
- ICurrentTenant currentTenant)
- : base(userManager, claimsFactory)
- {
- CurrentTenant = currentTenant;
- }
-
- [UnitOfWork]
- public override async Task GetProfileDataAsync(ProfileDataRequestContext context)
- {
- using (CurrentTenant.Change(context.Subject.FindTenantId()))
- {
- await base.GetProfileDataAsync(context);
-
- // TODO: 可以从令牌获取openid, 安全性呢?
- TryAddWeChatClaim(context, AbpWeChatClaimTypes.OpenId);
- TryAddWeChatClaim(context, AbpWeChatClaimTypes.UnionId);
- }
- }
-
- [UnitOfWork]
- public override async Task IsActiveAsync(IsActiveContext context)
- {
- using (CurrentTenant.Change(context.Subject.FindTenantId()))
- {
- await base.IsActiveAsync(context);
- }
- }
-
- protected virtual void TryAddWeChatClaim(ProfileDataRequestContext context, string weChatClaimType)
- {
- if (context.RequestedClaimTypes.Any(rc => rc.Contains(weChatClaimType)))
- {
- var weChatClaim = context.Subject.FindFirst(weChatClaimType);
- if (weChatClaim != null)
- {
- context.IssuedClaims.Add(weChatClaim);
- }
- }
- }
- }
-}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/IWeChatResourceDataSeeder.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/IWeChatResourceDataSeeder.cs
deleted file mode 100644
index 38d591d26..000000000
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/IWeChatResourceDataSeeder.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System.Threading.Tasks;
-
-namespace LINGYUN.Abp.IdentityServer
-{
- public interface IWeChatResourceDataSeeder
- {
- Task CreateStandardResourcesAsync();
- }
-}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/Localization/WeChatValidator/en.json b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/Localization/WeChatValidator/en.json
deleted file mode 100644
index 77d155b38..000000000
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/Localization/WeChatValidator/en.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "culture": "en",
- "texts": {
- "SelfRegistrationDisabledMessage": "Self-registration is disabled for this application. Please contact the application administrator to register a new user.",
- "InvalidGrant:GrantTypeInvalid": "The type of authorization that is not allowed!",
- "InvalidGrant:WeChatTokenInvalid": "WeChat authentication failed!",
- "InvalidGrant:WeChatCodeNotFound": "The code obtained when WeChat is logged in is empty or does not exist!",
- "InvalidGrant:WeChatNotRegister": "User WeChat account not registed!"
- }
-}
\ No newline at end of file
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/Localization/WeChatValidator/zh-Hans.json b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/Localization/WeChatValidator/zh-Hans.json
deleted file mode 100644
index 72a2995b4..000000000
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/Localization/WeChatValidator/zh-Hans.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "culture": "zh-Hans",
- "texts": {
- "SelfRegistrationDisabledMessage": "应用程序未开放注册,请联系管理员添加新用户.",
- "InvalidGrant:GrantTypeInvalid": "不被允许的授权类型!",
- "InvalidGrant:WeChatTokenInvalid": "微信认证失败!",
- "InvalidGrant:WeChatCodeNotFound": "微信登录时获取的 code 为空或不存在!",
- "InvalidGrant:WeChatNotRegister": "用户微信账号未绑定!"
- }
-}
\ No newline at end of file
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatResourceDataSeeder.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatResourceDataSeeder.cs
deleted file mode 100644
index eb2e69766..000000000
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatResourceDataSeeder.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-using LINGYUN.Abp.WeChat.Authorization;
-using System.Threading.Tasks;
-using Volo.Abp.DependencyInjection;
-using Volo.Abp.Guids;
-using Volo.Abp.Identity;
-using Volo.Abp.IdentityServer.IdentityResources;
-
-namespace LINGYUN.Abp.IdentityServer
-{
- public class WeChatResourceDataSeeder : IWeChatResourceDataSeeder, ITransientDependency
- {
- protected IIdentityClaimTypeRepository ClaimTypeRepository { get; }
- protected IIdentityResourceRepository IdentityResourceRepository { get; }
- protected IGuidGenerator GuidGenerator { get; }
-
- public WeChatResourceDataSeeder(
- IIdentityResourceRepository identityResourceRepository,
- IGuidGenerator guidGenerator,
- IIdentityClaimTypeRepository claimTypeRepository)
- {
- IdentityResourceRepository = identityResourceRepository;
- GuidGenerator = guidGenerator;
- ClaimTypeRepository = claimTypeRepository;
- }
-
- public virtual async Task CreateStandardResourcesAsync()
- {
- var wechatClaimTypes = new string[]
- {
- AbpWeChatClaimTypes.AvatarUrl,
- AbpWeChatClaimTypes.City,
- AbpWeChatClaimTypes.Country,
- AbpWeChatClaimTypes.NickName,
- AbpWeChatClaimTypes.OpenId,
- AbpWeChatClaimTypes.Privilege,
- AbpWeChatClaimTypes.Province,
- AbpWeChatClaimTypes.Sex,
- AbpWeChatClaimTypes.UnionId
- };
-
- var wechatResource = new IdentityServer4.Models.IdentityResource(
- AbpWeChatAuthorizationConsts.ProfileKey,
- AbpWeChatAuthorizationConsts.DisplayName,
- wechatClaimTypes);
-
- foreach (var claimType in wechatClaimTypes)
- {
- await AddClaimTypeIfNotExistsAsync(claimType);
- }
-
- await AddIdentityResourceIfNotExistsAsync(wechatResource);
- }
-
- protected virtual async Task AddIdentityResourceIfNotExistsAsync(IdentityServer4.Models.IdentityResource resource)
- {
- if (await IdentityResourceRepository.CheckNameExistAsync(resource.Name))
- {
- return;
- }
-
- await IdentityResourceRepository.InsertAsync(
- new IdentityResource(
- GuidGenerator.Create(),
- resource
- )
- );
- }
-
- protected virtual async Task AddClaimTypeIfNotExistsAsync(string claimType)
- {
- if (await ClaimTypeRepository.AnyAsync(claimType))
- {
- return;
- }
-
- await ClaimTypeRepository.InsertAsync(
- new IdentityClaimType(
- GuidGenerator.Create(),
- claimType,
- isStatic: true
- )
- );
- }
- }
-}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatSignatureMiddleware.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatSignatureMiddleware.cs
deleted file mode 100644
index 74b1a70b7..000000000
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatSignatureMiddleware.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Options;
-using System;
-using System.Collections;
-using System.Threading.Tasks;
-using Volo.Abp;
-using Volo.Abp.DependencyInjection;
-
-namespace LINGYUN.Abp.IdentityServer
-{
- public class WeChatSignatureMiddleware : IMiddleware, ITransientDependency
- {
- protected WeChatSignatureOptions Options { get; }
- public WeChatSignatureMiddleware(IOptions options)
- {
- Options = options.Value;
- }
-
- public async Task InvokeAsync(HttpContext context, RequestDelegate next)
- {
- if (context.Request.Path.HasValue)
- {
- var requestPath = context.Request.Path.Value;
- // 访问地址是否与定义的地址匹配
- if (requestPath.Equals(Options.RequestPath))
- {
- var timestamp = context.Request.Query["timestamp"];
- var nonce = context.Request.Query["nonce"];
- var signature = context.Request.Query["signature"];
- var echostr = context.Request.Query["echostr"];
- // 验证消息合法性
- var check = CheckWeChatSignature(Options.Token, timestamp, nonce, signature);
- if (check)
- {
- // 验证通过需要把微信服务器传递的字符原封不动传回
- await context.Response.WriteAsync(echostr);
- return;
- }
- // 微信消息验证不通过
- throw new AbpException("Invalid wechat signature");
- }
- }
- // 不属于微信的消息进入下一个中间件
- await next(context);
- }
-
- protected bool CheckWeChatSignature(string token, string timestamp, string nonce, string signature)
- {
- var al = new ArrayList
- {
- token,
- timestamp,
- nonce
- };
- // step1 排序
- al.Sort();
- string signatureStr = string.Empty;
- // step2 拼接
- for (int i = 0; i < al.Count; i++)
- {
- signatureStr += al[i];
- }
- // step3 SHA1加密
- byte[] bytes_out = signatureStr.Sha1();
- string result = BitConverter.ToString(bytes_out).Replace("-", "");
- // step4 比对
- if (result.Equals(signature, StringComparison.CurrentCultureIgnoreCase))
- {
- return true;
- }
- return false;
- }
- }
-}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatSignatureOptions.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatSignatureOptions.cs
deleted file mode 100644
index 7e5b82154..000000000
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatSignatureOptions.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-namespace LINGYUN.Abp.IdentityServer
-{
- public class WeChatSignatureOptions
- {
- ///
- /// 微信服务器请求路径
- /// 填写在微信开发者中心配置的地址
- ///
- public string RequestPath { get; set; }
- ///
- /// 微信服务器请求token
- /// 填写在微信开发者中心配置的token
- ///
- public string Token { get; set; }
- }
-}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatTokenGrantValidator.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatTokenGrantValidator.cs
deleted file mode 100644
index 25827a066..000000000
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatTokenGrantValidator.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-using IdentityModel;
-using IdentityServer4.Events;
-using IdentityServer4.Models;
-using IdentityServer4.Services;
-using IdentityServer4.Validation;
-using LINGYUN.Abp.WeChat.Authorization;
-using Microsoft.AspNetCore.Identity;
-using Microsoft.Extensions.Localization;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-using System;
-using System.Collections.Generic;
-using System.Net.Http;
-using System.Security.Claims;
-using System.Threading.Tasks;
-using Volo.Abp.Identity;
-using Volo.Abp.IdentityServer.Localization;
-using Volo.Abp.Security.Claims;
-using IdentityUser = Volo.Abp.Identity.IdentityUser;
-
-namespace LINGYUN.Abp.IdentityServer.WeChatValidator
-{
- public class WeChatTokenGrantValidator : IExtensionGrantValidator
- {
- protected ILogger Logger { get; }
- protected AbpWeChatAuthorizationOptions Options { get; }
- protected IHttpClientFactory HttpClientFactory{ get; }
- protected IEventService EventService { get; }
- protected IWeChatOpenIdFinder WeChatOpenIdFinder { get; }
- protected IIdentityUserRepository UserRepository { get; }
- protected UserManager UserManager { get; }
- protected SignInManager SignInManager { get; }
- protected IStringLocalizer Localizer { get; }
- protected PhoneNumberTokenProvider PhoneNumberTokenProvider { get; }
-
-
- public WeChatTokenGrantValidator(
- IEventService eventService,
- IWeChatOpenIdFinder weChatOpenIdFinder,
- IHttpClientFactory httpClientFactory,
- UserManager userManager,
- IIdentityUserRepository userRepository,
- SignInManager signInManager,
- IStringLocalizer stringLocalizer,
- PhoneNumberTokenProvider phoneNumberTokenProvider,
- IOptions options,
- ILogger logger)
- {
- Logger = logger;
- Options = options.Value;
-
- EventService = eventService;
- UserManager = userManager;
- SignInManager = signInManager;
- Localizer = stringLocalizer;
- UserRepository = userRepository;
- WeChatOpenIdFinder = weChatOpenIdFinder;
- HttpClientFactory = httpClientFactory;
- PhoneNumberTokenProvider = phoneNumberTokenProvider;
- }
-
- public string GrantType => WeChatValidatorConsts.WeChatValidatorGrantTypeName;
-
- public async Task ValidateAsync(ExtensionGrantValidationContext context)
- {
- var raw = context.Request.Raw;
- var credential = raw.Get(OidcConstants.TokenRequest.GrantType);
- if (credential == null || !credential.Equals(GrantType))
- {
- Logger.LogWarning("Invalid grant type: not allowed");
- context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant,
- Localizer["InvalidGrant:GrantTypeInvalid"]);
- return;
- }
- // TODO: 统一命名规范, 微信认证传递的 code 改为 WeChatOpenIdConsts.WeCahtCodeKey
- var wechatCode = raw.Get(WeChatValidatorConsts.WeChatValidatorTokenName);
- if (wechatCode.IsNullOrWhiteSpace() || wechatCode.IsNullOrWhiteSpace())
- {
- Logger.LogWarning("Invalid grant type: wechat code not found");
- context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant,
- Localizer["InvalidGrant:WeChatCodeNotFound"]);
- return;
- }
- var wechatOpenId = await WeChatOpenIdFinder.FindAsync(wechatCode);
- var currentUser = await UserManager.FindByLoginAsync(AbpWeChatAuthorizationConsts.ProviderKey, wechatOpenId.OpenId);
- if(currentUser == null)
- {
- Logger.LogWarning("Invalid grant type: wechat openid: {0} not register", wechatOpenId.OpenId);
- context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant,
- Localizer["InvalidGrant:WeChatNotRegister"]);
- return;
- }
- var sub = await UserManager.GetUserIdAsync(currentUser);
-
- var additionalClaims = new List();
- if (currentUser.TenantId.HasValue)
- {
- additionalClaims.Add(new Claim(AbpClaimTypes.TenantId, currentUser.TenantId?.ToString()));
- }
- additionalClaims.Add(new Claim(AbpWeChatClaimTypes.OpenId, wechatOpenId.OpenId));
- if (!wechatOpenId.UnionId.IsNullOrWhiteSpace())
- {
- additionalClaims.Add(new Claim(AbpWeChatClaimTypes.UnionId, wechatOpenId.UnionId));
- }
-
- await EventService.RaiseAsync(new UserLoginSuccessEvent(currentUser.UserName, wechatOpenId.OpenId, null));
- context.Result = new GrantValidationResult(sub,
- WeChatValidatorConsts.AuthenticationMethods.BasedWeChatAuthentication, additionalClaims.ToArray());
- }
- }
-}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatValidatorConsts.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatValidatorConsts.cs
deleted file mode 100644
index 53bf094c5..000000000
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatValidatorConsts.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-namespace LINGYUN.Abp.IdentityServer.WeChatValidator
-{
- public class WeChatValidatorConsts
- {
- public const string WeChatValidatorClientName = "WeChatValidator";
-
- public const string WeChatValidatorGrantTypeName = "wechat";
-
- public const string WeChatValidatorTokenName = "code";
-
- public class AuthenticationMethods
- {
- public const string BasedWeChatAuthentication = "wca";
- }
- }
-}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Authentication/WeChat/WeChatAuthenticationHandler.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Authentication/WeChat/WeChatAuthenticationHandler.cs
deleted file mode 100644
index 446c9cb59..000000000
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Authentication/WeChat/WeChatAuthenticationHandler.cs
+++ /dev/null
@@ -1,316 +0,0 @@
-using LINGYUN.Abp.WeChat.Authorization;
-using Microsoft.AspNetCore.Authentication.OAuth;
-using Microsoft.AspNetCore.WebUtilities;
-using Microsoft.Extensions.Caching.Distributed;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-using Microsoft.Extensions.Primitives;
-using Microsoft.Net.Http.Headers;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Net.Http;
-using System.Security.Claims;
-using System.Text;
-using System.Text.Encodings.Web;
-using System.Text.Json;
-using System.Threading.Tasks;
-using Volo.Abp.Caching;
-
-namespace Microsoft.AspNetCore.Authentication.WeChat
-{
- public class WeChatAuthenticationHandler : OAuthHandler
- {
- protected IDistributedCache Cache { get; }
- public WeChatAuthenticationHandler(
- IDistributedCache cache,
- IOptionsMonitor options,
- ILoggerFactory logger,
- UrlEncoder encoder,
- ISystemClock clock)
- : base(options, logger, encoder, clock)
- {
- Cache = cache;
- }
-
- protected override async Task CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens)
- {
- var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary
- {
- ["access_token"] = tokens.AccessToken,
- ["openid"] = tokens.Response.GetRootString("openid")
- });
-
- var response = await Backchannel.GetAsync(address);
- if (!response.IsSuccessStatusCode)
- {
- Logger.LogError("An error occurred while retrieving the user profile: the remote server " +
- "returned a {Status} response with the following payload: {Headers} {Body}.",
- /* Status: */ response.StatusCode,
- /* Headers: */ response.Headers.ToString(),
- /* Body: */ await response.Content.ReadAsStringAsync());
-
- throw new HttpRequestException("An error occurred while retrieving user information.");
- }
-
- var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
- if (!string.IsNullOrEmpty(payload.GetRootString("errcode")))
- {
- Logger.LogError("An error occurred while retrieving the user profile: the remote server " +
- "returned a {Status} response with the following payload: {Headers} {Body}.",
- /* Status: */ response.StatusCode,
- /* Headers: */ response.Headers.ToString(),
- /* Body: */ await response.Content.ReadAsStringAsync());
-
- throw new HttpRequestException("An error occurred while retrieving user information.");
- }
-
- var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, payload.RootElement);
- context.RunClaimActions();
-
- await Events.CreatingTicket(context);
-
- // TODO: 此处通过唯一的 CorrelationId, 将 properties生成的State缓存删除
- var state = Request.Query["state"];
-
- var stateCacheKey = WeChatAuthenticationStateCacheItem.CalculateCacheKey(state, null);
- await Cache.RemoveAsync(stateCacheKey, token: Context.RequestAborted);
-
- return new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name);
- }
-
- ///
- /// code换取access_token
- ///
- protected override async Task ExchangeCodeAsync(OAuthCodeExchangeContext context)
- {
- var address = QueryHelpers.AddQueryString(Options.TokenEndpoint, new Dictionary()
- {
- ["appid"] = Options.ClientId,
- ["secret"] = Options.ClientSecret,
- ["code"] = context.Code,
- ["grant_type"] = "authorization_code"
- });
-
- var response = await Backchannel.GetAsync(address);
- if (!response.IsSuccessStatusCode)
- {
- Logger.LogError("An error occurred while retrieving an access token: the remote server " +
- "returned a {Status} response with the following payload: {Headers} {Body}.",
- /* Status: */ response.StatusCode,
- /* Headers: */ response.Headers.ToString(),
- /* Body: */ await response.Content.ReadAsStringAsync());
-
- return OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token."));
- }
-
- var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
- if (!string.IsNullOrEmpty(payload.GetRootString("errcode")))
- {
- Logger.LogError("An error occurred while retrieving an access token: the remote server " +
- "returned a {Status} response with the following payload: {Headers} {Body}.",
- /* Status: */ response.StatusCode,
- /* Headers: */ response.Headers.ToString(),
- /* Body: */ await response.Content.ReadAsStringAsync());
-
- return OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token."));
- }
- return OAuthTokenResponse.Success(payload);
- }
-
- protected override async Task HandleChallengeAsync(AuthenticationProperties properties)
- {
- await base.HandleChallengeAsync(properties);
-
- // TODO: 此处已经生成唯一的 CorrelationId, 可以借此将 properties生成State之后再进行缓存
- var state = properties.Items[".xsrf"];
-
- var stateToken = Options.StateDataFormat.Protect(properties);
- var stateCacheKey = WeChatAuthenticationStateCacheItem.CalculateCacheKey(state, null);
-
- await Cache
- .SetAsync(
- stateCacheKey,
- new WeChatAuthenticationStateCacheItem(stateToken),
- new DistributedCacheEntryOptions
- {
- AbsoluteExpiration = Clock.UtcNow.AddMinutes(2) // TODO: 设定2分钟过期?
- },
- token: Context.RequestAborted);
- }
- ///
- /// 构建用户授权地址
- ///
- protected override string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri)
- {
- var state = properties.Items[".xsrf"];
-
- var isWeChatBrewserRequest = IsWeChatBrowser();
-
- var scope = isWeChatBrewserRequest
- ? AbpWeChatAuthorizationConsts.UserInfoScope
- : FormatScope();
-
- var endPoint = isWeChatBrewserRequest
- ? Options.AuthorizationEndpoint
- : AbpWeChatAuthorizationConsts.QrConnectEndpoint;
-
- var challengeUrl = QueryHelpers.AddQueryString(endPoint, new Dictionary
- {
- ["appid"] = Options.ClientId,
- ["redirect_uri"] = redirectUri,
- ["response_type"] = "code"
- });
-
- challengeUrl += $"&scope={scope}&state={state}";
-
- return challengeUrl;
- }
-
- protected override async Task HandleRemoteAuthenticateAsync()
- {
- var query = Request.Query;
-
- // TODO: 此处借用唯一的 CorrelationId, 将 properties生成的State缓存取出,进行解密
- var state = query["state"];
-
- var stateCacheKey = WeChatAuthenticationStateCacheItem.CalculateCacheKey(state, null);
- var stateCacheItem = await Cache.GetAsync(stateCacheKey, token: Context.RequestAborted);
-
- var properties = Options.StateDataFormat.Unprotect(stateCacheItem.State);
-
- if (properties == null)
- {
- return HandleRequestResult.Fail("The oauth state was missing or invalid.");
- }
-
- // OAuth2 10.12 CSRF
- if (!ValidateCorrelationId(properties))
- {
- return HandleRequestResult.Fail("Correlation failed.", properties);
- }
-
- var error = query["error"];
- if (!StringValues.IsNullOrEmpty(error))
- {
- // Note: access_denied errors are special protocol errors indicating the user didn't
- // approve the authorization demand requested by the remote authorization server.
- // Since it's a frequent scenario (that is not caused by incorrect configuration),
- // denied errors are handled differently using HandleAccessDeniedErrorAsync().
- // Visit https://tools.ietf.org/html/rfc6749#section-4.1.2.1 for more information.
- var errorDescription = query["error_description"];
- var errorUri = query["error_uri"];
- if (StringValues.Equals(error, "access_denied"))
- {
- var result = await HandleAccessDeniedErrorAsync(properties);
- if (!result.None)
- {
- return result;
- }
- var deniedEx = new Exception("Access was denied by the resource owner or by the remote server.");
- deniedEx.Data["error"] = error.ToString();
- deniedEx.Data["error_description"] = errorDescription.ToString();
- deniedEx.Data["error_uri"] = errorUri.ToString();
-
- return HandleRequestResult.Fail(deniedEx, properties);
- }
-
- var failureMessage = new StringBuilder();
- failureMessage.Append(error);
- if (!StringValues.IsNullOrEmpty(errorDescription))
- {
- failureMessage.Append(";Description=").Append(errorDescription);
- }
- if (!StringValues.IsNullOrEmpty(errorUri))
- {
- failureMessage.Append(";Uri=").Append(errorUri);
- }
-
- var ex = new Exception(failureMessage.ToString());
- ex.Data["error"] = error.ToString();
- ex.Data["error_description"] = errorDescription.ToString();
- ex.Data["error_uri"] = errorUri.ToString();
-
- return HandleRequestResult.Fail(ex, properties);
- }
-
- var code = query["code"];
-
- if (StringValues.IsNullOrEmpty(code))
- {
- return HandleRequestResult.Fail("Code was not found.", properties);
- }
-
- var codeExchangeContext = new OAuthCodeExchangeContext(properties, code, BuildRedirectUri(Options.CallbackPath));
- using var tokens = await ExchangeCodeAsync(codeExchangeContext);
-
- if (tokens.Error != null)
- {
- return HandleRequestResult.Fail(tokens.Error, properties);
- }
-
- if (string.IsNullOrEmpty(tokens.AccessToken))
- {
- return HandleRequestResult.Fail("Failed to retrieve access token.", properties);
- }
-
- var identity = new ClaimsIdentity(ClaimsIssuer);
-
- if (Options.SaveTokens)
- {
- var authTokens = new List();
-
- authTokens.Add(new AuthenticationToken { Name = "access_token", Value = tokens.AccessToken });
- if (!string.IsNullOrEmpty(tokens.RefreshToken))
- {
- authTokens.Add(new AuthenticationToken { Name = "refresh_token", Value = tokens.RefreshToken });
- }
-
- if (!string.IsNullOrEmpty(tokens.TokenType))
- {
- authTokens.Add(new AuthenticationToken { Name = "token_type", Value = tokens.TokenType });
- }
-
- if (!string.IsNullOrEmpty(tokens.ExpiresIn))
- {
- int value;
- if (int.TryParse(tokens.ExpiresIn, NumberStyles.Integer, CultureInfo.InvariantCulture, out value))
- {
- // https://www.w3.org/TR/xmlschema-2/#dateTime
- // https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx
- var expiresAt = Clock.UtcNow + TimeSpan.FromSeconds(value);
- authTokens.Add(new AuthenticationToken
- {
- Name = "expires_at",
- Value = expiresAt.ToString("o", CultureInfo.InvariantCulture)
- });
- }
- }
-
- properties.StoreTokens(authTokens);
- }
-
- var ticket = await CreateTicketAsync(identity, properties, tokens);
- if (ticket != null)
- {
- return HandleRequestResult.Success(ticket);
- }
- else
- {
- return HandleRequestResult.Fail("Failed to retrieve user information from remote server.", properties);
- }
- }
-
- protected override string FormatScope()
- {
- return string.Join(",", Options.Scope);
- }
-
- protected virtual bool IsWeChatBrowser()
- {
- var userAgent = Request.Headers[HeaderNames.UserAgent].ToString();
-
- return userAgent.Contains("micromessenger", StringComparison.InvariantCultureIgnoreCase);
- }
- }
-}
\ No newline at end of file
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Authentication/WeChat/WeChatAuthenticationOptions.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Authentication/WeChat/WeChatAuthenticationOptions.cs
deleted file mode 100644
index 9efc7600b..000000000
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Authentication/WeChat/WeChatAuthenticationOptions.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-using LINGYUN.Abp.WeChat.Authorization;
-using Microsoft.AspNetCore.Authentication.OAuth;
-using Microsoft.AspNetCore.Http;
-using System.Security.Claims;
-using System.Text.Json;
-
-namespace Microsoft.AspNetCore.Authentication.WeChat
-{
- public class WeChatAuthenticationOptions : OAuthOptions
- {
- public string AppId
- {
- get => ClientId;
- set => ClientId = value;
- }
-
- public string AppSecret
- {
- get => ClientSecret;
- set => ClientSecret = value;
- }
-
- public WeChatAuthenticationOptions()
- {
- ClaimsIssuer = AbpWeChatAuthorizationConsts.ProviderKey;
- CallbackPath = new PathString(AbpWeChatAuthorizationConsts.CallbackPath);
-
- AuthorizationEndpoint = AbpWeChatAuthorizationConsts.AuthorizationEndpoint;
- TokenEndpoint = AbpWeChatAuthorizationConsts.TokenEndpoint;
- UserInformationEndpoint = AbpWeChatAuthorizationConsts.UserInformationEndpoint;
-
- Scope.Add(AbpWeChatAuthorizationConsts.LoginScope);
- Scope.Add(AbpWeChatAuthorizationConsts.UserInfoScope);
-
- // 这个原始的属性一定要写进去,框架与UserLogin.ProviderKey进行关联判断是否绑定微信
- ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "openid");
- ClaimActions.MapJsonKey(ClaimTypes.Name, "nickname");
-
- // 把自定义的身份标识写进令牌
- ClaimActions.MapJsonKey(AbpWeChatClaimTypes.OpenId, "openid");
- ClaimActions.MapJsonKey(AbpWeChatClaimTypes.UnionId, "unionid"); // TODO: 可用作tenant对比?
- ClaimActions.MapJsonKey(AbpWeChatClaimTypes.NickName, "nickname");
- ClaimActions.MapJsonKey(AbpWeChatClaimTypes.Sex, "sex", ClaimValueTypes.Integer);
- ClaimActions.MapJsonKey(AbpWeChatClaimTypes.Country, "country");
- ClaimActions.MapJsonKey(AbpWeChatClaimTypes.Province, "province");
- ClaimActions.MapJsonKey(AbpWeChatClaimTypes.City, "city");
- ClaimActions.MapJsonKey(AbpWeChatClaimTypes.AvatarUrl, "headimgurl");
- ClaimActions.MapCustomJson(AbpWeChatClaimTypes.Privilege, user =>
- {
- return string.Join(",", user.GetStrings("privilege"));
- });
- }
- }
-}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Authentication/WeChat/WeChatAuthenticationStateCacheItem.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Authentication/WeChat/WeChatAuthenticationStateCacheItem.cs
deleted file mode 100644
index efc3ab3a5..000000000
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Authentication/WeChat/WeChatAuthenticationStateCacheItem.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Microsoft.AspNetCore.Authentication.WeChat
-{
- public class WeChatAuthenticationStateCacheItem
- {
- public string State { get; set; }
-
- public WeChatAuthenticationStateCacheItem() { }
- public WeChatAuthenticationStateCacheItem(string state)
- {
- State = state;
- }
-
- public static string CalculateCacheKey(string correlationId, string purpose)
- {
- return $"ci:{correlationId};p:{purpose ?? "null"}";
- }
- }
-}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Authentication/WeChatAuthenticationExtensions.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Authentication/WeChatAuthenticationExtensions.cs
deleted file mode 100644
index 3fa471dc4..000000000
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Authentication/WeChatAuthenticationExtensions.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-using LINGYUN.Abp.WeChat.Authorization;
-using Microsoft.AspNetCore.Authentication.WeChat;
-using Microsoft.Extensions.DependencyInjection;
-using System;
-
-namespace Microsoft.AspNetCore.Authentication
-{
- public static class WeChatAuthenticationExtensions
- {
- ///
- ///
- public static AuthenticationBuilder AddWeChat(
- this AuthenticationBuilder builder)
- {
- return builder
- .AddWeChat(
- AbpWeChatAuthorizationConsts.AuthenticationScheme,
- AbpWeChatAuthorizationConsts.DisplayName,
- options => { });
- }
-
- ///
- ///
- public static AuthenticationBuilder AddWeChat(
- this AuthenticationBuilder builder,
- Action configureOptions)
- {
- return builder
- .AddWeChat(
- AbpWeChatAuthorizationConsts.AuthenticationScheme,
- AbpWeChatAuthorizationConsts.DisplayName,
- configureOptions);
- }
-
- ///
- ///
- public static AuthenticationBuilder AddWeChat(
- this AuthenticationBuilder builder,
- string authenticationScheme,
- Action configureOptions)
- {
- return builder
- .AddWeChat(
- authenticationScheme,
- AbpWeChatAuthorizationConsts.DisplayName,
- configureOptions);
- }
-
- ///
- ///
- public static AuthenticationBuilder AddWeChat(
- this AuthenticationBuilder builder,
- string authenticationScheme,
- string displayName,
- Action configureOptions)
- {
- return builder
- .AddOAuth(
- authenticationScheme,
- displayName,
- configureOptions);
- }
- }
-}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Builder/IdentityServerApplicationBuilderExtensions.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Builder/IdentityServerApplicationBuilderExtensions.cs
deleted file mode 100644
index f8b805fbe..000000000
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Builder/IdentityServerApplicationBuilderExtensions.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using LINGYUN.Abp.IdentityServer;
-
-namespace Microsoft.AspNetCore.Builder
-{
- public static class IdentityServerApplicationBuilderExtensions
- {
- ///
- /// 启用中间件可以处理微信服务器消息
- /// 用于验证消息是否来自于微信服务器
- ///
- ///
- ///
- /// 也可以用Controller的形式来实现
- ///
- ///
- public static IApplicationBuilder UseWeChatSignature(this IApplicationBuilder builder)
- {
- builder.UseMiddleware();
- return builder;
- }
- }
-}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/README.md b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/README.md
deleted file mode 100644
index 8cf26f883..000000000
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/README.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# LINGYUN.Abp.IdentityServer.WeChatValidator
-
-废弃模块,模块层次不清晰,微信有多端平台,不同平台授权规则不一致
-
-#### 注意
-
-
-
-## 配置使用
-
-
-```csharp
-[DependsOn(typeof(AbpIdentityServerWeChatValidatorModule))]
-public class YouProjectModule : AbpModule
-{
- // other
-}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/System/BytesExtensions.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/System/BytesExtensions.cs
deleted file mode 100644
index d1bad7915..000000000
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/System/BytesExtensions.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System.Security.Cryptography;
-
-namespace System
-{
- internal static class BytesExtensions
- {
- public static byte[] Sha1(this byte[] data)
- {
- using (var sha = SHA1.Create())
- {
- var hashBytes = sha.ComputeHash(data);
- return hashBytes;
- }
- }
- }
-}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/System/StringExtensions.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/System/StringExtensions.cs
deleted file mode 100644
index a8eb40c27..000000000
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/System/StringExtensions.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System.Security.Cryptography;
-using System.Text;
-
-namespace System
-{
- internal static class StringExtensions
- {
- public static byte[] Sha1(this string str)
- {
- using (var sha = SHA1.Create())
- {
- var hashBytes = sha.ComputeHash(Encoding.ASCII.GetBytes(str));
- return hashBytes;
- }
- }
- }
-}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/System/Text/Json/JsonElementExtensions.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/System/Text/Json/JsonElementExtensions.cs
deleted file mode 100644
index 653a868ac..000000000
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/System/Text/Json/JsonElementExtensions.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-using System.Collections.Generic;
-
-namespace System.Text.Json
-{
- internal static class JsonElementExtensions
- {
- public static IEnumerable GetRootStrings(this JsonDocument json, string key)
- {
- return json.RootElement.GetStrings(key);
- }
-
- public static IEnumerable GetStrings(this JsonElement json, string key)
- {
- var result = new List();
-
- if (json.TryGetProperty(key, out JsonElement property) && property.ValueKind == JsonValueKind.Array)
- {
- foreach (var jsonProp in property.EnumerateArray())
- {
- result.Add(jsonProp.GetString());
- }
- }
-
- return result;
- }
-
- public static string GetRootString(this JsonDocument json, string key, string defaultValue = "")
- {
- if (json.RootElement.TryGetProperty(key, out JsonElement property))
- {
- return property.GetString();
- }
- return defaultValue;
- }
-
- public static string GetString(this JsonElement json, string key, string defaultValue = "")
- {
- if (json.TryGetProperty(key, out JsonElement property))
- {
- return property.GetString();
- }
- return defaultValue;
- }
-
- public static int GetRootInt32(this JsonDocument json, string key, int defaultValue = 0)
- {
- if (json.RootElement.TryGetProperty(key, out JsonElement property) && property.TryGetInt32(out int value))
- {
- return value;
- }
- return defaultValue;
- }
-
- public static int GetInt32(this JsonElement json, string key, int defaultValue = 0)
- {
- if (json.TryGetProperty(key, out JsonElement property) && property.TryGetInt32(out int value))
- {
- return value;
- }
- return defaultValue;
- }
- }
-}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.Identity.WeChat/LINGYUN.Abp.Identity.WeChat.csproj b/aspnet-core/modules/wechat/LINGYUN.Abp.Identity.WeChat/LINGYUN.Abp.Identity.WeChat.csproj
new file mode 100644
index 000000000..4184a6b51
--- /dev/null
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.Identity.WeChat/LINGYUN.Abp.Identity.WeChat.csproj
@@ -0,0 +1,19 @@
+
+
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.Identity.WeChat/LINGYUN/Abp/Identity/WeChat/AbpIdentityWeChatModule.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.Identity.WeChat/LINGYUN/Abp/Identity/WeChat/AbpIdentityWeChatModule.cs
new file mode 100644
index 000000000..848cc4e83
--- /dev/null
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.Identity.WeChat/LINGYUN/Abp/Identity/WeChat/AbpIdentityWeChatModule.cs
@@ -0,0 +1,13 @@
+using LINGYUN.Abp.WeChat;
+using Volo.Abp.Identity;
+using Volo.Abp.Modularity;
+
+namespace LINGYUN.Abp.Identity.WeChat
+{
+ [DependsOn(
+ typeof(AbpWeChatModule),
+ typeof(AbpIdentityDomainModule))]
+ public class AbpIdentityWeChatModule : AbpModule
+ {
+ }
+}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/WeChat/Authorization/UserWeChatOpenIdFinder.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.Identity.WeChat/LINGYUN/Abp/Identity/WeChat/OpenId/UserWeChatOpenIdFinder.cs
similarity index 68%
rename from aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/WeChat/Authorization/UserWeChatOpenIdFinder.cs
rename to aspnet-core/modules/wechat/LINGYUN.Abp.Identity.WeChat/LINGYUN/Abp/Identity/WeChat/OpenId/UserWeChatOpenIdFinder.cs
index 7a0a36a6d..009fb50c3 100644
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/WeChat/Authorization/UserWeChatOpenIdFinder.cs
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.Identity.WeChat/LINGYUN/Abp/Identity/WeChat/OpenId/UserWeChatOpenIdFinder.cs
@@ -1,46 +1,47 @@
-using Microsoft.Extensions.DependencyInjection;
-using System;
-using System.Linq;
-using System.Threading.Tasks;
-using Volo.Abp.DependencyInjection;
-using Volo.Abp.Identity;
-
-namespace LINGYUN.Abp.WeChat.Authorization
-{
- [Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
- [ExposeServices(typeof(IUserWeChatOpenIdFinder))]
- public class UserWeChatOpenIdFinder : IUserWeChatOpenIdFinder
- {
- protected IdentityUserManager UserManager { get; }
-
- public UserWeChatOpenIdFinder(
- IdentityUserManager userManager)
- {
- UserManager = userManager;
- }
-
- public virtual async Task FindByUserIdAsync(Guid userId)
- {
- var user = await UserManager.FindByIdAsync(userId.ToString());
-
- return GetUserOpenIdOrNull(user);
- }
-
- public virtual async Task FindByUserNameAsync(string userName)
- {
- var user = await UserManager.FindByNameAsync(userName);
-
- return GetUserOpenIdOrNull(user);
- }
-
- protected string GetUserOpenIdOrNull(IdentityUser user)
- {
- // 微信扩展登录后openid存储在Login中
- var userLogin = user?.Logins
- .Where(login => login.LoginProvider == AbpWeChatAuthorizationConsts.ProviderKey)
- .FirstOrDefault();
-
- return userLogin?.ProviderKey;
- }
- }
-}
+using LINGYUN.Abp.WeChat.OpenId;
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Identity;
+
+namespace LINGYUN.Abp.Identity.WeChat.OpenId
+{
+ [Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
+ [ExposeServices(typeof(IUserWeChatOpenIdFinder))]
+ public class UserWeChatOpenIdFinder : IUserWeChatOpenIdFinder
+ {
+ protected IdentityUserManager UserManager { get; }
+
+ public UserWeChatOpenIdFinder(
+ IdentityUserManager userManager)
+ {
+ UserManager = userManager;
+ }
+
+ public virtual async Task FindByUserIdAsync(Guid userId, string provider)
+ {
+ var user = await UserManager.FindByIdAsync(userId.ToString());
+
+ return GetUserOpenIdOrNull(user, provider);
+ }
+
+ public virtual async Task FindByUserNameAsync(string userName, string provider)
+ {
+ var user = await UserManager.FindByNameAsync(userName);
+
+ return GetUserOpenIdOrNull(user, provider);
+ }
+
+ protected string GetUserOpenIdOrNull(IdentityUser user, string provider)
+ {
+ // 微信扩展登录后openid存储在Login中
+ var userLogin = user?.Logins
+ .Where(login => login.LoginProvider == provider)
+ .FirstOrDefault();
+
+ return userLogin?.ProviderKey;
+ }
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN.Abp.WeChat.Application.Contracts.csproj b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN.Abp.WeChat.Application.Contracts.csproj
new file mode 100644
index 000000000..447716e8e
--- /dev/null
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN.Abp.WeChat.Application.Contracts.csproj
@@ -0,0 +1,14 @@
+
+
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/AbpWeChatApplicationContractsModule.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/AbpWeChatApplicationContractsModule.cs
new file mode 100644
index 000000000..91d20406a
--- /dev/null
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/AbpWeChatApplicationContractsModule.cs
@@ -0,0 +1,11 @@
+using Volo.Abp.Application;
+using Volo.Abp.Modularity;
+
+namespace LINGYUN.Abp.WeChat
+{
+ [DependsOn(
+ typeof(AbpDddApplicationContractsModule))]
+ public class AbpWeChatApplicationContractsModule : AbpModule
+ {
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/Crypto/Dto/Gender.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/Crypto/Dto/Gender.cs
new file mode 100644
index 000000000..c748a441a
--- /dev/null
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/Crypto/Dto/Gender.cs
@@ -0,0 +1,21 @@
+namespace LINGYUN.Abp.WeChat.Crypto
+{
+ ///
+ /// 性别
+ ///
+ public enum Gender
+ {
+ ///
+ /// 未知
+ ///
+ None = 0,
+ ///
+ /// 男性
+ ///
+ Man = 1,
+ ///
+ /// 女性
+ ///
+ Women = 2
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/Crypto/Dto/GetUserInfoInput.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/Crypto/Dto/GetUserInfoInput.cs
new file mode 100644
index 000000000..c6f0ef52f
--- /dev/null
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/Crypto/Dto/GetUserInfoInput.cs
@@ -0,0 +1,9 @@
+namespace LINGYUN.Abp.WeChat.Crypto
+{
+ public class GetUserInfoInput
+ {
+ public string EncryptedData { get; set; }
+ public string IV { get; set; }
+ public string Code { get; set; }
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/Crypto/Dto/UserInfoDto.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/Crypto/Dto/UserInfoDto.cs
new file mode 100644
index 000000000..0875fe427
--- /dev/null
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/Crypto/Dto/UserInfoDto.cs
@@ -0,0 +1,37 @@
+namespace LINGYUN.Abp.WeChat.Crypto
+{
+ public class UserInfoDto
+ {
+ ///
+ /// 用户昵称
+ ///
+ public string NickName { get; set; }
+ ///
+ /// 用户头像图片的 URL。
+ /// URL 最后一个数值代表正方形头像大小(有 0、46、64、96、132 数值可选,0 代表 640x640 的正方形头像,46 表示 46x46 的正方形头像,剩余数值以此类推。默认132),
+ /// 用户没有头像时该项为空。
+ /// 若用户更换头像,原有头像 URL 将失效。
+ ///
+ public string AvatarUrl { get; set; }
+ ///
+ /// 性别
+ ///
+ public Gender Gender { get; set; }
+ ///
+ /// 用户所在国家
+ ///
+ public string Country { get; set; }
+ ///
+ /// 用户所在省份
+ ///
+ public string Province { get; set; }
+ ///
+ /// 用户所在城市
+ ///
+ public string City { get; set; }
+ ///
+ /// 显示 country,province,city 所用的语言
+ ///
+ public string Language { get; set; }
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/Crypto/ICryptoAppService.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/Crypto/ICryptoAppService.cs
new file mode 100644
index 000000000..1baa146d8
--- /dev/null
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/Crypto/ICryptoAppService.cs
@@ -0,0 +1,10 @@
+using System.Threading.Tasks;
+using Volo.Abp.Application.Services;
+
+namespace LINGYUN.Abp.WeChat.Crypto
+{
+ public interface ICryptoAppService : IApplicationService
+ {
+ Task GetUserInfoAsync(GetUserInfoInput input);
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/WeChatRemoteServiceConsts.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/WeChatRemoteServiceConsts.cs
new file mode 100644
index 000000000..a901f36e7
--- /dev/null
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/WeChatRemoteServiceConsts.cs
@@ -0,0 +1,7 @@
+namespace LINGYUN.Abp.WeChat
+{
+ public static class WeChatRemoteServiceConsts
+ {
+ public const string RemoteServiceName = "AbpWeChat";
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application/LINGYUN.Abp.WeChat.Application.csproj b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application/LINGYUN.Abp.WeChat.Application.csproj
new file mode 100644
index 000000000..8a5c12a74
--- /dev/null
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application/LINGYUN.Abp.WeChat.Application.csproj
@@ -0,0 +1,19 @@
+
+
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application/LINGYUN/Abp/WeChat/AbpWeChatApplicationModule.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application/LINGYUN/Abp/WeChat/AbpWeChatApplicationModule.cs
new file mode 100644
index 000000000..e448e3622
--- /dev/null
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application/LINGYUN/Abp/WeChat/AbpWeChatApplicationModule.cs
@@ -0,0 +1,14 @@
+using LINGYUN.Abp.WeChat.MiniProgram;
+using Volo.Abp.Application;
+using Volo.Abp.Modularity;
+
+namespace LINGYUN.Abp.WeChat
+{
+ [DependsOn(
+ typeof(AbpWeChatMiniProgramModule),
+ typeof(AbpWeChatApplicationContractsModule),
+ typeof(AbpDddApplicationModule))]
+ public class AbpWeChatApplicationModule : AbpModule
+ {
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application/LINGYUN/Abp/WeChat/Crypto/CryptoAppService.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application/LINGYUN/Abp/WeChat/Crypto/CryptoAppService.cs
new file mode 100644
index 000000000..fb43fdc23
--- /dev/null
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application/LINGYUN/Abp/WeChat/Crypto/CryptoAppService.cs
@@ -0,0 +1,42 @@
+using LINGYUN.Abp.WeChat.MiniProgram;
+using LINGYUN.Abp.WeChat.OpenId;
+using Microsoft.AspNetCore.Authorization;
+using System;
+using System.Threading.Tasks;
+using Volo.Abp.Json;
+
+namespace LINGYUN.Abp.WeChat.Crypto
+{
+ [Authorize]
+ public class CryptoAppService : WeChatApplicationServiceBase, ICryptoAppService
+ {
+ protected IJsonSerializer JsonSerializer { get; }
+ protected IWeChatOpenIdFinder OpenIdFinder { get; }
+ protected IWeChatCryptoService WeChatCryptoService { get; }
+ protected AbpWeChatMiniProgramOptionsFactory MiniProgramOptionsFactory { get; }
+
+ public CryptoAppService(
+ IJsonSerializer jsonSerializer,
+ IWeChatOpenIdFinder openIdFinder,
+ IWeChatCryptoService weChatCryptoService,
+ AbpWeChatMiniProgramOptionsFactory miniProgramOptionsFactory)
+ {
+ JsonSerializer = jsonSerializer;
+ OpenIdFinder = openIdFinder;
+ WeChatCryptoService = weChatCryptoService;
+ MiniProgramOptionsFactory = miniProgramOptionsFactory;
+ }
+
+ public virtual async Task GetUserInfoAsync(GetUserInfoInput input)
+ {
+ var options = await MiniProgramOptionsFactory.CreateAsync();
+ WeChatOpenId weChatOpenId = input.Code.IsNullOrWhiteSpace()
+ ? await OpenIdFinder.FindAsync(options.AppId)
+ : await OpenIdFinder.FindAsync(input.Code, options.AppId, options.AppSecret);
+
+ var decryptedData = WeChatCryptoService.Decrypt(input.EncryptedData, input.IV, weChatOpenId.SessionKey);
+
+ return JsonSerializer.Deserialize(decryptedData);
+ }
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application/LINGYUN/Abp/WeChat/WeChatApplicationServiceBase.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application/LINGYUN/Abp/WeChat/WeChatApplicationServiceBase.cs
new file mode 100644
index 000000000..fabb44b0b
--- /dev/null
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application/LINGYUN/Abp/WeChat/WeChatApplicationServiceBase.cs
@@ -0,0 +1,14 @@
+using LINGYUN.Abp.WeChat.Localization;
+using Volo.Abp.Application.Services;
+
+namespace LINGYUN.Abp.WeChat
+{
+ public abstract class WeChatApplicationServiceBase : ApplicationService
+ {
+ protected WeChatApplicationServiceBase()
+ {
+ LocalizationResource = typeof(WeChatResource);
+ ObjectMapperContext = typeof(AbpWeChatApplicationModule);
+ }
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.HttpApi/LINGYUN.Abp.WeChat.HttpApi.csproj b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.HttpApi/LINGYUN.Abp.WeChat.HttpApi.csproj
new file mode 100644
index 000000000..c09f02218
--- /dev/null
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.HttpApi/LINGYUN.Abp.WeChat.HttpApi.csproj
@@ -0,0 +1,14 @@
+
+
+
+
+
+ net5.0
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.HttpApi/LINGYUN/Abp/WeChat/AbpWeChatHttpApiModule.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.HttpApi/LINGYUN/Abp/WeChat/AbpWeChatHttpApiModule.cs
new file mode 100644
index 000000000..f9c167c90
--- /dev/null
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.HttpApi/LINGYUN/Abp/WeChat/AbpWeChatHttpApiModule.cs
@@ -0,0 +1,12 @@
+using Volo.Abp.AspNetCore.Mvc;
+using Volo.Abp.Modularity;
+
+namespace LINGYUN.Abp.WeChat
+{
+ [DependsOn(
+ typeof(AbpWeChatApplicationContractsModule),
+ typeof(AbpAspNetCoreMvcModule))]
+ public class AbpWeChatHttpApiModule : AbpModule
+ {
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.HttpApi/LINGYUN/Abp/WeChat/Crypto/CryptoController.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.HttpApi/LINGYUN/Abp/WeChat/Crypto/CryptoController.cs
new file mode 100644
index 000000000..ce06483fd
--- /dev/null
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.HttpApi/LINGYUN/Abp/WeChat/Crypto/CryptoController.cs
@@ -0,0 +1,29 @@
+using Microsoft.AspNetCore.Mvc;
+using System.Threading.Tasks;
+using Volo.Abp;
+using Volo.Abp.AspNetCore.Mvc;
+
+namespace LINGYUN.Abp.WeChat.Crypto
+{
+ [RemoteService(Name = WeChatRemoteServiceConsts.RemoteServiceName)]
+ [Area("account")]
+ [ApiVersion("1.0")]
+ [Route("api/wechat")]
+ public class CryptoController : AbpController, ICryptoAppService
+ {
+ private readonly ICryptoAppService _service;
+
+ public CryptoController(
+ ICryptoAppService service)
+ {
+ _service = service;
+ }
+
+ [HttpGet]
+ [Route("getUserInfo")]
+ public virtual async Task GetUserInfoAsync(GetUserInfoInput input)
+ {
+ return await _service.GetUserInfoAsync(input);
+ }
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/AbpWeChatMiniProgramConsts.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/AbpWeChatMiniProgramConsts.cs
index 32cd7d6da..f2496a5ef 100644
--- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/AbpWeChatMiniProgramConsts.cs
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/AbpWeChatMiniProgramConsts.cs
@@ -1,21 +1,21 @@
-namespace LINGYUN.Abp.WeChat.MiniProgram
-{
- public class AbpWeChatMiniProgramConsts
- {
- ///
- /// 微信小程序对应的Provider名称
- ///
- public static string ProviderKey { get; set; } = "WeChat.MiniProgram";
-
- ///
- /// 微信小程序授权类型
- ///
- public static string GrantType { get; set; } = "wx-mp";
-
- ///
- /// 微信小程序授权方法名称
- ///
- public static string AuthenticationMethod { get; set; } = "wma";
- public static string HttpClient { get; set; } = "Abp.WeChat.MiniProgram";
- }
-}
+namespace LINGYUN.Abp.WeChat.MiniProgram
+{
+ public class AbpWeChatMiniProgramConsts
+ {
+ ///
+ /// 微信小程序对应的Provider名称
+ ///
+ public static string ProviderName { get; set; } = "WeChat.MiniProgram";
+
+ ///
+ /// 微信小程序授权类型
+ ///
+ public static string GrantType { get; set; } = "wx-mp";
+
+ ///
+ /// 微信小程序授权方法名称
+ ///
+ public static string AuthenticationMethod { get; set; } = "wma";
+ public static string HttpClient { get; set; } = "Abp.WeChat.MiniProgram";
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/AbpWeChatMiniProgramModule.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/AbpWeChatMiniProgramModule.cs
index 00db3f7d1..fb67d3276 100644
--- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/AbpWeChatMiniProgramModule.cs
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/AbpWeChatMiniProgramModule.cs
@@ -1,38 +1,36 @@
-using LINGYUN.Abp.WeChat.Localization;
-using Microsoft.Extensions.DependencyInjection;
-using System;
-using Volo.Abp.Localization;
-using Volo.Abp.Modularity;
-using Volo.Abp.Settings;
-using Volo.Abp.VirtualFileSystem;
-
-namespace LINGYUN.Abp.WeChat.MiniProgram
-{
- [DependsOn(
- typeof(AbpWeChatModule),
- typeof(AbpSettingsModule))]
- public class AbpWeChatMiniProgramModule : AbpModule
- {
- public override void ConfigureServices(ServiceConfigurationContext context)
- {
- Configure(options =>
- {
- options.FileSets.AddEmbedded();
- });
-
- Configure(options =>
- {
- options.Resources
- .Get()
- .AddVirtualJson("/LINGYUN/Abp/WeChat/MiniProgram/Localization/Resources");
- });
-
- context.Services.AddHttpClient(AbpWeChatMiniProgramConsts.HttpClient, options =>
- {
- options.BaseAddress = new Uri("https://api.weixin.qq.com");
- });
-
- context.Services.AddAbpDynamicOptions();
- }
- }
-}
+using LINGYUN.Abp.WeChat.Localization;
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using Volo.Abp.Localization;
+using Volo.Abp.Modularity;
+using Volo.Abp.VirtualFileSystem;
+
+namespace LINGYUN.Abp.WeChat.MiniProgram
+{
+ [DependsOn(
+ typeof(AbpWeChatModule))]
+ public class AbpWeChatMiniProgramModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options =>
+ {
+ options.FileSets.AddEmbedded();
+ });
+
+ Configure(options =>
+ {
+ options.Resources
+ .Get()
+ .AddVirtualJson("/LINGYUN/Abp/WeChat/MiniProgram/Localization/Resources");
+ });
+
+ context.Services.AddHttpClient(AbpWeChatMiniProgramConsts.HttpClient, options =>
+ {
+ options.BaseAddress = new Uri("https://api.weixin.qq.com");
+ });
+
+ context.Services.AddAbpDynamicOptions();
+ }
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Messages/Response.SubscribeMessage.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Messages/Response.SubscribeMessage.cs
index eb1dd58a5..c854d43c9 100644
--- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Messages/Response.SubscribeMessage.cs
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Messages/Response.SubscribeMessage.cs
@@ -1,24 +1,24 @@
-using Newtonsoft.Json;
-using Volo.Abp;
-
-namespace LINGYUN.Abp.WeChat.MiniProgram.Messages
-{
- public class SubscribeMessageResponse
- {
- [JsonProperty("errcode")]
- public int ErrorCode { get; set; }
-
- [JsonProperty("errmsg")]
- public string ErrorMessage { get; set; }
-
- public bool IsSuccessed => ErrorCode == 0;
-
- public void ThrowIfNotSuccess()
- {
- if (ErrorCode != 0)
- {
- throw new AbpException($"Send wechat weapp notification error:{ErrorMessage}");
- }
- }
- }
-}
+using Newtonsoft.Json;
+using Volo.Abp;
+
+namespace LINGYUN.Abp.WeChat.MiniProgram.Messages
+{
+ public class SubscribeMessageResponse
+ {
+ [JsonProperty("errcode")]
+ public int ErrorCode { get; set; }
+
+ [JsonProperty("errmsg")]
+ public string ErrorMessage { get; set; }
+
+ public bool IsSuccessed => ErrorCode == 0;
+
+ public void ThrowIfNotSuccess()
+ {
+ if (ErrorCode != 0)
+ {
+ throw new AbpException($"Send wechat weapp notification error:{ErrorMessage}");
+ }
+ }
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Messages/SubscribeMessage.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Messages/SubscribeMessage.cs
index 36d27397c..46e4a5cb8 100644
--- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Messages/SubscribeMessage.cs
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Messages/SubscribeMessage.cs
@@ -1,106 +1,106 @@
-using Newtonsoft.Json;
-using System.Collections.Generic;
-
-namespace LINGYUN.Abp.WeChat.MiniProgram.Messages
-{
- public class SubscribeMessage
- {
- ///
- /// 接收者(用户)的 openid
- ///
- [JsonProperty("touser")]
- public string ToUser { get; set; }
- ///
- /// 所需下发的订阅模板id
- ///
- [JsonProperty("template_id")]
- public string TemplateId { get; set; }
- ///
- /// 点击模板卡片后的跳转页面,仅限本小程序内的页面。
- /// 支持带参数,(示例index?foo=bar)。
- /// 该字段不填则模板无跳转
- ///
- [JsonProperty("page")]
- public string Page { get; set; }
- ///
- /// 跳转小程序类型:
- /// developer为开发版;trial为体验版;formal为正式版;
- /// 默认为正式版
- ///
- [JsonProperty("miniprogram_state")]
- public string MiniProgramState { get; set; }
- ///
- /// 进入小程序查看”的语言类型,
- /// 支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),
- /// 默认为zh_CN
- ///
- [JsonProperty("lang")]
- public string Lang { get; set; } = "zh_CN";
- ///
- /// 模板内容,
- /// 格式形如 { "key1": { "value": any }, "key2": { "value": any } }
- ///
- [JsonProperty("data")]
- public Dictionary Data { get; set; } = new Dictionary();
-
- public SubscribeMessage() { }
- public SubscribeMessage(
- string openId,
- string templateId,
- string redirectPage = "",
- string state = "formal",
- string miniLang = "zh_CN")
- {
- ToUser = openId;
- TemplateId = templateId;
- Page = redirectPage;
- MiniProgramState = state;
- Lang = miniLang;
- }
-
- public SubscribeMessage WriteData(string prefix, string key, object value)
- {
- // 只截取符合标记的数据
- if (key.StartsWith(prefix))
- {
- key = key.Replace(prefix, "");
- if (!Data.ContainsKey(key))
- {
- Data.Add(key, new MessageData(value));
- }
- }
- return this;
- }
-
- public SubscribeMessage WriteData(string prefix, IDictionary setData)
- {
- foreach (var kv in setData)
- {
- WriteData(prefix, kv.Key, kv.Value);
- }
- return this;
- }
-
- public SubscribeMessage WriteData(IDictionary setData)
- {
- foreach (var kv in setData)
- {
- if (!Data.ContainsKey(kv.Key))
- {
- Data.Add(kv.Key, new MessageData(kv.Value));
- }
- }
- return this;
- }
- }
-
- public class MessageData
- {
- public object Value { get; }
-
- public MessageData(object value)
- {
- Value = value;
- }
- }
-}
+using Newtonsoft.Json;
+using System.Collections.Generic;
+
+namespace LINGYUN.Abp.WeChat.MiniProgram.Messages
+{
+ public class SubscribeMessage
+ {
+ ///
+ /// 接收者(用户)的 openid
+ ///
+ [JsonProperty("touser")]
+ public string ToUser { get; set; }
+ ///
+ /// 所需下发的订阅模板id
+ ///
+ [JsonProperty("template_id")]
+ public string TemplateId { get; set; }
+ ///
+ /// 点击模板卡片后的跳转页面,仅限本小程序内的页面。
+ /// 支持带参数,(示例index?foo=bar)。
+ /// 该字段不填则模板无跳转
+ ///
+ [JsonProperty("page")]
+ public string Page { get; set; }
+ ///
+ /// 跳转小程序类型:
+ /// developer为开发版;trial为体验版;formal为正式版;
+ /// 默认为正式版
+ ///
+ [JsonProperty("miniprogram_state")]
+ public string MiniProgramState { get; set; }
+ ///
+ /// 进入小程序查看”的语言类型,
+ /// 支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),
+ /// 默认为zh_CN
+ ///
+ [JsonProperty("lang")]
+ public string Lang { get; set; } = "zh_CN";
+ ///
+ /// 模板内容,
+ /// 格式形如 { "key1": { "value": any }, "key2": { "value": any } }
+ ///
+ [JsonProperty("data")]
+ public Dictionary Data { get; set; } = new Dictionary();
+
+ public SubscribeMessage() { }
+ public SubscribeMessage(
+ string openId,
+ string templateId,
+ string redirectPage = "",
+ string state = "formal",
+ string miniLang = "zh_CN")
+ {
+ ToUser = openId;
+ TemplateId = templateId;
+ Page = redirectPage;
+ MiniProgramState = state;
+ Lang = miniLang;
+ }
+
+ public SubscribeMessage WriteData(string prefix, string key, object value)
+ {
+ // 只截取符合标记的数据
+ if (key.StartsWith(prefix))
+ {
+ key = key.Replace(prefix, "");
+ if (!Data.ContainsKey(key))
+ {
+ Data.Add(key, new MessageData(value));
+ }
+ }
+ return this;
+ }
+
+ public SubscribeMessage WriteData(string prefix, IDictionary setData)
+ {
+ foreach (var kv in setData)
+ {
+ WriteData(prefix, kv.Key, kv.Value);
+ }
+ return this;
+ }
+
+ public SubscribeMessage WriteData(IDictionary setData)
+ {
+ foreach (var kv in setData)
+ {
+ if (!Data.ContainsKey(kv.Key))
+ {
+ Data.Add(kv.Key, new MessageData(kv.Value));
+ }
+ }
+ return this;
+ }
+ }
+
+ public class MessageData
+ {
+ public object Value { get; }
+
+ public MessageData(object value)
+ {
+ Value = value;
+ }
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Messages/SubscribeMessager.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Messages/SubscribeMessager.cs
index 8867c3e01..cdb1cc6ec 100644
--- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Messages/SubscribeMessager.cs
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Messages/SubscribeMessager.cs
@@ -1,121 +1,117 @@
-using LINGYUN.Abp.WeChat.OpenId;
-using LINGYUN.Abp.WeChat.Token;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Logging.Abstractions;
-using Microsoft.Extensions.Options;
-using System;
-using System.Collections.Generic;
-using System.Net.Http;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using Volo.Abp;
-using Volo.Abp.DependencyInjection;
-using Volo.Abp.Json;
-
-namespace LINGYUN.Abp.WeChat.MiniProgram.Messages
-{
- public class SubscribeMessager : ISubscribeMessager, ITransientDependency
- {
- public ILogger Logger { get; set; }
- protected IHttpClientFactory HttpClientFactory { get; }
- protected IJsonSerializer JsonSerializer { get; }
- protected AbpWeChatMiniProgramOptionsFactory MiniProgramOptionsFactory { get; }
- protected IWeChatTokenProvider WeChatTokenProvider { get; }
- protected IUserWeChatOpenIdFinder UserWeChatOpenIdFinder { get; }
- public SubscribeMessager(
- IJsonSerializer jsonSerializer,
- IHttpClientFactory httpClientFactory,
- IWeChatTokenProvider weChatTokenProvider,
- IUserWeChatOpenIdFinder userWeChatOpenIdFinder,
- AbpWeChatMiniProgramOptionsFactory miniProgramOptionsFactory)
- {
- JsonSerializer = jsonSerializer;
- HttpClientFactory = httpClientFactory;
- WeChatTokenProvider = weChatTokenProvider;
- UserWeChatOpenIdFinder = userWeChatOpenIdFinder;
- MiniProgramOptionsFactory = miniProgramOptionsFactory;
-
- Logger = NullLogger.Instance;
- }
-
- public virtual async Task SendAsync(
- Guid toUser,
- string templateId,
- string page = "",
- string lang = "zh_CN",
- string state = "formal",
- Dictionary data = null,
- CancellationToken cancellation = default)
- {
- var openId = await UserWeChatOpenIdFinder.FindByUserIdAsync(toUser, AbpWeChatMiniProgramConsts.ProviderKey);
- if (openId.IsNullOrWhiteSpace())
- {
- Logger.LogWarning("Can not found openId, Unable to send WeChat message!");
- return;
- }
- var messageData = new SubscribeMessage(openId, templateId, page, state, lang);
- if (data != null)
- {
- messageData.WriteData(data);
- }
- await SendAsync(messageData, cancellation);
- }
-
- public virtual async Task SendAsync(SubscribeMessage message, CancellationToken cancellationToken = default)
- {
- var options = await MiniProgramOptionsFactory.CreateAsync();
-
- var weChatToken = await WeChatTokenProvider.GetTokenAsync(options.AppId, options.AppSecret, cancellationToken);
- var requestParamters = new Dictionary
- {
- { "access_token", weChatToken.AccessToken }
- };
- var weChatSendNotificationUrl = "https://api.weixin.qq.com";
- var weChatSendNotificationPath = "/cgi-bin/message/subscribe/send";
- var requestUrl = BuildRequestUrl(weChatSendNotificationUrl, weChatSendNotificationPath, requestParamters);
- var responseContent = await MakeRequestAndGetResultAsync(requestUrl, message, cancellationToken);
- var response = JsonSerializer.Deserialize(responseContent);
-
- if (!response.IsSuccessed)
- {
- Logger.LogWarning("Send wechat we app subscribe message failed");
- Logger.LogWarning($"Error code: {response.ErrorCode}, message: {response.ErrorMessage}");
- }
- }
-
- protected virtual async Task MakeRequestAndGetResultAsync(string url, SubscribeMessage message, CancellationToken cancellationToken = default)
- {
- var client = HttpClientFactory.CreateClient(AbpWeChatMiniProgramConsts.HttpClient);
- var sendDataContent = JsonSerializer.Serialize(message);
- var requestContent = new StringContent(sendDataContent);
- var requestMessage = new HttpRequestMessage(HttpMethod.Post, url)
- {
- Content = requestContent
- };
-
- var response = await client.SendAsync(requestMessage, cancellationToken);
- if (!response.IsSuccessStatusCode)
- {
- throw new AbpException($"WeChat send subscribe message http request service returns error! HttpStatusCode: {response.StatusCode}, ReasonPhrase: {response.ReasonPhrase}");
- }
- var resultContent = await response.Content.ReadAsStringAsync();
-
- return resultContent;
- }
-
- protected virtual string BuildRequestUrl(string uri, string path, IDictionary paramters)
- {
- var requestUrlBuilder = new StringBuilder(128);
- requestUrlBuilder.Append(uri);
- requestUrlBuilder.Append(path).Append("?");
- foreach (var paramter in paramters)
- {
- requestUrlBuilder.AppendFormat("{0}={1}", paramter.Key, paramter.Value);
- requestUrlBuilder.Append("&");
- }
- requestUrlBuilder.Remove(requestUrlBuilder.Length - 1, 1);
- return requestUrlBuilder.ToString();
- }
- }
-}
+using LINGYUN.Abp.WeChat.OpenId;
+using LINGYUN.Abp.WeChat.Token;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Volo.Abp;
+using Volo.Abp.DependencyInjection;
+
+namespace LINGYUN.Abp.WeChat.MiniProgram.Messages
+{
+ public class SubscribeMessager : ISubscribeMessager, ITransientDependency
+ {
+ public ILogger Logger { get; set; }
+ protected IHttpClientFactory HttpClientFactory { get; }
+ protected AbpWeChatMiniProgramOptionsFactory MiniProgramOptionsFactory { get; }
+ protected IWeChatTokenProvider WeChatTokenProvider { get; }
+ protected IUserWeChatOpenIdFinder UserWeChatOpenIdFinder { get; }
+ public SubscribeMessager(
+ IHttpClientFactory httpClientFactory,
+ IWeChatTokenProvider weChatTokenProvider,
+ IUserWeChatOpenIdFinder userWeChatOpenIdFinder,
+ AbpWeChatMiniProgramOptionsFactory miniProgramOptionsFactory)
+ {
+ HttpClientFactory = httpClientFactory;
+ WeChatTokenProvider = weChatTokenProvider;
+ UserWeChatOpenIdFinder = userWeChatOpenIdFinder;
+ MiniProgramOptionsFactory = miniProgramOptionsFactory;
+
+ Logger = NullLogger.Instance;
+ }
+
+ public virtual async Task SendAsync(
+ Guid toUser,
+ string templateId,
+ string page = "",
+ string lang = "zh_CN",
+ string state = "formal",
+ Dictionary data = null,
+ CancellationToken cancellation = default)
+ {
+ var openId = await UserWeChatOpenIdFinder.FindByUserIdAsync(toUser, AbpWeChatMiniProgramConsts.ProviderName);
+ if (openId.IsNullOrWhiteSpace())
+ {
+ Logger.LogWarning("Can not found openId, Unable to send WeChat message!");
+ return;
+ }
+ var messageData = new SubscribeMessage(openId, templateId, page, state, lang);
+ if (data != null)
+ {
+ messageData.WriteData(data);
+ }
+ await SendAsync(messageData, cancellation);
+ }
+
+ public virtual async Task SendAsync(SubscribeMessage message, CancellationToken cancellationToken = default)
+ {
+ var options = await MiniProgramOptionsFactory.CreateAsync();
+
+ var weChatToken = await WeChatTokenProvider.GetTokenAsync(options.AppId, options.AppSecret, cancellationToken);
+ var requestParamters = new Dictionary
+ {
+ { "access_token", weChatToken.AccessToken }
+ };
+ var weChatSendNotificationUrl = "https://api.weixin.qq.com";
+ var weChatSendNotificationPath = "/cgi-bin/message/subscribe/send";
+ var requestUrl = BuildRequestUrl(weChatSendNotificationUrl, weChatSendNotificationPath, requestParamters);
+ var responseContent = await MakeRequestAndGetResultAsync(requestUrl, message, cancellationToken);
+ var response = JsonConvert.DeserializeObject(responseContent);
+
+ if (!response.IsSuccessed)
+ {
+ Logger.LogWarning("Send wechat we app subscribe message failed");
+ Logger.LogWarning($"Error code: {response.ErrorCode}, message: {response.ErrorMessage}");
+ }
+ }
+
+ protected virtual async Task MakeRequestAndGetResultAsync(string url, SubscribeMessage message, CancellationToken cancellationToken = default)
+ {
+ var client = HttpClientFactory.CreateClient(AbpWeChatMiniProgramConsts.HttpClient);
+ var sendDataContent = JsonConvert.SerializeObject(message);
+ var requestContent = new StringContent(sendDataContent);
+ var requestMessage = new HttpRequestMessage(HttpMethod.Post, url)
+ {
+ Content = requestContent
+ };
+
+ var response = await client.SendAsync(requestMessage, cancellationToken);
+ if (!response.IsSuccessStatusCode)
+ {
+ throw new AbpException($"WeChat send subscribe message http request service returns error! HttpStatusCode: {response.StatusCode}, ReasonPhrase: {response.ReasonPhrase}");
+ }
+ var resultContent = await response.Content.ReadAsStringAsync();
+
+ return resultContent;
+ }
+
+ protected virtual string BuildRequestUrl(string uri, string path, IDictionary paramters)
+ {
+ var requestUrlBuilder = new StringBuilder(128);
+ requestUrlBuilder.Append(uri);
+ requestUrlBuilder.Append(path).Append("?");
+ foreach (var paramter in paramters)
+ {
+ requestUrlBuilder.AppendFormat("{0}={1}", paramter.Key, paramter.Value);
+ requestUrlBuilder.Append("&");
+ }
+ requestUrlBuilder.Remove(requestUrlBuilder.Length - 1, 1);
+ return requestUrlBuilder.ToString();
+ }
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/AbpWeChatOfficialConsts.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/AbpWeChatOfficialConsts.cs
index d57bf895e..7f3e73c3a 100644
--- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/AbpWeChatOfficialConsts.cs
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/AbpWeChatOfficialConsts.cs
@@ -1,22 +1,22 @@
-namespace LINGYUN.Abp.WeChat.Official
-{
- public class AbpWeChatOfficialConsts
- {
- ///
- /// 微信公众号对应的Provider名称
- ///
- public static string ProviderKey { get; set; } = "WeChat.Official";
-
- ///
- /// 微信公众平台授权类型
- ///
- public static string GrantType { get; set; } = "wx-op";
-
- ///
- /// 微信公众平台授权方法名称
- ///
- public static string AuthenticationMethod { get; set; } = "woa";
-
- public static string HttpClient { get; set; } = "Abp.WeChat.Official";
- }
-}
+namespace LINGYUN.Abp.WeChat.Official
+{
+ public class AbpWeChatOfficialConsts
+ {
+ ///
+ /// 微信公众号对应的Provider名称
+ ///
+ public static string ProviderName { get; set; } = "WeChat.Official";
+
+ ///
+ /// 微信公众平台授权类型
+ ///
+ public static string GrantType { get; set; } = "wx-op";
+
+ ///
+ /// 微信公众平台授权方法名称
+ ///
+ public static string AuthenticationMethod { get; set; } = "woa";
+
+ public static string HttpClient { get; set; } = "Abp.WeChat.Official";
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.SettingManagement/LINGYUN/Abp/WeChat/SettingManagement/WeChatSettingAppService.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.SettingManagement/LINGYUN/Abp/WeChat/SettingManagement/WeChatSettingAppService.cs
index fcc80fe8b..5b6b4263c 100644
--- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.SettingManagement/LINGYUN/Abp/WeChat/SettingManagement/WeChatSettingAppService.cs
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.SettingManagement/LINGYUN/Abp/WeChat/SettingManagement/WeChatSettingAppService.cs
@@ -1,116 +1,124 @@
-using LINGYUN.Abp.SettingManagement;
-using LINGYUN.Abp.WeChat.Localization;
-using LINGYUN.Abp.WeChat.MiniProgram.Settings;
-using LINGYUN.Abp.WeChat.Official.Settings;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using Volo.Abp.Application.Dtos;
-using Volo.Abp.Application.Services;
-using Volo.Abp.Authorization.Permissions;
-using Volo.Abp.MultiTenancy;
-using Volo.Abp.SettingManagement;
-using Volo.Abp.Settings;
-
-namespace LINGYUN.Abp.WeChat.SettingManagement
-{
- public class WeChatSettingAppService : ApplicationService, IWeChatSettingAppService
- {
- protected ISettingManager SettingManager { get; }
- protected IPermissionChecker PermissionChecker { get; }
- protected ISettingDefinitionManager SettingDefinitionManager { get; }
-
- public WeChatSettingAppService(
- ISettingManager settingManager,
- IPermissionChecker permissionChecker,
- ISettingDefinitionManager settingDefinitionManager)
- {
- SettingManager = settingManager;
- PermissionChecker = permissionChecker;
- SettingDefinitionManager = settingDefinitionManager;
- LocalizationResource = typeof(WeChatResource);
- }
-
- public virtual async Task> GetAllForCurrentTenantAsync()
- {
- return await GetAllForProviderAsync(TenantSettingValueProvider.ProviderName, CurrentTenant.GetId().ToString());
- }
-
- public virtual async Task> GetAllForGlobalAsync()
- {
- return await GetAllForProviderAsync(GlobalSettingValueProvider.ProviderName, null);
- }
-
- protected virtual async Task> GetAllForProviderAsync(string providerName, string providerKey)
- {
- var settingGroups = new List();
- var wechatSettingGroup = new SettingGroupDto(L["DisplayName:WeChat"], L["Description:WeChat"]);
-
- // 无权限返回空结果,直接报错的话,网关聚合会抛出异常
- if (await PermissionChecker.IsGrantedAsync(WeChatSettingPermissionNames.Official))
- {
- #region 公众号
-
- var officialSetting = wechatSettingGroup.AddSetting(L["DisplayName:WeChat.Official"], L["Description:WeChat.Official"]);
- officialSetting.AddDetail(
- SettingDefinitionManager.Get(WeChatOfficialSettingNames.AppId),
- StringLocalizerFactory,
- await SettingManager.GetOrNullAsync(WeChatOfficialSettingNames.AppId, providerName, providerKey),
- ValueType.String);
- officialSetting.AddDetail(
- SettingDefinitionManager.Get(WeChatOfficialSettingNames.AppSecret),
- StringLocalizerFactory,
- await SettingManager.GetOrNullAsync(WeChatOfficialSettingNames.AppSecret, providerName, providerKey),
- ValueType.String);
- officialSetting.AddDetail(
- SettingDefinitionManager.Get(WeChatOfficialSettingNames.Url),
- StringLocalizerFactory,
- await SettingManager.GetOrNullAsync(WeChatOfficialSettingNames.Url, providerName, providerKey),
- ValueType.String);
- officialSetting.AddDetail(
- SettingDefinitionManager.Get(WeChatOfficialSettingNames.Token),
- StringLocalizerFactory,
- await SettingManager.GetOrNullAsync(WeChatOfficialSettingNames.Token, providerName, providerKey),
- ValueType.String);
- officialSetting.AddDetail(
- SettingDefinitionManager.Get(WeChatOfficialSettingNames.EncodingAESKey),
- StringLocalizerFactory,
- await SettingManager.GetOrNullAsync(WeChatOfficialSettingNames.EncodingAESKey, providerName, providerKey),
- ValueType.String);
-
- #endregion
- }
-
- if (await PermissionChecker.IsGrantedAsync(WeChatSettingPermissionNames.MiniProgram))
- {
- #region 小程序
-
- var miniProgramSetting = wechatSettingGroup.AddSetting(L["DisplayName:WeChat.MiniProgram"], L["Description:WeChat.MiniProgram"]);
- miniProgramSetting.AddDetail(
- SettingDefinitionManager.Get(WeChatMiniProgramSettingNames.AppId),
- StringLocalizerFactory,
- await SettingManager.GetOrNullAsync(WeChatMiniProgramSettingNames.AppId, providerName, providerKey),
- ValueType.String);
- miniProgramSetting.AddDetail(
- SettingDefinitionManager.Get(WeChatMiniProgramSettingNames.AppSecret),
- StringLocalizerFactory,
- await SettingManager.GetOrNullAsync(WeChatMiniProgramSettingNames.AppSecret, providerName, providerKey),
- ValueType.String);
- miniProgramSetting.AddDetail(
- SettingDefinitionManager.Get(WeChatMiniProgramSettingNames.Token),
- StringLocalizerFactory,
- await SettingManager.GetOrNullAsync(WeChatMiniProgramSettingNames.Token, providerName, providerKey),
- ValueType.String);
- miniProgramSetting.AddDetail(
- SettingDefinitionManager.Get(WeChatMiniProgramSettingNames.EncodingAESKey),
- StringLocalizerFactory,
- await SettingManager.GetOrNullAsync(WeChatMiniProgramSettingNames.EncodingAESKey, providerName, providerKey),
- ValueType.String);
-
- #endregion
- }
-
- settingGroups.Add(wechatSettingGroup);
- return new ListResultDto(settingGroups);
- }
- }
-}
+using LINGYUN.Abp.SettingManagement;
+using LINGYUN.Abp.WeChat.Localization;
+using LINGYUN.Abp.WeChat.MiniProgram.Settings;
+using LINGYUN.Abp.WeChat.Official.Settings;
+using LINGYUN.Abp.WeChat.Settings;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Dtos;
+using Volo.Abp.Application.Services;
+using Volo.Abp.Authorization.Permissions;
+using Volo.Abp.MultiTenancy;
+using Volo.Abp.SettingManagement;
+using Volo.Abp.Settings;
+
+namespace LINGYUN.Abp.WeChat.SettingManagement
+{
+ public class WeChatSettingAppService : ApplicationService, IWeChatSettingAppService
+ {
+ protected ISettingManager SettingManager { get; }
+ protected IPermissionChecker PermissionChecker { get; }
+ protected ISettingDefinitionManager SettingDefinitionManager { get; }
+
+ public WeChatSettingAppService(
+ ISettingManager settingManager,
+ IPermissionChecker permissionChecker,
+ ISettingDefinitionManager settingDefinitionManager)
+ {
+ SettingManager = settingManager;
+ PermissionChecker = permissionChecker;
+ SettingDefinitionManager = settingDefinitionManager;
+ LocalizationResource = typeof(WeChatResource);
+ }
+
+ public virtual async Task> GetAllForCurrentTenantAsync()
+ {
+ return await GetAllForProviderAsync(TenantSettingValueProvider.ProviderName, CurrentTenant.GetId().ToString());
+ }
+
+ public virtual async Task> GetAllForGlobalAsync()
+ {
+ return await GetAllForProviderAsync(GlobalSettingValueProvider.ProviderName, null);
+ }
+
+ protected virtual async Task> GetAllForProviderAsync(string providerName, string providerKey)
+ {
+ var settingGroups = new List();
+ var wechatSettingGroup = new SettingGroupDto(L["DisplayName:WeChat"], L["Description:WeChat"]);
+
+ var loginSetting = wechatSettingGroup.AddSetting(L["UserLogin"], L["UserLogin"]);
+ loginSetting.AddDetail(
+ SettingDefinitionManager.Get(WeChatSettingNames.EnabledQuickLogin),
+ StringLocalizerFactory,
+ await SettingManager.GetOrNullAsync(WeChatSettingNames.EnabledQuickLogin, providerName, providerKey),
+ ValueType.Boolean);
+
+ // 无权限返回空结果,直接报错的话,网关聚合会抛出异常
+ if (await PermissionChecker.IsGrantedAsync(WeChatSettingPermissionNames.Official))
+ {
+ #region 公众号
+
+ var officialSetting = wechatSettingGroup.AddSetting(L["DisplayName:WeChat.Official"], L["Description:WeChat.Official"]);
+ officialSetting.AddDetail(
+ SettingDefinitionManager.Get(WeChatOfficialSettingNames.AppId),
+ StringLocalizerFactory,
+ await SettingManager.GetOrNullAsync(WeChatOfficialSettingNames.AppId, providerName, providerKey),
+ ValueType.String);
+ officialSetting.AddDetail(
+ SettingDefinitionManager.Get(WeChatOfficialSettingNames.AppSecret),
+ StringLocalizerFactory,
+ await SettingManager.GetOrNullAsync(WeChatOfficialSettingNames.AppSecret, providerName, providerKey),
+ ValueType.String);
+ officialSetting.AddDetail(
+ SettingDefinitionManager.Get(WeChatOfficialSettingNames.Url),
+ StringLocalizerFactory,
+ await SettingManager.GetOrNullAsync(WeChatOfficialSettingNames.Url, providerName, providerKey),
+ ValueType.String);
+ officialSetting.AddDetail(
+ SettingDefinitionManager.Get(WeChatOfficialSettingNames.Token),
+ StringLocalizerFactory,
+ await SettingManager.GetOrNullAsync(WeChatOfficialSettingNames.Token, providerName, providerKey),
+ ValueType.String);
+ officialSetting.AddDetail(
+ SettingDefinitionManager.Get(WeChatOfficialSettingNames.EncodingAESKey),
+ StringLocalizerFactory,
+ await SettingManager.GetOrNullAsync(WeChatOfficialSettingNames.EncodingAESKey, providerName, providerKey),
+ ValueType.String);
+
+ #endregion
+ }
+
+ if (await PermissionChecker.IsGrantedAsync(WeChatSettingPermissionNames.MiniProgram))
+ {
+ #region 小程序
+
+ var miniProgramSetting = wechatSettingGroup.AddSetting(L["DisplayName:WeChat.MiniProgram"], L["Description:WeChat.MiniProgram"]);
+ miniProgramSetting.AddDetail(
+ SettingDefinitionManager.Get(WeChatMiniProgramSettingNames.AppId),
+ StringLocalizerFactory,
+ await SettingManager.GetOrNullAsync(WeChatMiniProgramSettingNames.AppId, providerName, providerKey),
+ ValueType.String);
+ miniProgramSetting.AddDetail(
+ SettingDefinitionManager.Get(WeChatMiniProgramSettingNames.AppSecret),
+ StringLocalizerFactory,
+ await SettingManager.GetOrNullAsync(WeChatMiniProgramSettingNames.AppSecret, providerName, providerKey),
+ ValueType.String);
+ miniProgramSetting.AddDetail(
+ SettingDefinitionManager.Get(WeChatMiniProgramSettingNames.Token),
+ StringLocalizerFactory,
+ await SettingManager.GetOrNullAsync(WeChatMiniProgramSettingNames.Token, providerName, providerKey),
+ ValueType.String);
+ miniProgramSetting.AddDetail(
+ SettingDefinitionManager.Get(WeChatMiniProgramSettingNames.EncodingAESKey),
+ StringLocalizerFactory,
+ await SettingManager.GetOrNullAsync(WeChatMiniProgramSettingNames.EncodingAESKey, providerName, providerKey),
+ ValueType.String);
+
+ #endregion
+ }
+
+ settingGroups.Add(wechatSettingGroup);
+ return new ListResultDto(settingGroups);
+ }
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/AbpWeChatModule.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/AbpWeChatModule.cs
index 5a5805d4b..f72cbcb8c 100644
--- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/AbpWeChatModule.cs
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/AbpWeChatModule.cs
@@ -1,42 +1,44 @@
-using LINGYUN.Abp.WeChat.Localization;
-using Microsoft.Extensions.DependencyInjection;
-using Polly;
-using System;
-using Volo.Abp.Caching;
-using Volo.Abp.Features;
-using Volo.Abp.Json;
-using Volo.Abp.Localization;
-using Volo.Abp.Modularity;
-using Volo.Abp.VirtualFileSystem;
-
-namespace LINGYUN.Abp.WeChat
-{
- [DependsOn(
- typeof(AbpCachingModule),
- typeof(AbpFeaturesModule),
- typeof(AbpJsonModule))]
- public class AbpWeChatModule : AbpModule
- {
- public override void ConfigureServices(ServiceConfigurationContext context)
- {
- Configure(options =>
- {
- options.FileSets.AddEmbedded();
- });
-
- Configure(options =>
- {
- options.Resources
- .Add("zh-Hans")
- .AddVirtualJson("/LINGYUN/Abp/WeChat/Localization/Resources");
- });
-
- context.Services.AddHttpClient(AbpWeChatGlobalConsts.HttpClient,
- options =>
- {
- options.BaseAddress = new Uri("https://api.weixin.qq.com");
- }).AddTransientHttpErrorPolicy(builder =>
- builder.WaitAndRetryAsync(3, i => TimeSpan.FromSeconds(Math.Pow(2, i))));
- }
- }
-}
+using LINGYUN.Abp.WeChat.Localization;
+using Microsoft.Extensions.DependencyInjection;
+using Polly;
+using System;
+using Volo.Abp.Caching;
+using Volo.Abp.Features;
+using Volo.Abp.Json;
+using Volo.Abp.Localization;
+using Volo.Abp.Modularity;
+using Volo.Abp.Settings;
+using Volo.Abp.VirtualFileSystem;
+
+namespace LINGYUN.Abp.WeChat
+{
+ [DependsOn(
+ typeof(AbpCachingModule),
+ typeof(AbpFeaturesModule),
+ typeof(AbpJsonModule),
+ typeof(AbpSettingsModule))]
+ public class AbpWeChatModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options =>
+ {
+ options.FileSets.AddEmbedded();
+ });
+
+ Configure(options =>
+ {
+ options.Resources
+ .Add("zh-Hans")
+ .AddVirtualJson("/LINGYUN/Abp/WeChat/Localization/Resources");
+ });
+
+ context.Services.AddHttpClient(AbpWeChatGlobalConsts.HttpClient,
+ options =>
+ {
+ options.BaseAddress = new Uri("https://api.weixin.qq.com");
+ }).AddTransientHttpErrorPolicy(builder =>
+ builder.WaitAndRetryAsync(3, i => TimeSpan.FromSeconds(Math.Pow(2, i))));
+ }
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Crypto/IWeChatCryptoService.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Crypto/IWeChatCryptoService.cs
new file mode 100644
index 000000000..ffa0c39c1
--- /dev/null
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Crypto/IWeChatCryptoService.cs
@@ -0,0 +1,7 @@
+namespace LINGYUN.Abp.WeChat.Crypto
+{
+ public interface IWeChatCryptoService
+ {
+ string Decrypt(string encryptedData, string iv, string sessionKey);
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Crypto/WeChatCryptoService.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Crypto/WeChatCryptoService.cs
new file mode 100644
index 000000000..65fcb9789
--- /dev/null
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Crypto/WeChatCryptoService.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Security.Cryptography;
+using System.Text;
+using Volo.Abp.DependencyInjection;
+
+namespace LINGYUN.Abp.WeChat.Crypto
+{
+ public class WeChatCryptoService : IWeChatCryptoService, ITransientDependency
+ {
+ public virtual string Decrypt(string encryptedData, string iv, string sessionKey)
+ {
+ using var aes = new AesCryptoServiceProvider();
+ aes.Mode = CipherMode.CBC;
+ aes.BlockSize = 128;
+ // 对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充。
+ aes.Padding = PaddingMode.PKCS7;
+
+ //格式化待处理字符串
+ // 对称解密的目标密文为 Base64_Decode(encryptedData)。
+ byte[] byte_encryptedData = Convert.FromBase64String(encryptedData);
+ // 对称解密算法初始向量 为Base64_Decode(iv),其中iv由数据接口返回。
+ byte[] byte_iv = Convert.FromBase64String(iv);
+ // 对称解密秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节。
+ byte[] byte_sessionKey = Convert.FromBase64String(sessionKey);
+
+ //根据设置好的数据生成解密器实例
+ using var transform = aes.CreateDecryptor(byte_iv, byte_sessionKey);
+ //解密
+ byte[] final = transform.TransformFinalBlock(byte_encryptedData, 0, byte_encryptedData.Length);
+
+ //生成结果
+ string result = Encoding.UTF8.GetString(final);
+ return result;
+ }
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Localization/Resources/en.json b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Localization/Resources/en.json
index cfdf39b93..08d22a9e3 100644
--- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Localization/Resources/en.json
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Localization/Resources/en.json
@@ -4,6 +4,9 @@
"Features:WeChat": "WeChat",
"Permission:WeChat": "WeChat",
"DisplayName:WeChat": "WeChat",
- "Description:WeChat": "WeChat"
+ "Description:WeChat": "WeChat",
+ "UserLogin": "User Login",
+ "DisplayName:WeChat.EnabledQuickLogin": "Enabled Quick Login",
+ "Description:WeChat.EnabledQuickLogin": "Users can login directly with the code given by wx.login when they are not registered"
}
}
\ No newline at end of file
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Localization/Resources/zh-Hans.json b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Localization/Resources/zh-Hans.json
index f84b1ef39..81c06a287 100644
--- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Localization/Resources/zh-Hans.json
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Localization/Resources/zh-Hans.json
@@ -4,6 +4,9 @@
"Features:WeChat": "微信开发",
"Permission:WeChat": "微信开发",
"DisplayName:WeChat": "微信开发平台",
- "Description:WeChat": "微信开发平台"
+ "Description:WeChat": "微信开发平台",
+ "UserLogin": "用户登录",
+ "DisplayName:WeChat.EnabledQuickLogin": "启用快捷登录",
+ "Description:WeChat.EnabledQuickLogin": "用户可在未注册时通过 wx.login 得到的code直接登录"
}
}
\ No newline at end of file
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/IUserWeChatOpenIdFinder.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/IUserWeChatOpenIdFinder.cs
index 79f2c703f..01312a458 100644
--- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/IUserWeChatOpenIdFinder.cs
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/IUserWeChatOpenIdFinder.cs
@@ -1,12 +1,12 @@
-using System;
-using System.Threading.Tasks;
-
-namespace LINGYUN.Abp.WeChat.OpenId
-{
- public interface IUserWeChatOpenIdFinder
- {
- Task FindByUserIdAsync(Guid userId, string provider);
-
- Task FindByUserNameAsync(string userName, string provider);
- }
-}
+using System;
+using System.Threading.Tasks;
+
+namespace LINGYUN.Abp.WeChat.OpenId
+{
+ public interface IUserWeChatOpenIdFinder
+ {
+ Task FindByUserIdAsync(Guid userId, string provider);
+
+ Task FindByUserNameAsync(string userName, string provider);
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/IWeChatOpenIdFinder.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/IWeChatOpenIdFinder.cs
index da2a0fc9c..3d1d5fcc0 100644
--- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/IWeChatOpenIdFinder.cs
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/IWeChatOpenIdFinder.cs
@@ -1,9 +1,17 @@
-using System.Threading.Tasks;
-
-namespace LINGYUN.Abp.WeChat.OpenId
-{
- public interface IWeChatOpenIdFinder
- {
- Task FindAsync(string code, string appId, string appSecret);
- }
-}
+using System.Threading.Tasks;
+
+namespace LINGYUN.Abp.WeChat.OpenId
+{
+ public interface IWeChatOpenIdFinder
+ {
+ Task FindAsync(string code, string appId, string appSecret);
+ ///
+ /// 获取当前登录用户OpenId
+ ///
+ /// 应用标识
+ ///
+ /// 用户未登录时
+ /// 微信sessionKey过期时
+ Task FindAsync(string appId);
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/WeChatOpenIdCacheItem.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/WeChatOpenIdCacheItem.cs
index 76ddc5492..6aed88126 100644
--- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/WeChatOpenIdCacheItem.cs
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/WeChatOpenIdCacheItem.cs
@@ -1,24 +1,32 @@
-namespace LINGYUN.Abp.WeChat.OpenId
-{
- public class WeChatOpenIdCacheItem
- {
- public string Code { get; set; }
-
- public WeChatOpenId WeChatOpenId { get; set; }
- public WeChatOpenIdCacheItem()
- {
-
- }
-
- public WeChatOpenIdCacheItem(string code, WeChatOpenId weChatOpenId)
- {
- Code = code;
- WeChatOpenId = weChatOpenId;
- }
-
- public static string CalculateCacheKey(string appId, string code)
- {
- return "app:" + appId + ";code:" + code;
- }
- }
-}
+using System;
+
+namespace LINGYUN.Abp.WeChat.OpenId
+{
+ public class WeChatOpenIdCacheItem
+ {
+ public string Code { get; set; }
+
+ public WeChatOpenId WeChatOpenId { get; set; }
+ public WeChatOpenIdCacheItem()
+ {
+
+ }
+
+ public WeChatOpenIdCacheItem(string code, WeChatOpenId weChatOpenId)
+ {
+ Code = code;
+ WeChatOpenId = weChatOpenId;
+ }
+
+ public static string CalculateCacheKey(string appId, Guid userId)
+ {
+ return "app:" + appId + ";user:" + userId.ToString("D");
+ }
+
+
+ public static string CalculateCacheKey(string appId, string code)
+ {
+ return "app:" + appId + ";code:" + code;
+ }
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/WeChatOpenIdFinder.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/WeChatOpenIdFinder.cs
index f0d9c68cd..d3934940e 100644
--- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/WeChatOpenIdFinder.cs
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/WeChatOpenIdFinder.cs
@@ -1,95 +1,117 @@
-using Microsoft.Extensions.Caching.Distributed;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Logging.Abstractions;
-using System;
-using System.Net.Http;
-using System.Threading.Tasks;
-using Volo.Abp.Caching;
-using Volo.Abp.DependencyInjection;
-using Volo.Abp.Json;
-using Volo.Abp.MultiTenancy;
-
-namespace LINGYUN.Abp.WeChat.OpenId
-{
- [Dependency(ServiceLifetime.Singleton, ReplaceServices = true)]
- [ExposeServices(typeof(IWeChatOpenIdFinder))]
- public class WeChatOpenIdFinder : IWeChatOpenIdFinder
- {
- public ILogger Logger { get; set; }
- protected ICurrentTenant CurrentTenant { get; }
- protected IHttpClientFactory HttpClientFactory { get; }
- protected IJsonSerializer JsonSerializer { get; }
- protected IDistributedCache Cache { get; }
- public WeChatOpenIdFinder(
- ICurrentTenant currentTenant,
- IJsonSerializer jsonSerializer,
- IHttpClientFactory httpClientFactory,
- IDistributedCache cache)
- {
- CurrentTenant = currentTenant;
- JsonSerializer = jsonSerializer;
- HttpClientFactory = httpClientFactory;
-
- Cache = cache;
-
- Logger = NullLogger.Instance;
- }
- public virtual async Task FindAsync(string code, string appId, string appSecret)
- {
- // TODO: 如果需要获取SessionKey的话呢,需要再以openid作为标识来缓存一下吗
- // 或者前端保存code,通过传递code来获取
- return (await GetCacheItemAsync(code, appId, appSecret)).WeChatOpenId;
- }
-
- protected virtual async Task GetCacheItemAsync(string code, string appId, string appSecret)
- {
- var cacheKey = WeChatOpenIdCacheItem.CalculateCacheKey(appId, code);
-
- Logger.LogDebug($"WeChatOpenIdFinder.GetCacheItemAsync: {cacheKey}");
-
- var cacheItem = await Cache.GetAsync(cacheKey);
-
- if (cacheItem != null)
- {
- Logger.LogDebug($"Found in the cache: {cacheKey}");
- return cacheItem;
- }
-
- Logger.LogDebug($"Not found in the cache, getting from the httpClient: {cacheKey}");
-
- var client = HttpClientFactory.CreateClient(AbpWeChatGlobalConsts.HttpClient);
-
- var request = new WeChatOpenIdRequest
- {
- BaseUrl = client.BaseAddress.AbsoluteUri,
- AppId = appId,
- Secret = appSecret,
- Code = code
- };
-
- var response = await client.RequestWeChatOpenIdAsync(request);
- var responseContent = await response.Content.ReadAsStringAsync();
- var weChatOpenIdResponse = JsonSerializer.Deserialize(responseContent);
- var weChatOpenId = weChatOpenIdResponse.ToWeChatOpenId();
- cacheItem = new WeChatOpenIdCacheItem(code, weChatOpenId);
-
- Logger.LogDebug($"Setting the cache item: {cacheKey}");
-
- var cacheOptions = new DistributedCacheEntryOptions
- {
- // 微信官方文档表示 session_key的有效期是3天
- // https://developers.weixin.qq.com/community/develop/doc/000c2424654c40bd9c960e71e5b009
- AbsoluteExpiration = DateTimeOffset.Now.AddDays(3).AddSeconds(-120)
- // SlidingExpiration = TimeSpan.FromDays(3),
- };
-
-
- await Cache.SetAsync(cacheKey, cacheItem, cacheOptions);
-
- Logger.LogDebug($"Finished setting the cache item: {cacheKey}");
-
- return cacheItem;
- }
- }
-}
+using Microsoft.Extensions.Caching.Distributed;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using Newtonsoft.Json;
+using System;
+using System.Net.Http;
+using System.Threading.Tasks;
+using Volo.Abp;
+using Volo.Abp.Authorization;
+using Volo.Abp.Caching;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.MultiTenancy;
+using Volo.Abp.Users;
+
+namespace LINGYUN.Abp.WeChat.OpenId
+{
+ [Dependency(ServiceLifetime.Singleton, ReplaceServices = true)]
+ [ExposeServices(typeof(IWeChatOpenIdFinder))]
+ public class WeChatOpenIdFinder : IWeChatOpenIdFinder
+ {
+ public ILogger Logger { get; set; }
+ protected ICurrentTenant CurrentTenant { get; }
+ protected ICurrentUser CurrentUser { get; }
+ protected IHttpClientFactory HttpClientFactory { get; }
+ protected IDistributedCache Cache { get; }
+ public WeChatOpenIdFinder(
+ ICurrentUser currentUser,
+ ICurrentTenant currentTenant,
+ IHttpClientFactory httpClientFactory,
+ IDistributedCache cache)
+ {
+ CurrentUser = currentUser;
+ CurrentTenant = currentTenant;
+ HttpClientFactory = httpClientFactory;
+
+ Cache = cache;
+
+ Logger = NullLogger.Instance;
+ }
+
+ public virtual async Task FindAsync(string appId)
+ {
+ if (!CurrentUser.IsAuthenticated)
+ {
+ throw new AbpAuthorizationException("Try to get wechat information when the user is not logged in!");
+ }
+ var cacheKey = WeChatOpenIdCacheItem.CalculateCacheKey(appId, CurrentUser.Id.Value);
+ var openIdCache = await Cache.GetAsync(cacheKey);
+ return openIdCache?.WeChatOpenId ??
+ throw new AbpException("The wechat login session has expired. Use 'wx.login' result code to exchange the sessionKey");
+ }
+
+ public virtual async Task FindAsync(string code, string appId, string appSecret)
+ {
+ // TODO: 如果需要获取SessionKey的话呢,需要再以openid作为标识来缓存一下吗
+ // 或者前端保存code,通过传递code来获取
+ return (await GetCacheItemAsync(code, appId, appSecret)).WeChatOpenId;
+ }
+
+ protected virtual async Task GetCacheItemAsync(string code, string appId, string appSecret)
+ {
+ var cacheKey = WeChatOpenIdCacheItem.CalculateCacheKey(appId, code);
+
+ Logger.LogDebug($"WeChatOpenIdFinder.GetCacheItemAsync: {cacheKey}");
+
+ var cacheItem = await Cache.GetAsync(cacheKey);
+
+ if (cacheItem != null)
+ {
+ Logger.LogDebug($"Found in the cache: {cacheKey}");
+ return cacheItem;
+ }
+
+ Logger.LogDebug($"Not found in the cache, getting from the httpClient: {cacheKey}");
+
+ var client = HttpClientFactory.CreateClient(AbpWeChatGlobalConsts.HttpClient);
+
+ var request = new WeChatOpenIdRequest
+ {
+ BaseUrl = client.BaseAddress.AbsoluteUri,
+ AppId = appId,
+ Secret = appSecret,
+ Code = code
+ };
+
+ var response = await client.RequestWeChatOpenIdAsync(request);
+ var responseContent = await response.Content.ReadAsStringAsync();
+ // 改为直接引用 Newtownsoft.Json
+ var weChatOpenIdResponse = JsonConvert.DeserializeObject(responseContent);
+ var weChatOpenId = weChatOpenIdResponse.ToWeChatOpenId();
+ cacheItem = new WeChatOpenIdCacheItem(code, weChatOpenId);
+
+ Logger.LogDebug($"Setting the cache item: {cacheKey}");
+
+ var cacheOptions = new DistributedCacheEntryOptions
+ {
+ // 微信官方文档表示 session_key的有效期是3天
+ // https://developers.weixin.qq.com/community/develop/doc/000c2424654c40bd9c960e71e5b009
+ AbsoluteExpiration = DateTimeOffset.Now.AddDays(3).AddSeconds(-120)
+ // SlidingExpiration = TimeSpan.FromDays(3),
+ };
+
+
+ await Cache.SetAsync(cacheKey, cacheItem, cacheOptions);
+
+ if (CurrentUser.IsAuthenticated)
+ {
+ await Cache.SetAsync(WeChatOpenIdCacheItem.CalculateCacheKey(appId, CurrentUser.Id.Value), cacheItem, cacheOptions);
+ }
+
+ Logger.LogDebug($"Finished setting the cache item: {cacheKey}");
+
+ return cacheItem;
+ }
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/WeChatOpenIdResponse.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/WeChatOpenIdResponse.cs
index d00bc54d9..4556795a4 100644
--- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/WeChatOpenIdResponse.cs
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/WeChatOpenIdResponse.cs
@@ -1,63 +1,63 @@
-using Newtonsoft.Json;
-using System;
-using Volo.Abp;
-
-namespace LINGYUN.Abp.WeChat.OpenId
-{
- ///
- /// 微信OpenId返回对象
- ///
- public class WeChatOpenIdResponse
- {
- ///
- /// 错误码
- ///
- [JsonProperty("errcode")]
- public string ErrorCode { get; set; }
- ///
- /// 会话密钥
- ///
- [JsonProperty("session_key")]
- public string SessionKey { get; set; }
- ///
- /// 用户唯一标识
- ///
- [JsonProperty("openid")]
- public string OpenId { get; set; }
- ///
- /// 用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回
- ///
- [JsonProperty("unionid")]
- public string UnionId { get; set; }
- ///
- /// 错误消息
- ///
- public string ErrorMessage
- {
- get
- {
- switch (ErrorCode)
- {
- case "-1": return "系统繁忙,此时请开发者稍候再试";
- case "0": return string.Empty;
- case "40029": return "code 无效";
- case "45011": return "频率限制,每个用户每分钟100次";
- default: return $"未定义的异常代码:{ErrorCode},请重试";
- };
- }
- }
- ///
- /// 微信认证成功没有errorcode或者errorcode为0
- ///
- public bool IsError => !ErrorCode.IsNullOrWhiteSpace() && !"0".Equals(ErrorCode);
-
- public WeChatOpenId ToWeChatOpenId()
- {
- if(IsError)
- {
- throw new AbpException(ErrorMessage);
- }
- return new WeChatOpenId(OpenId, SessionKey, UnionId);
- }
- }
-}
+using Newtonsoft.Json;
+using System;
+using Volo.Abp;
+
+namespace LINGYUN.Abp.WeChat.OpenId
+{
+ ///
+ /// 微信OpenId返回对象
+ ///
+ public class WeChatOpenIdResponse
+ {
+ ///
+ /// 错误码
+ ///
+ [JsonProperty("errcode")]
+ public string ErrorCode { get; set; }
+ ///
+ /// 会话密钥
+ ///
+ [JsonProperty("session_key")]
+ public string SessionKey { get; set; }
+ ///
+ /// 用户唯一标识
+ ///
+ [JsonProperty("openid")]
+ public string OpenId { get; set; }
+ ///
+ /// 用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回
+ ///
+ [JsonProperty("unionid")]
+ public string UnionId { get; set; }
+ ///
+ /// 错误消息
+ ///
+ public string ErrorMessage
+ {
+ get
+ {
+ switch (ErrorCode)
+ {
+ case "-1": return "系统繁忙,此时请开发者稍候再试";
+ case "0": return string.Empty;
+ case "40029": return "code 无效";
+ case "45011": return "频率限制,每个用户每分钟100次";
+ default: return $"未定义的异常代码:{ErrorCode},请重试";
+ };
+ }
+ }
+ ///
+ /// 微信认证成功没有errorcode或者errorcode为0
+ ///
+ public bool IsError => !ErrorCode.IsNullOrWhiteSpace() && !"0".Equals(ErrorCode);
+
+ public WeChatOpenId ToWeChatOpenId()
+ {
+ if(IsError)
+ {
+ throw new AbpException(ErrorMessage);
+ }
+ return new WeChatOpenId(OpenId, SessionKey, UnionId);
+ }
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Settings/WeChatSettingDefinitionProvider.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Settings/WeChatSettingDefinitionProvider.cs
new file mode 100644
index 000000000..44b2731c4
--- /dev/null
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Settings/WeChatSettingDefinitionProvider.cs
@@ -0,0 +1,28 @@
+using LINGYUN.Abp.WeChat.Localization;
+using Volo.Abp.Localization;
+using Volo.Abp.Settings;
+
+namespace LINGYUN.Abp.WeChat.Settings
+{
+ public class WeChatSettingDefinitionProvider : SettingDefinitionProvider
+ {
+ public override void Define(ISettingDefinitionContext context)
+ {
+ context.Add(
+ new SettingDefinition(
+ WeChatSettingNames.EnabledQuickLogin,
+ // 默认启用
+ true.ToString(),
+ L("DisplayName:WeChat.EnabledQuickLogin"),
+ L("Description:WeChat.EnabledQuickLogin"),
+ isVisibleToClients: true,
+ isEncrypted: false)
+ );
+ }
+
+ protected ILocalizableString L(string name)
+ {
+ return LocalizableString.Create(name);
+ }
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Settings/WeChatSettingNames.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Settings/WeChatSettingNames.cs
index 416eb4854..b0bc42bef 100644
--- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Settings/WeChatSettingNames.cs
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Settings/WeChatSettingNames.cs
@@ -1,7 +1,12 @@
-namespace LINGYUN.Abp.WeChat.Settings
-{
- public static class WeChatSettingNames
- {
- public const string Prefix = "Abp.WeChat";
- }
-}
+namespace LINGYUN.Abp.WeChat.Settings
+{
+ public static class WeChatSettingNames
+ {
+ public const string Prefix = "Abp.WeChat";
+ ///
+ /// 启用快捷登录
+ /// 通过微信code登录时,如果没有注册用户信息且此配置启用时,直接创建新用户并关联openid
+ ///
+ public const string EnabledQuickLogin = Prefix + ".EnabledQuickLogin";
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Token/WeChatTokenProvider.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Token/WeChatTokenProvider.cs
index 8c8d8fbec..cdf9797d6 100644
--- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Token/WeChatTokenProvider.cs
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Token/WeChatTokenProvider.cs
@@ -1,92 +1,90 @@
-using Microsoft.Extensions.Caching.Distributed;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Logging.Abstractions;
-using System;
-using System.Net.Http;
-using System.Threading;
-using System.Threading.Tasks;
-using Volo.Abp.Caching;
-using Volo.Abp.DependencyInjection;
-using Volo.Abp.Json;
-
-namespace LINGYUN.Abp.WeChat.Token
-{
- public class WeChatTokenProvider : IWeChatTokenProvider, ISingletonDependency
- {
- public ILogger Logger { get; set; }
- protected IHttpClientFactory HttpClientFactory { get; }
- protected IJsonSerializer JsonSerializer { get; }
- protected IDistributedCache Cache { get; }
- public WeChatTokenProvider(
- IJsonSerializer jsonSerializer,
- IHttpClientFactory httpClientFactory,
- IDistributedCache cache)
- {
- JsonSerializer = jsonSerializer;
- HttpClientFactory = httpClientFactory;
-
- Cache = cache;
-
- Logger = NullLogger.Instance;
- }
-
- public virtual async Task GetTokenAsync(
- string appId,
- string appSecret,
- CancellationToken cancellationToken = default)
- {
- return (await GetCacheItemAsync("WeChatToken", appId, appSecret, cancellationToken)).WeChatToken;
- }
-
- protected virtual async Task GetCacheItemAsync(
- string provider,
- string appId,
- string appSecret,
- CancellationToken cancellationToken = default)
- {
- var cacheKey = WeChatTokenCacheItem.CalculateCacheKey(provider, appId);
-
- Logger.LogDebug($"WeChatTokenProvider.GetCacheItemAsync: {cacheKey}");
-
- var cacheItem = await Cache.GetAsync(cacheKey, token: cancellationToken);
-
- if (cacheItem != null)
- {
- Logger.LogDebug($"Found in the cache: {cacheKey}");
- return cacheItem;
- }
-
- Logger.LogDebug($"Not found in the cache, getting from the httpClient: {cacheKey}");
-
- var client = HttpClientFactory.CreateClient(AbpWeChatGlobalConsts.HttpClient);
-
- var request = new WeChatTokenRequest
- {
- BaseUrl = client.BaseAddress.AbsoluteUri,
- AppSecret = appSecret,
- AppId = appId,
- GrantType = "client_credential"
- };
-
- var response = await client.RequestWeChatCodeTokenAsync(request, cancellationToken);
- var responseContent = await response.Content.ReadAsStringAsync();
- var weChatTokenResponse = JsonSerializer.Deserialize(responseContent);
- var weChatToken = weChatTokenResponse.ToWeChatToken();
- cacheItem = new WeChatTokenCacheItem(appId, weChatToken);
-
- Logger.LogDebug($"Setting the cache item: {cacheKey}");
-
- var cacheOptions = new DistributedCacheEntryOptions
- {
- // 设置绝对过期时间为Token有效期剩余的二分钟
- AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(weChatToken.ExpiresIn - 120)
- };
-
- await Cache.SetAsync(cacheKey, cacheItem, cacheOptions, token: cancellationToken);
-
- Logger.LogDebug($"Finished setting the cache item: {cacheKey}");
-
- return cacheItem;
- }
- }
-}
+using Microsoft.Extensions.Caching.Distributed;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using Newtonsoft.Json;
+using System;
+using System.Net.Http;
+using System.Threading;
+using System.Threading.Tasks;
+using Volo.Abp.Caching;
+using Volo.Abp.DependencyInjection;
+
+namespace LINGYUN.Abp.WeChat.Token
+{
+ public class WeChatTokenProvider : IWeChatTokenProvider, ISingletonDependency
+ {
+ public ILogger Logger { get; set; }
+ protected IHttpClientFactory HttpClientFactory { get; }
+ protected IDistributedCache Cache { get; }
+ public WeChatTokenProvider(
+ IHttpClientFactory httpClientFactory,
+ IDistributedCache cache)
+ {
+ HttpClientFactory = httpClientFactory;
+
+ Cache = cache;
+
+ Logger = NullLogger.Instance;
+ }
+
+ public virtual async Task GetTokenAsync(
+ string appId,
+ string appSecret,
+ CancellationToken cancellationToken = default)
+ {
+ return (await GetCacheItemAsync("WeChatToken", appId, appSecret, cancellationToken)).WeChatToken;
+ }
+
+ protected virtual async Task GetCacheItemAsync(
+ string provider,
+ string appId,
+ string appSecret,
+ CancellationToken cancellationToken = default)
+ {
+ var cacheKey = WeChatTokenCacheItem.CalculateCacheKey(provider, appId);
+
+ Logger.LogDebug($"WeChatTokenProvider.GetCacheItemAsync: {cacheKey}");
+
+ var cacheItem = await Cache.GetAsync(cacheKey, token: cancellationToken);
+
+ if (cacheItem != null)
+ {
+ Logger.LogDebug($"Found in the cache: {cacheKey}");
+ return cacheItem;
+ }
+
+ Logger.LogDebug($"Not found in the cache, getting from the httpClient: {cacheKey}");
+
+ var client = HttpClientFactory.CreateClient(AbpWeChatGlobalConsts.HttpClient);
+
+ var request = new WeChatTokenRequest
+ {
+ BaseUrl = client.BaseAddress.AbsoluteUri,
+ AppSecret = appSecret,
+ AppId = appId,
+ GrantType = "client_credential"
+ };
+
+ var response = await client.RequestWeChatCodeTokenAsync(request, cancellationToken);
+ var responseContent = await response.Content.ReadAsStringAsync();
+ // 改为直接引用 Newtownsoft.Json
+ var weChatTokenResponse = JsonConvert.DeserializeObject(responseContent);
+ var weChatToken = weChatTokenResponse.ToWeChatToken();
+ cacheItem = new WeChatTokenCacheItem(appId, weChatToken);
+
+ Logger.LogDebug($"Setting the cache item: {cacheKey}");
+
+ var cacheOptions = new DistributedCacheEntryOptions
+ {
+ // 设置绝对过期时间为Token有效期剩余的二分钟
+ AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(weChatToken.ExpiresIn - 120)
+ };
+
+ await Cache.SetAsync(cacheKey, cacheItem, cacheOptions, token: cancellationToken);
+
+ Logger.LogDebug($"Finished setting the cache item: {cacheKey}");
+
+ return cacheItem;
+ }
+ }
+}
diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Token/WeChatTokenResponse.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Token/WeChatTokenResponse.cs
index 79cdd4d02..49ecac0b2 100644
--- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Token/WeChatTokenResponse.cs
+++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Token/WeChatTokenResponse.cs
@@ -1,41 +1,41 @@
-using Newtonsoft.Json;
-using Volo.Abp;
-
-namespace LINGYUN.Abp.WeChat.Token
-{
- ///
- /// 微信访问令牌返回对象
- ///
- public class WeChatTokenResponse
- {
- ///
- /// 错误码
- ///
- [JsonProperty("errcode")]
- public int ErrorCode { get; set; }
- ///
- /// 错误消息
- ///
- [JsonProperty("errmsg")]
- public string ErrorMessage { get; set; }
- ///
- /// 访问令牌
- ///
- [JsonProperty("access_token")]
- public string AccessToken { get; set; }
- ///
- /// 过期时间,单位(s)
- ///
- [JsonProperty("expires_in")]
- public int ExpiresIn { get; set; }
-
- public WeChatToken ToWeChatToken()
- {
- if(ErrorCode != 0)
- {
- throw new AbpException(ErrorMessage);
- }
- return new WeChatToken(AccessToken, ExpiresIn);
- }
- }
-}
+using Newtonsoft.Json;
+using Volo.Abp;
+
+namespace LINGYUN.Abp.WeChat.Token
+{
+ ///
+ /// 微信访问令牌返回对象
+ ///
+ public class WeChatTokenResponse
+ {
+ ///
+ /// 错误码
+ ///
+ [JsonProperty("errcode")]
+ public int ErrorCode { get; set; }
+ ///
+ /// 错误消息
+ ///
+ [JsonProperty("errmsg")]
+ public string ErrorMessage { get; set; }
+ ///
+ /// 访问令牌
+ ///
+ [JsonProperty("access_token")]
+ public string AccessToken { get; set; }
+ ///
+ /// 过期时间,单位(s)
+ ///
+ [JsonProperty("expires_in")]
+ public int ExpiresIn { get; set; }
+
+ public WeChatToken ToWeChatToken()
+ {
+ if(ErrorCode != 0)
+ {
+ throw new AbpException(ErrorMessage);
+ }
+ return new WeChatToken(AccessToken, ExpiresIn);
+ }
+ }
+}
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 343b0c48f..99d691dd7 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,310 +1,314 @@
-using DotNetCore.CAP;
-using Hangfire;
-using LINGYUN.Abp.AspNetCore.HttpOverrides;
-using LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json;
-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.IM.SignalR;
-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.Autofac;
-using Volo.Abp.BackgroundWorkers;
-using Volo.Abp.Caching;
-using Volo.Abp.Caching.StackExchangeRedis;
-using Volo.Abp.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(AbpMessageServiceApplicationModule),
- typeof(AbpMessageServiceHttpApiModule),
- typeof(AbpAspNetCoreMultiTenancyModule),
- typeof(AbpMessageServiceEntityFrameworkCoreModule),
- typeof(AbpTenantManagementEntityFrameworkCoreModule),
- typeof(AbpSettingManagementEntityFrameworkCoreModule),
- typeof(AbpPermissionManagementEntityFrameworkCoreModule),
- typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
- typeof(AbpHangfireMySqlStorageModule),
- typeof(AbpBackgroundJobsHangfireModule),
- typeof(AbpBackgroundWorkersModule),
- typeof(AbpIMSignalRModule),
- typeof(AbpNotificationsSmsModule),
- typeof(AbpNotificationsSignalRModule),
- typeof(AbpNotificationsWeChatMiniProgramModule),
- typeof(AbpNotificationsExceptionHandlingModule),
- typeof(AbpAspNetCoreSignalRProtocolJsonModule),
- typeof(AbpCAPEventBusModule),
- typeof(AbpDbFinderMultiTenancyModule),
- typeof(AbpCachingStackExchangeRedisModule),
- typeof(AbpAspNetCoreHttpOverridesModule),
- typeof(AbpAutofacModule)
- )]
- public class AbpMessageServiceHttpApiHostModule : AbpModule
- {
- private const string DefaultCorsPolicyName = "Default";
-
- 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 = 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");
- }
- }
-
- public override void OnApplicationInitialization(ApplicationInitializationContext context)
- {
- var app = context.GetApplicationBuilder();
- // http调用链
- app.UseCorrelationId();
- // 虚拟文件系统
- app.UseStaticFiles();
- // 本地化
- app.UseAbpRequestLocalization();
- //路由
- app.UseRouting();
- // 跨域
- app.UseCors(DefaultCorsPolicyName);
- // 加入自定义中间件
- app.UseSignalRJwtToken();
- // TODO: 还有没有其他方法在iframe中传递身份令牌?
- app.UseHangfireAuthorication();
- // 认证
- app.UseAuthentication();
- // jwt
- app.UseJwtTokenMiddleware();
- // 授权
- app.UseAuthorization();
- // 多租户
- app.UseMultiTenancy();
- // Swagger
- app.UseSwagger();
- // Swagger可视化界面
- app.UseSwaggerUI(options =>
- {
- options.SwaggerEndpoint("/swagger/v1/swagger.json", "Support MessageService API");
- });
- // 审计日志
- app.UseAuditing();
- app.UseHangfireServer();
- app.UseHangfireDashboard();
- // 路由
- app.UseConfiguredEndpoints();
- }
- }
-}
+using DotNetCore.CAP;
+using Hangfire;
+using LINGYUN.Abp.AspNetCore.HttpOverrides;
+using LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json;
+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.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.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(AbpMessageServiceApplicationModule),
+ typeof(AbpMessageServiceHttpApiModule),
+ typeof(AbpAspNetCoreMultiTenancyModule),
+ typeof(AbpIdentityWeChatModule),
+ typeof(AbpMessageServiceEntityFrameworkCoreModule),
+ typeof(AbpIdentityEntityFrameworkCoreModule),
+ typeof(AbpTenantManagementEntityFrameworkCoreModule),
+ typeof(AbpSettingManagementEntityFrameworkCoreModule),
+ typeof(AbpPermissionManagementEntityFrameworkCoreModule),
+ typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
+ typeof(AbpHangfireMySqlStorageModule),
+ typeof(AbpBackgroundJobsHangfireModule),
+ typeof(AbpBackgroundWorkersModule),
+ typeof(AbpIMSignalRModule),
+ typeof(AbpNotificationsSmsModule),
+ typeof(AbpNotificationsSignalRModule),
+ typeof(AbpNotificationsWeChatMiniProgramModule),
+ typeof(AbpNotificationsExceptionHandlingModule),
+ typeof(AbpAspNetCoreSignalRProtocolJsonModule),
+ typeof(AbpCAPEventBusModule),
+ typeof(AbpDbFinderMultiTenancyModule),
+ typeof(AbpCachingStackExchangeRedisModule),
+ typeof(AbpAspNetCoreHttpOverridesModule),
+ typeof(AbpAutofacModule)
+ )]
+ public class AbpMessageServiceHttpApiHostModule : AbpModule
+ {
+ private const string DefaultCorsPolicyName = "Default";
+
+ 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 = 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");
+ }
+ }
+
+ public override void OnApplicationInitialization(ApplicationInitializationContext context)
+ {
+ var app = context.GetApplicationBuilder();
+ // http调用链
+ app.UseCorrelationId();
+ // 虚拟文件系统
+ app.UseStaticFiles();
+ // 本地化
+ app.UseAbpRequestLocalization();
+ //路由
+ app.UseRouting();
+ // 跨域
+ app.UseCors(DefaultCorsPolicyName);
+ // 加入自定义中间件
+ app.UseSignalRJwtToken();
+ // TODO: 还有没有其他方法在iframe中传递身份令牌?
+ app.UseHangfireAuthorication();
+ // 认证
+ app.UseAuthentication();
+ // jwt
+ app.UseJwtTokenMiddleware();
+ // 授权
+ app.UseAuthorization();
+ // 多租户
+ app.UseMultiTenancy();
+ // Swagger
+ app.UseSwagger();
+ // Swagger可视化界面
+ app.UseSwaggerUI(options =>
+ {
+ options.SwaggerEndpoint("/swagger/v1/swagger.json", "Support MessageService API");
+ });
+ // 审计日志
+ app.UseAuditing();
+ app.UseHangfireServer();
+ app.UseHangfireDashboard();
+ // 路由
+ app.UseConfiguredEndpoints();
+ }
+ }
+}
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 941f5a355..4834ace66 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
@@ -36,6 +36,7 @@
+
@@ -57,6 +58,7 @@
+