Browse Source

support wechat quick login.

pull/292/head
cKey 4 years ago
parent
commit
4968b1a4e8
  1. 7
      aspnet-core/LINGYUN.MicroService.IdentityServer.sln
  2. 478
      aspnet-core/LINGYUN.MicroService.IdentityServerAdmin.sln
  3. 541
      aspnet-core/LINGYUN.MicroService.Messages.sln
  4. 1
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN.Abp.IdentityServer.WeChat.csproj
  5. 110
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/AbpIdentityServerWeChatModule.cs
  6. 94
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/MiniProgram/WeChatMiniProgramGrantValidator.cs
  7. 92
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialGrantValidator.cs
  8. 142
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialOAuthConsts.cs
  9. 259
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/WeChatGrantValidator.cs
  10. 28
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN.Abp.IdentityServer.WeChatValidator.csproj
  11. 57
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/AbpIdentityServerWeChatValidatorModule.cs
  12. 62
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/AspNetIdentity/AbpWeChatProfileService.cs
  13. 9
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/IWeChatResourceDataSeeder.cs
  14. 10
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/Localization/WeChatValidator/en.json
  15. 10
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/Localization/WeChatValidator/zh-Hans.json
  16. 85
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatResourceDataSeeder.cs
  17. 74
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatSignatureMiddleware.cs
  18. 16
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatSignatureOptions.cs
  19. 111
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatTokenGrantValidator.cs
  20. 16
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatValidatorConsts.cs
  21. 316
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Authentication/WeChat/WeChatAuthenticationHandler.cs
  22. 54
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Authentication/WeChat/WeChatAuthenticationOptions.cs
  23. 18
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Authentication/WeChat/WeChatAuthenticationStateCacheItem.cs
  24. 64
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Authentication/WeChatAuthenticationExtensions.cs
  25. 22
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Builder/IdentityServerApplicationBuilderExtensions.cs
  26. 17
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/README.md
  27. 16
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/System/BytesExtensions.cs
  28. 17
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/System/StringExtensions.cs
  29. 63
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/System/Text/Json/JsonElementExtensions.cs
  30. 19
      aspnet-core/modules/wechat/LINGYUN.Abp.Identity.WeChat/LINGYUN.Abp.Identity.WeChat.csproj
  31. 13
      aspnet-core/modules/wechat/LINGYUN.Abp.Identity.WeChat/LINGYUN/Abp/Identity/WeChat/AbpIdentityWeChatModule.cs
  32. 93
      aspnet-core/modules/wechat/LINGYUN.Abp.Identity.WeChat/LINGYUN/Abp/Identity/WeChat/OpenId/UserWeChatOpenIdFinder.cs
  33. 14
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN.Abp.WeChat.Application.Contracts.csproj
  34. 11
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/AbpWeChatApplicationContractsModule.cs
  35. 21
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/Crypto/Dto/Gender.cs
  36. 9
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/Crypto/Dto/GetUserInfoInput.cs
  37. 37
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/Crypto/Dto/UserInfoDto.cs
  38. 10
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/Crypto/ICryptoAppService.cs
  39. 7
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN/Abp/WeChat/WeChatRemoteServiceConsts.cs
  40. 19
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application/LINGYUN.Abp.WeChat.Application.csproj
  41. 14
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application/LINGYUN/Abp/WeChat/AbpWeChatApplicationModule.cs
  42. 42
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application/LINGYUN/Abp/WeChat/Crypto/CryptoAppService.cs
  43. 14
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application/LINGYUN/Abp/WeChat/WeChatApplicationServiceBase.cs
  44. 14
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.HttpApi/LINGYUN.Abp.WeChat.HttpApi.csproj
  45. 12
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.HttpApi/LINGYUN/Abp/WeChat/AbpWeChatHttpApiModule.cs
  46. 29
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.HttpApi/LINGYUN/Abp/WeChat/Crypto/CryptoController.cs
  47. 42
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/AbpWeChatMiniProgramConsts.cs
  48. 74
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/AbpWeChatMiniProgramModule.cs
  49. 48
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Messages/Response.SubscribeMessage.cs
  50. 212
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Messages/SubscribeMessage.cs
  51. 238
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Messages/SubscribeMessager.cs
  52. 44
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/AbpWeChatOfficialConsts.cs
  53. 240
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.SettingManagement/LINGYUN/Abp/WeChat/SettingManagement/WeChatSettingAppService.cs
  54. 86
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/AbpWeChatModule.cs
  55. 7
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Crypto/IWeChatCryptoService.cs
  56. 36
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Crypto/WeChatCryptoService.cs
  57. 5
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Localization/Resources/en.json
  58. 5
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Localization/Resources/zh-Hans.json
  59. 24
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/IUserWeChatOpenIdFinder.cs
  60. 26
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/IWeChatOpenIdFinder.cs
  61. 56
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/WeChatOpenIdCacheItem.cs
  62. 212
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/WeChatOpenIdFinder.cs
  63. 126
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/OpenId/WeChatOpenIdResponse.cs
  64. 28
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Settings/WeChatSettingDefinitionProvider.cs
  65. 19
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Settings/WeChatSettingNames.cs
  66. 182
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Token/WeChatTokenProvider.cs
  67. 82
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat/LINGYUN/Abp/WeChat/Token/WeChatTokenResponse.cs
  68. 624
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/AbpMessageServiceHttpApiHostModule.cs
  69. 2
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj

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

478
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

541
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

1
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN.Abp.IdentityServer.WeChat.csproj

@ -17,6 +17,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\wechat\LINGYUN.Abp.Identity.WeChat\LINGYUN.Abp.Identity.WeChat.csproj" />
<ProjectReference Include="..\..\wechat\LINGYUN.Abp.WeChat.MiniProgram\LINGYUN.Abp.WeChat.MiniProgram.csproj" />
<ProjectReference Include="..\..\wechat\LINGYUN.Abp.WeChat.Official\LINGYUN.Abp.WeChat.Official.csproj" />
</ItemGroup>

110
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<IIdentityServerBuilder>(builder =>
{
builder.AddProfileService<WeChatMiniProgramProfileService>();
// TODO: 两个类型不通用配置项,不然只需要一个
builder.AddExtensionGrantValidator<WeChatMiniProgramGrantValidator>();
builder.AddExtensionGrantValidator<WeChatOfficialGrantValidator>();
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpIdentityServerWeChatModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<AbpIdentityServerResource>()
.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<IIdentityServerBuilder>(builder =>
{
builder.AddProfileService<WeChatMiniProgramProfileService>();
// TODO: 两个类型不通用配置项,不然只需要一个
builder.AddExtensionGrantValidator<WeChatMiniProgramGrantValidator>();
builder.AddExtensionGrantValidator<WeChatOfficialGrantValidator>();
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpIdentityServerWeChatModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<AbpIdentityServerResource>()
.AddVirtualJson("/LINGYUN/Abp/IdentityServer/WeChat/Localization");
});
context.Services
.AddAuthentication()
.AddWeChat();
}
}
}

94
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
{
/// <summary>
/// 对于小程序绑定用户的扩展授权验证器
/// </summary>
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<IdentityUser> userManager,
IIdentityUserRepository userRepository,
IStringLocalizer<Volo.Abp.Identity.Localization.IdentityResource> identityLocalizer,
IStringLocalizer<AbpIdentityServerResource> identityServerLocalizer,
AbpWeChatMiniProgramOptionsFactory miniProgramOptionsFactory)
: base(eventService, weChatOpenIdFinder, userManager, userRepository, identityLocalizer, identityServerLocalizer)
{
MiniProgramOptionsFactory = miniProgramOptionsFactory;
}
protected override async Task<WeChatOpenId> 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
{
/// <summary>
/// 对于小程序绑定用户的扩展授权验证器
/// </summary>
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<IdentityUser> userManager,
IIdentityUserRepository userRepository,
IStringLocalizer<Volo.Abp.Identity.Localization.IdentityResource> identityLocalizer,
IStringLocalizer<AbpIdentityServerResource> identityServerLocalizer,
AbpWeChatMiniProgramOptionsFactory miniProgramOptionsFactory)
: base(eventService, weChatOpenIdFinder, userManager, userRepository, identityLocalizer, identityServerLocalizer)
{
MiniProgramOptionsFactory = miniProgramOptionsFactory;
}
protected override async Task<WeChatOpenId> FindOpenIdAsync(string code)
{
var options = await MiniProgramOptionsFactory.CreateAsync();
return await WeChatOpenIdFinder.FindAsync(code, options.AppId, options.AppSecret);
}
}
}

92
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
{
/// <summary>
/// 对于公众平台绑定用户的扩展授权验证器
/// </summary>
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<IdentityUser> userManager,
IIdentityUserRepository userRepository,
IStringLocalizer<Volo.Abp.Identity.Localization.IdentityResource> identityLocalizer,
IStringLocalizer<AbpIdentityServerResource> identityServerLocalizer,
AbpWeChatOfficialOptionsFactory weChatOfficialOptionsFactory)
: base(eventService, weChatOpenIdFinder, userManager, userRepository, identityLocalizer, identityServerLocalizer)
{
WeChatOfficialOptionsFactory = weChatOfficialOptionsFactory;
}
protected override async Task<WeChatOpenId> 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
{
/// <summary>
/// 对于公众平台绑定用户的扩展授权验证器
/// </summary>
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<IdentityUser> userManager,
IIdentityUserRepository userRepository,
IStringLocalizer<Volo.Abp.Identity.Localization.IdentityResource> identityLocalizer,
IStringLocalizer<AbpIdentityServerResource> identityServerLocalizer,
AbpWeChatOfficialOptionsFactory weChatOfficialOptionsFactory)
: base(eventService, weChatOpenIdFinder, userManager, userRepository, identityLocalizer, identityServerLocalizer)
{
WeChatOfficialOptionsFactory = weChatOfficialOptionsFactory;
}
protected override async Task<WeChatOpenId> FindOpenIdAsync(string code)
{
var options = await WeChatOfficialOptionsFactory.CreateAsync();
return await WeChatOpenIdFinder.FindAsync(code, options.AppId, options.AppSecret);
}
}
}

142
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
{
/// <summary>
/// 与微信公众号认证相关的静态(可变)常量
/// </summary>
public static class WeChatOfficialOAuthConsts
{
/// <summary>
/// 微信个人信息标识
/// </summary>
public static string ProfileKey { get; set; } = "wechat.profile";
/// <summary>
/// 微信提供者标识
/// </summary>
public static string ProviderKey => AbpWeChatOfficialConsts.ProviderKey;
/// <summary>
/// 微信提供者显示名称
/// </summary>
public static string DisplayName => AbpWeChatGlobalConsts.DisplayName;
/// <summary>
/// 回调地址
/// </summary>
public static string CallbackPath { get; set; } = "/signin-wechat";
/// <summary>
/// 微信客户端外的网页登录
/// </summary>
public const string QrConnectEndpoint = "https://open.weixin.qq.com/connect/qrconnect";
/// <summary>
/// 微信客户端内的网页登录
/// </summary>
public const string AuthorizationEndpoint = "https://open.weixin.qq.com/connect/oauth2/authorize";
/// <summary>
/// 用户允许授权后通过返回的code换取access_token地址
/// </summary>
public const string TokenEndpoint = "https://api.weixin.qq.com/sns/oauth2/access_token";
/// <summary>
/// 使用access_token获取用户个人信息地址
/// </summary>
public const string UserInformationEndpoint = "https://api.weixin.qq.com/sns/userinfo";
/// <summary>
/// 弹出授权页面,可通过openid拿到昵称、性别、所在地。
/// 并且, 即使在未关注的情况下,只要用户授权,也能获取其信息
/// <br />
/// <br />
/// 详询: <see cref="https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html"/>
/// </summary>
/// <remarks>
/// 以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。
/// 但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息
/// </remarks>
public const string UserInfoScope = "snsapi_userinfo";
/// <summary>
/// 不弹出授权页面,直接跳转,只能获取用户openid
/// <br />
/// <br />
/// 详询: <see cref="https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html"/>
/// </summary>
/// <remarks>
/// 以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。
/// 用户感知的就是直接进入了回调页(往往是业务页面)
/// </remarks>
public const string LoginScope = "snsapi_login";
}
}
using LINGYUN.Abp.WeChat;
using LINGYUN.Abp.WeChat.Official;
namespace LINGYUN.Abp.IdentityServer.WeChat.Official
{
/// <summary>
/// 与微信公众号认证相关的静态(可变)常量
/// </summary>
public static class WeChatOfficialOAuthConsts
{
/// <summary>
/// 微信个人信息标识
/// </summary>
public static string ProfileKey { get; set; } = "wechat.profile";
/// <summary>
/// 微信提供者标识
/// </summary>
public static string ProviderKey => AbpWeChatOfficialConsts.ProviderName;
/// <summary>
/// 微信提供者显示名称
/// </summary>
public static string DisplayName => AbpWeChatGlobalConsts.DisplayName;
/// <summary>
/// 回调地址
/// </summary>
public static string CallbackPath { get; set; } = "/signin-wechat";
/// <summary>
/// 微信客户端外的网页登录
/// </summary>
public const string QrConnectEndpoint = "https://open.weixin.qq.com/connect/qrconnect";
/// <summary>
/// 微信客户端内的网页登录
/// </summary>
public const string AuthorizationEndpoint = "https://open.weixin.qq.com/connect/oauth2/authorize";
/// <summary>
/// 用户允许授权后通过返回的code换取access_token地址
/// </summary>
public const string TokenEndpoint = "https://api.weixin.qq.com/sns/oauth2/access_token";
/// <summary>
/// 使用access_token获取用户个人信息地址
/// </summary>
public const string UserInformationEndpoint = "https://api.weixin.qq.com/sns/userinfo";
/// <summary>
/// 弹出授权页面,可通过openid拿到昵称、性别、所在地。
/// 并且, 即使在未关注的情况下,只要用户授权,也能获取其信息
/// <br />
/// <br />
/// 详询: <see cref="https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html"/>
/// </summary>
/// <remarks>
/// 以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。
/// 但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息
/// </remarks>
public const string UserInfoScope = "snsapi_userinfo";
/// <summary>
/// 不弹出授权页面,直接跳转,只能获取用户openid
/// <br />
/// <br />
/// 详询: <see cref="https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html"/>
/// </summary>
/// <remarks>
/// 以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。
/// 用户感知的就是直接进入了回调页(往往是业务页面)
/// </remarks>
public const string LoginScope = "snsapi_login";
}
}

259
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<IdentityUser> UserManager { get; }
protected IStringLocalizer<IdentityResource> IdentityLocalizer { get; }
protected IStringLocalizer<AbpIdentityServerResource> IdentityServerLocalizer { get; }
public WeChatGrantValidator(
IEventService eventService,
IWeChatOpenIdFinder weChatOpenIdFinder,
UserManager<IdentityUser> userManager,
IIdentityUserRepository userRepository,
IStringLocalizer<IdentityResource> identityLocalizer,
IStringLocalizer<AbpIdentityServerResource> identityServerLocalizer)
{
EventService = eventService;
UserManager = userManager;
UserRepository = userRepository;
WeChatOpenIdFinder = weChatOpenIdFinder;
IdentityLocalizer = identityLocalizer;
IdentityServerLocalizer = identityServerLocalizer;
Logger = NullLogger<WeChatGrantValidator>.Instance;
}
protected abstract Task<WeChatOpenId> 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<Claim>();
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<IdentityUser> UserManager { get; }
protected IStringLocalizer<IdentityResource> IdentityLocalizer { get; }
protected IStringLocalizer<AbpIdentityServerResource> IdentityServerLocalizer { get; }
public WeChatGrantValidator(
IEventService eventService,
IWeChatOpenIdFinder weChatOpenIdFinder,
UserManager<IdentityUser> userManager,
IIdentityUserRepository userRepository,
IStringLocalizer<IdentityResource> identityLocalizer,
IStringLocalizer<AbpIdentityServerResource> identityServerLocalizer)
{
EventService = eventService;
UserManager = userManager;
UserRepository = userRepository;
WeChatOpenIdFinder = weChatOpenIdFinder;
IdentityLocalizer = identityLocalizer;
IdentityServerLocalizer = identityServerLocalizer;
Logger = NullLogger<WeChatGrantValidator>.Instance;
}
protected abstract Task<WeChatOpenId> 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<ISettingProvider>();
// 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<IGuidGenerator>();
var currentTenant = ServiceProvider.LazyGetRequiredService<ICurrentTenant>();
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<Claim>();
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();
}
}
}

28
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN.Abp.IdentityServer.WeChatValidator.csproj

@ -1,28 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<None Remove="LINGYUN\Abp\IdentityServer\Localization\WeChatValidator\en.json" />
<None Remove="LINGYUN\Abp\IdentityServer\Localization\WeChatValidator\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="LINGYUN\Abp\IdentityServer\Localization\WeChatValidator\en.json" />
<EmbeddedResource Include="LINGYUN\Abp\IdentityServer\Localization\WeChatValidator\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.IdentityServer.Domain" Version="4.4.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Microsoft\DependencyInjection\" />
</ItemGroup>
</Project>

57
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/AbpIdentityServerWeChatValidatorModule.cs

@ -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<IIdentityServerBuilder>(builder =>
{
builder.AddProfileService<AbpWeChatProfileServicee>();
builder.AddExtensionGrantValidator<WeChatTokenGrantValidator>();
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
Configure<WeChatSignatureOptions>(configuration.GetSection("WeChat:Signature"));
context.Services
.AddAuthentication()
.AddWeChat(options => // 加入微信认证登录
{
configuration.GetSection("WeChat:Auth")?.Bind(options);
});
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpIdentityServerWeChatValidatorModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<AbpIdentityServerResource>()
.AddVirtualJson("/LINGYUN/Abp/IdentityServer/Localization/WeChatValidator");
});
}
}
}

62
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/AspNetIdentity/AbpWeChatProfileService.cs

@ -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<IdentityUser>
{
protected ICurrentTenant CurrentTenant { get; }
public AbpWeChatProfileServicee(
IdentityUserManager userManager,
IUserClaimsPrincipalFactory<IdentityUser> 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);
}
}
}
}
}

9
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/IWeChatResourceDataSeeder.cs

@ -1,9 +0,0 @@
using System.Threading.Tasks;
namespace LINGYUN.Abp.IdentityServer
{
public interface IWeChatResourceDataSeeder
{
Task CreateStandardResourcesAsync();
}
}

10
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/Localization/WeChatValidator/en.json

@ -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!"
}
}

10
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/Localization/WeChatValidator/zh-Hans.json

@ -1,10 +0,0 @@
{
"culture": "zh-Hans",
"texts": {
"SelfRegistrationDisabledMessage": "应用程序未开放注册,请联系管理员添加新用户.",
"InvalidGrant:GrantTypeInvalid": "不被允许的授权类型!",
"InvalidGrant:WeChatTokenInvalid": "微信认证失败!",
"InvalidGrant:WeChatCodeNotFound": "微信登录时获取的 code 为空或不存在!",
"InvalidGrant:WeChatNotRegister": "用户微信账号未绑定!"
}
}

85
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatResourceDataSeeder.cs

@ -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
)
);
}
}
}

74
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatSignatureMiddleware.cs

@ -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<WeChatSignatureOptions> 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;
}
}
}

16
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatSignatureOptions.cs

@ -1,16 +0,0 @@
namespace LINGYUN.Abp.IdentityServer
{
public class WeChatSignatureOptions
{
/// <summary>
/// 微信服务器请求路径
/// 填写在微信开发者中心配置的地址
/// </summary>
public string RequestPath { get; set; }
/// <summary>
/// 微信服务器请求token
/// 填写在微信开发者中心配置的token
/// </summary>
public string Token { get; set; }
}
}

111
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatTokenGrantValidator.cs

@ -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<WeChatTokenGrantValidator> Logger { get; }
protected AbpWeChatAuthorizationOptions Options { get; }
protected IHttpClientFactory HttpClientFactory{ get; }
protected IEventService EventService { get; }
protected IWeChatOpenIdFinder WeChatOpenIdFinder { get; }
protected IIdentityUserRepository UserRepository { get; }
protected UserManager<IdentityUser> UserManager { get; }
protected SignInManager<IdentityUser> SignInManager { get; }
protected IStringLocalizer<AbpIdentityServerResource> Localizer { get; }
protected PhoneNumberTokenProvider<IdentityUser> PhoneNumberTokenProvider { get; }
public WeChatTokenGrantValidator(
IEventService eventService,
IWeChatOpenIdFinder weChatOpenIdFinder,
IHttpClientFactory httpClientFactory,
UserManager<IdentityUser> userManager,
IIdentityUserRepository userRepository,
SignInManager<IdentityUser> signInManager,
IStringLocalizer<AbpIdentityServerResource> stringLocalizer,
PhoneNumberTokenProvider<IdentityUser> phoneNumberTokenProvider,
IOptions<AbpWeChatAuthorizationOptions> options,
ILogger<WeChatTokenGrantValidator> 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<Claim>();
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());
}
}
}

16
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatValidatorConsts.cs

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

316
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Authentication/WeChat/WeChatAuthenticationHandler.cs

@ -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<WeChatAuthenticationOptions>
{
protected IDistributedCache<WeChatAuthenticationStateCacheItem> Cache { get; }
public WeChatAuthenticationHandler(
IDistributedCache<WeChatAuthenticationStateCacheItem> cache,
IOptionsMonitor<WeChatAuthenticationOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock)
: base(options, logger, encoder, clock)
{
Cache = cache;
}
protected override async Task<AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens)
{
var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary<string, string>
{
["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);
}
/// <summary>
/// code换取access_token
/// </summary>
protected override async Task<OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
{
var address = QueryHelpers.AddQueryString(Options.TokenEndpoint, new Dictionary<string, string>()
{
["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);
}
/// <summary>
/// 构建用户授权地址
/// </summary>
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<string, string>
{
["appid"] = Options.ClientId,
["redirect_uri"] = redirectUri,
["response_type"] = "code"
});
challengeUrl += $"&scope={scope}&state={state}";
return challengeUrl;
}
protected override async Task<HandleRequestResult> 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<AuthenticationToken>();
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);
}
}
}

54
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Authentication/WeChat/WeChatAuthenticationOptions.cs

@ -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"));
});
}
}
}

18
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Authentication/WeChat/WeChatAuthenticationStateCacheItem.cs

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

64
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Authentication/WeChatAuthenticationExtensions.cs

@ -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
{
/// <summary>
/// </summary>
public static AuthenticationBuilder AddWeChat(
this AuthenticationBuilder builder)
{
return builder
.AddWeChat(
AbpWeChatAuthorizationConsts.AuthenticationScheme,
AbpWeChatAuthorizationConsts.DisplayName,
options => { });
}
/// <summary>
/// </summary>
public static AuthenticationBuilder AddWeChat(
this AuthenticationBuilder builder,
Action<WeChatAuthenticationOptions> configureOptions)
{
return builder
.AddWeChat(
AbpWeChatAuthorizationConsts.AuthenticationScheme,
AbpWeChatAuthorizationConsts.DisplayName,
configureOptions);
}
/// <summary>
/// </summary>
public static AuthenticationBuilder AddWeChat(
this AuthenticationBuilder builder,
string authenticationScheme,
Action<WeChatAuthenticationOptions> configureOptions)
{
return builder
.AddWeChat(
authenticationScheme,
AbpWeChatAuthorizationConsts.DisplayName,
configureOptions);
}
/// <summary>
/// </summary>
public static AuthenticationBuilder AddWeChat(
this AuthenticationBuilder builder,
string authenticationScheme,
string displayName,
Action<WeChatAuthenticationOptions> configureOptions)
{
return builder
.AddOAuth<WeChatAuthenticationOptions, WeChatAuthenticationHandler>(
authenticationScheme,
displayName,
configureOptions);
}
}
}

22
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Builder/IdentityServerApplicationBuilderExtensions.cs

@ -1,22 +0,0 @@
using LINGYUN.Abp.IdentityServer;
namespace Microsoft.AspNetCore.Builder
{
public static class IdentityServerApplicationBuilderExtensions
{
/// <summary>
/// 启用中间件可以处理微信服务器消息
/// 用于验证消息是否来自于微信服务器
/// </summary>
/// <param name="builder"></param>
/// <remarks>
/// 也可以用Controller的形式来实现
/// </remarks>
/// <returns></returns>
public static IApplicationBuilder UseWeChatSignature(this IApplicationBuilder builder)
{
builder.UseMiddleware<WeChatSignatureMiddleware>();
return builder;
}
}
}

17
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/README.md

@ -1,17 +0,0 @@
# LINGYUN.Abp.IdentityServer.WeChatValidator
废弃模块,模块层次不清晰,微信有多端平台,不同平台授权规则不一致
#### 注意
## 配置使用
```csharp
[DependsOn(typeof(AbpIdentityServerWeChatValidatorModule))]
public class YouProjectModule : AbpModule
{
// other
}

16
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/System/BytesExtensions.cs

@ -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;
}
}
}
}

17
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/System/StringExtensions.cs

@ -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;
}
}
}
}

63
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/System/Text/Json/JsonElementExtensions.cs

@ -1,63 +0,0 @@
using System.Collections.Generic;
namespace System.Text.Json
{
internal static class JsonElementExtensions
{
public static IEnumerable<string> GetRootStrings(this JsonDocument json, string key)
{
return json.RootElement.GetStrings(key);
}
public static IEnumerable<string> GetStrings(this JsonElement json, string key)
{
var result = new List<string>();
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;
}
}
}

19
aspnet-core/modules/wechat/LINGYUN.Abp.Identity.WeChat/LINGYUN.Abp.Identity.WeChat.csproj

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Identity.Domain" Version="4.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.WeChat\LINGYUN.Abp.WeChat.csproj" />
</ItemGroup>
</Project>

13
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
{
}
}

93
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/WeChat/Authorization/UserWeChatOpenIdFinder.cs → 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<string> FindByUserIdAsync(Guid userId)
{
var user = await UserManager.FindByIdAsync(userId.ToString());
return GetUserOpenIdOrNull(user);
}
public virtual async Task<string> 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<string> FindByUserIdAsync(Guid userId, string provider)
{
var user = await UserManager.FindByIdAsync(userId.ToString());
return GetUserOpenIdOrNull(user, provider);
}
public virtual async Task<string> 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;
}
}
}

14
aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application.Contracts/LINGYUN.Abp.WeChat.Application.Contracts.csproj

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Application.Contracts" Version="4.4.0" />
</ItemGroup>
</Project>

11
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
{
}
}

21
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
{
/// <summary>
/// 性别
/// </summary>
public enum Gender
{
/// <summary>
/// 未知
/// </summary>
None = 0,
/// <summary>
/// 男性
/// </summary>
Man = 1,
/// <summary>
/// 女性
/// </summary>
Women = 2
}
}

9
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; }
}
}

37
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
{
/// <summary>
/// 用户昵称
/// </summary>
public string NickName { get; set; }
/// <summary>
/// 用户头像图片的 URL。
/// URL 最后一个数值代表正方形头像大小(有 0、46、64、96、132 数值可选,0 代表 640x640 的正方形头像,46 表示 46x46 的正方形头像,剩余数值以此类推。默认132),
/// 用户没有头像时该项为空。
/// 若用户更换头像,原有头像 URL 将失效。
/// </summary>
public string AvatarUrl { get; set; }
/// <summary>
/// 性别
/// </summary>
public Gender Gender { get; set; }
/// <summary>
/// 用户所在国家
/// </summary>
public string Country { get; set; }
/// <summary>
/// 用户所在省份
/// </summary>
public string Province { get; set; }
/// <summary>
/// 用户所在城市
/// </summary>
public string City { get; set; }
/// <summary>
/// 显示 country,province,city 所用的语言
/// </summary>
public string Language { get; set; }
}
}

10
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<UserInfoDto> GetUserInfoAsync(GetUserInfoInput input);
}
}

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

19
aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Application/LINGYUN.Abp.WeChat.Application.csproj

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Application" Version="4.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.WeChat.Application.Contracts\LINGYUN.Abp.WeChat.Application.Contracts.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.WeChat.MiniProgram\LINGYUN.Abp.WeChat.MiniProgram.csproj" />
</ItemGroup>
</Project>

14
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
{
}
}

42
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<UserInfoDto> 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<UserInfoDto>(decryptedData);
}
}
}

14
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);
}
}
}

14
aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.HttpApi/LINGYUN.Abp.WeChat.HttpApi.csproj

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="4.4.0" />
</ItemGroup>
</Project>

12
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
{
}
}

29
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<UserInfoDto> GetUserInfoAsync(GetUserInfoInput input)
{
return await _service.GetUserInfoAsync(input);
}
}
}

42
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
{
/// <summary>
/// 微信小程序对应的Provider名称
/// </summary>
public static string ProviderKey { get; set; } = "WeChat.MiniProgram";
/// <summary>
/// 微信小程序授权类型
/// </summary>
public static string GrantType { get; set; } = "wx-mp";
/// <summary>
/// 微信小程序授权方法名称
/// </summary>
public static string AuthenticationMethod { get; set; } = "wma";
public static string HttpClient { get; set; } = "Abp.WeChat.MiniProgram";
}
}
namespace LINGYUN.Abp.WeChat.MiniProgram
{
public class AbpWeChatMiniProgramConsts
{
/// <summary>
/// 微信小程序对应的Provider名称
/// </summary>
public static string ProviderName { get; set; } = "WeChat.MiniProgram";
/// <summary>
/// 微信小程序授权类型
/// </summary>
public static string GrantType { get; set; } = "wx-mp";
/// <summary>
/// 微信小程序授权方法名称
/// </summary>
public static string AuthenticationMethod { get; set; } = "wma";
public static string HttpClient { get; set; } = "Abp.WeChat.MiniProgram";
}
}

74
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<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpWeChatMiniProgramModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<WeChatResource>()
.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<AbpWeChatMiniProgramOptions, AbpWeChatMiniProgramOptionsManager>();
}
}
}
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<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpWeChatMiniProgramModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<WeChatResource>()
.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<AbpWeChatMiniProgramOptions, AbpWeChatMiniProgramOptionsManager>();
}
}
}

48
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}");
}
}
}
}

212
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
{
/// <summary>
/// 接收者(用户)的 openid
/// </summary>
[JsonProperty("touser")]
public string ToUser { get; set; }
/// <summary>
/// 所需下发的订阅模板id
/// </summary>
[JsonProperty("template_id")]
public string TemplateId { get; set; }
/// <summary>
/// 点击模板卡片后的跳转页面,仅限本小程序内的页面。
/// 支持带参数,(示例index?foo=bar)。
/// 该字段不填则模板无跳转
/// </summary>
[JsonProperty("page")]
public string Page { get; set; }
/// <summary>
/// 跳转小程序类型:
/// developer为开发版;trial为体验版;formal为正式版;
/// 默认为正式版
/// </summary>
[JsonProperty("miniprogram_state")]
public string MiniProgramState { get; set; }
/// <summary>
/// 进入小程序查看”的语言类型,
/// 支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),
/// 默认为zh_CN
/// </summary>
[JsonProperty("lang")]
public string Lang { get; set; } = "zh_CN";
/// <summary>
/// 模板内容,
/// 格式形如 { "key1": { "value": any }, "key2": { "value": any } }
/// </summary>
[JsonProperty("data")]
public Dictionary<string, MessageData> Data { get; set; } = new Dictionary<string, MessageData>();
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<string, object> setData)
{
foreach (var kv in setData)
{
WriteData(prefix, kv.Key, kv.Value);
}
return this;
}
public SubscribeMessage WriteData(IDictionary<string, object> 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
{
/// <summary>
/// 接收者(用户)的 openid
/// </summary>
[JsonProperty("touser")]
public string ToUser { get; set; }
/// <summary>
/// 所需下发的订阅模板id
/// </summary>
[JsonProperty("template_id")]
public string TemplateId { get; set; }
/// <summary>
/// 点击模板卡片后的跳转页面,仅限本小程序内的页面。
/// 支持带参数,(示例index?foo=bar)。
/// 该字段不填则模板无跳转
/// </summary>
[JsonProperty("page")]
public string Page { get; set; }
/// <summary>
/// 跳转小程序类型:
/// developer为开发版;trial为体验版;formal为正式版;
/// 默认为正式版
/// </summary>
[JsonProperty("miniprogram_state")]
public string MiniProgramState { get; set; }
/// <summary>
/// 进入小程序查看”的语言类型,
/// 支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),
/// 默认为zh_CN
/// </summary>
[JsonProperty("lang")]
public string Lang { get; set; } = "zh_CN";
/// <summary>
/// 模板内容,
/// 格式形如 { "key1": { "value": any }, "key2": { "value": any } }
/// </summary>
[JsonProperty("data")]
public Dictionary<string, MessageData> Data { get; set; } = new Dictionary<string, MessageData>();
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<string, object> setData)
{
foreach (var kv in setData)
{
WriteData(prefix, kv.Key, kv.Value);
}
return this;
}
public SubscribeMessage WriteData(IDictionary<string, object> 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;
}
}
}

238
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<SubscribeMessager> 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<SubscribeMessager>.Instance;
}
public virtual async Task SendAsync(
Guid toUser,
string templateId,
string page = "",
string lang = "zh_CN",
string state = "formal",
Dictionary<string, object> 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<string, string>
{
{ "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<SubscribeMessageResponse>(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<string> 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<string, string> 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<SubscribeMessager> 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<SubscribeMessager>.Instance;
}
public virtual async Task SendAsync(
Guid toUser,
string templateId,
string page = "",
string lang = "zh_CN",
string state = "formal",
Dictionary<string, object> 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<string, string>
{
{ "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<SubscribeMessageResponse>(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<string> 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<string, string> 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();
}
}
}

44
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
{
/// <summary>
/// 微信公众号对应的Provider名称
/// </summary>
public static string ProviderKey { get; set; } = "WeChat.Official";
/// <summary>
/// 微信公众平台授权类型
/// </summary>
public static string GrantType { get; set; } = "wx-op";
/// <summary>
/// 微信公众平台授权方法名称
/// </summary>
public static string AuthenticationMethod { get; set; } = "woa";
public static string HttpClient { get; set; } = "Abp.WeChat.Official";
}
}
namespace LINGYUN.Abp.WeChat.Official
{
public class AbpWeChatOfficialConsts
{
/// <summary>
/// 微信公众号对应的Provider名称
/// </summary>
public static string ProviderName { get; set; } = "WeChat.Official";
/// <summary>
/// 微信公众平台授权类型
/// </summary>
public static string GrantType { get; set; } = "wx-op";
/// <summary>
/// 微信公众平台授权方法名称
/// </summary>
public static string AuthenticationMethod { get; set; } = "woa";
public static string HttpClient { get; set; } = "Abp.WeChat.Official";
}
}

240
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<ListResultDto<SettingGroupDto>> GetAllForCurrentTenantAsync()
{
return await GetAllForProviderAsync(TenantSettingValueProvider.ProviderName, CurrentTenant.GetId().ToString());
}
public virtual async Task<ListResultDto<SettingGroupDto>> GetAllForGlobalAsync()
{
return await GetAllForProviderAsync(GlobalSettingValueProvider.ProviderName, null);
}
protected virtual async Task<ListResultDto<SettingGroupDto>> GetAllForProviderAsync(string providerName, string providerKey)
{
var settingGroups = new List<SettingGroupDto>();
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<SettingGroupDto>(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<ListResultDto<SettingGroupDto>> GetAllForCurrentTenantAsync()
{
return await GetAllForProviderAsync(TenantSettingValueProvider.ProviderName, CurrentTenant.GetId().ToString());
}
public virtual async Task<ListResultDto<SettingGroupDto>> GetAllForGlobalAsync()
{
return await GetAllForProviderAsync(GlobalSettingValueProvider.ProviderName, null);
}
protected virtual async Task<ListResultDto<SettingGroupDto>> GetAllForProviderAsync(string providerName, string providerKey)
{
var settingGroups = new List<SettingGroupDto>();
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<SettingGroupDto>(settingGroups);
}
}
}

86
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<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpWeChatModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<WeChatResource>("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<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpWeChatModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<WeChatResource>("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))));
}
}
}

7
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);
}
}

36
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;
}
}
}

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

5
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直接登录"
}
}

24
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<string> FindByUserIdAsync(Guid userId, string provider);
Task<string> FindByUserNameAsync(string userName, string provider);
}
}
using System;
using System.Threading.Tasks;
namespace LINGYUN.Abp.WeChat.OpenId
{
public interface IUserWeChatOpenIdFinder
{
Task<string> FindByUserIdAsync(Guid userId, string provider);
Task<string> FindByUserNameAsync(string userName, string provider);
}
}

26
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<WeChatOpenId> FindAsync(string code, string appId, string appSecret);
}
}
using System.Threading.Tasks;
namespace LINGYUN.Abp.WeChat.OpenId
{
public interface IWeChatOpenIdFinder
{
Task<WeChatOpenId> FindAsync(string code, string appId, string appSecret);
/// <summary>
/// 获取当前登录用户OpenId
/// </summary>
/// <param name="appId">应用标识</param>
/// <returns></returns>
/// <exception cref="Volo.Abp.Authorization.AbpAuthorizationException">用户未登录时</exception>
/// <exception cref="Volo.Abp.AbpException">微信sessionKey过期时</exception>
Task<WeChatOpenId> FindAsync(string appId);
}
}

56
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;
}
}
}

212
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<WeChatOpenIdFinder> Logger { get; set; }
protected ICurrentTenant CurrentTenant { get; }
protected IHttpClientFactory HttpClientFactory { get; }
protected IJsonSerializer JsonSerializer { get; }
protected IDistributedCache<WeChatOpenIdCacheItem> Cache { get; }
public WeChatOpenIdFinder(
ICurrentTenant currentTenant,
IJsonSerializer jsonSerializer,
IHttpClientFactory httpClientFactory,
IDistributedCache<WeChatOpenIdCacheItem> cache)
{
CurrentTenant = currentTenant;
JsonSerializer = jsonSerializer;
HttpClientFactory = httpClientFactory;
Cache = cache;
Logger = NullLogger<WeChatOpenIdFinder>.Instance;
}
public virtual async Task<WeChatOpenId> FindAsync(string code, string appId, string appSecret)
{
// TODO: 如果需要获取SessionKey的话呢,需要再以openid作为标识来缓存一下吗
// 或者前端保存code,通过传递code来获取
return (await GetCacheItemAsync(code, appId, appSecret)).WeChatOpenId;
}
protected virtual async Task<WeChatOpenIdCacheItem> 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<WeChatOpenIdResponse>(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<WeChatOpenIdFinder> Logger { get; set; }
protected ICurrentTenant CurrentTenant { get; }
protected ICurrentUser CurrentUser { get; }
protected IHttpClientFactory HttpClientFactory { get; }
protected IDistributedCache<WeChatOpenIdCacheItem> Cache { get; }
public WeChatOpenIdFinder(
ICurrentUser currentUser,
ICurrentTenant currentTenant,
IHttpClientFactory httpClientFactory,
IDistributedCache<WeChatOpenIdCacheItem> cache)
{
CurrentUser = currentUser;
CurrentTenant = currentTenant;
HttpClientFactory = httpClientFactory;
Cache = cache;
Logger = NullLogger<WeChatOpenIdFinder>.Instance;
}
public virtual async Task<WeChatOpenId> 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<WeChatOpenId> FindAsync(string code, string appId, string appSecret)
{
// TODO: 如果需要获取SessionKey的话呢,需要再以openid作为标识来缓存一下吗
// 或者前端保存code,通过传递code来获取
return (await GetCacheItemAsync(code, appId, appSecret)).WeChatOpenId;
}
protected virtual async Task<WeChatOpenIdCacheItem> 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<WeChatOpenIdResponse>(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;
}
}
}

126
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
{
/// <summary>
/// 微信OpenId返回对象
/// </summary>
public class WeChatOpenIdResponse
{
/// <summary>
/// 错误码
/// </summary>
[JsonProperty("errcode")]
public string ErrorCode { get; set; }
/// <summary>
/// 会话密钥
/// </summary>
[JsonProperty("session_key")]
public string SessionKey { get; set; }
/// <summary>
/// 用户唯一标识
/// </summary>
[JsonProperty("openid")]
public string OpenId { get; set; }
/// <summary>
/// 用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回
/// </summary>
[JsonProperty("unionid")]
public string UnionId { get; set; }
/// <summary>
/// 错误消息
/// </summary>
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},请重试";
};
}
}
/// <summary>
/// 微信认证成功没有errorcode或者errorcode为0
/// </summary>
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
{
/// <summary>
/// 微信OpenId返回对象
/// </summary>
public class WeChatOpenIdResponse
{
/// <summary>
/// 错误码
/// </summary>
[JsonProperty("errcode")]
public string ErrorCode { get; set; }
/// <summary>
/// 会话密钥
/// </summary>
[JsonProperty("session_key")]
public string SessionKey { get; set; }
/// <summary>
/// 用户唯一标识
/// </summary>
[JsonProperty("openid")]
public string OpenId { get; set; }
/// <summary>
/// 用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回
/// </summary>
[JsonProperty("unionid")]
public string UnionId { get; set; }
/// <summary>
/// 错误消息
/// </summary>
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},请重试";
};
}
}
/// <summary>
/// 微信认证成功没有errorcode或者errorcode为0
/// </summary>
public bool IsError => !ErrorCode.IsNullOrWhiteSpace() && !"0".Equals(ErrorCode);
public WeChatOpenId ToWeChatOpenId()
{
if(IsError)
{
throw new AbpException(ErrorMessage);
}
return new WeChatOpenId(OpenId, SessionKey, UnionId);
}
}
}

28
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<WeChatResource>(name);
}
}
}

19
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";
/// <summary>
/// 启用快捷登录
/// 通过微信code登录时,如果没有注册用户信息且此配置启用时,直接创建新用户并关联openid
/// </summary>
public const string EnabledQuickLogin = Prefix + ".EnabledQuickLogin";
}
}

182
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<WeChatTokenProvider> Logger { get; set; }
protected IHttpClientFactory HttpClientFactory { get; }
protected IJsonSerializer JsonSerializer { get; }
protected IDistributedCache<WeChatTokenCacheItem> Cache { get; }
public WeChatTokenProvider(
IJsonSerializer jsonSerializer,
IHttpClientFactory httpClientFactory,
IDistributedCache<WeChatTokenCacheItem> cache)
{
JsonSerializer = jsonSerializer;
HttpClientFactory = httpClientFactory;
Cache = cache;
Logger = NullLogger<WeChatTokenProvider>.Instance;
}
public virtual async Task<WeChatToken> GetTokenAsync(
string appId,
string appSecret,
CancellationToken cancellationToken = default)
{
return (await GetCacheItemAsync("WeChatToken", appId, appSecret, cancellationToken)).WeChatToken;
}
protected virtual async Task<WeChatTokenCacheItem> 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<WeChatTokenResponse>(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<WeChatTokenProvider> Logger { get; set; }
protected IHttpClientFactory HttpClientFactory { get; }
protected IDistributedCache<WeChatTokenCacheItem> Cache { get; }
public WeChatTokenProvider(
IHttpClientFactory httpClientFactory,
IDistributedCache<WeChatTokenCacheItem> cache)
{
HttpClientFactory = httpClientFactory;
Cache = cache;
Logger = NullLogger<WeChatTokenProvider>.Instance;
}
public virtual async Task<WeChatToken> GetTokenAsync(
string appId,
string appSecret,
CancellationToken cancellationToken = default)
{
return (await GetCacheItemAsync("WeChatToken", appId, appSecret, cancellationToken)).WeChatToken;
}
protected virtual async Task<WeChatTokenCacheItem> 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<WeChatTokenResponse>(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;
}
}
}

82
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
{
/// <summary>
/// 微信访问令牌返回对象
/// </summary>
public class WeChatTokenResponse
{
/// <summary>
/// 错误码
/// </summary>
[JsonProperty("errcode")]
public int ErrorCode { get; set; }
/// <summary>
/// 错误消息
/// </summary>
[JsonProperty("errmsg")]
public string ErrorMessage { get; set; }
/// <summary>
/// 访问令牌
/// </summary>
[JsonProperty("access_token")]
public string AccessToken { get; set; }
/// <summary>
/// 过期时间,单位(s)
/// </summary>
[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
{
/// <summary>
/// 微信访问令牌返回对象
/// </summary>
public class WeChatTokenResponse
{
/// <summary>
/// 错误码
/// </summary>
[JsonProperty("errcode")]
public int ErrorCode { get; set; }
/// <summary>
/// 错误消息
/// </summary>
[JsonProperty("errmsg")]
public string ErrorMessage { get; set; }
/// <summary>
/// 访问令牌
/// </summary>
[JsonProperty("access_token")]
public string AccessToken { get; set; }
/// <summary>
/// 过期时间,单位(s)
/// </summary>
[JsonProperty("expires_in")]
public int ExpiresIn { get; set; }
public WeChatToken ToWeChatToken()
{
if(ErrorCode != 0)
{
throw new AbpException(ErrorMessage);
}
return new WeChatToken(AccessToken, ExpiresIn);
}
}
}

624
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<CapOptions>(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<AbpDbContextOptions>(options =>
{
options.UseMySQL();
});
Configure<AbpAspNetCoreAuditingOptions>(options =>
{
options.IgnoredUrls.AddIfNotContains("/hangfire");
});
// 中文序列化的编码问题
Configure<AbpSystemTextJsonSerializerOptions>(options =>
{
options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
});
// 加解密
Configure<AbpStringEncryptionOptions>(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<AbpExceptionHandlingOptions>(options =>
{
// 加入需要处理的异常类型
options.Handlers.Add<Volo.Abp.Data.AbpDbConcurrencyException>();
options.Handlers.Add<AbpInitializationException>();
options.Handlers.Add<ObjectDisposedException>();
options.Handlers.Add<StackOverflowException>();
options.Handlers.Add<OutOfMemoryException>();
options.Handlers.Add<System.Data.Common.DbException>();
options.Handlers.Add<Microsoft.EntityFrameworkCore.DbUpdateException>();
options.Handlers.Add<System.Data.DBConcurrencyException>();
});
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpMessageServiceHttpApiHostModule>("LINGYUN.Abp.MessageService");
});
// 多租户
Configure<AbpMultiTenancyOptions>(options =>
{
options.IsEnabled = true;
});
var tenantResolveCfg = configuration.GetSection("App:Domains");
if (tenantResolveCfg.Exists())
{
Configure<AbpTenantResolveOptions>(options =>
{
var domains = tenantResolveCfg.Get<string[]>();
foreach (var domain in domains)
{
options.AddDomainTenantResolver(domain);
}
});
}
Configure<AbpDistributedCacheOptions>(options =>
{
// 最好统一命名,不然某个缓存变动其他应用服务有例外发生
options.KeyPrefix = "LINGYUN.Abp.Application";
// 滑动过期30天
options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30);
// 绝对过期60天
options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60);
});
Configure<RedisCacheOptions>(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<AbpLocalizationOptions>(options =>
{
options.Languages.Add(new LanguageInfo("en", "en", "English"));
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
options.Resources
.Get<MessageServiceResource>()
.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<CapOptions>(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<AbpDbContextOptions>(options =>
{
options.UseMySQL();
});
Configure<AbpAspNetCoreAuditingOptions>(options =>
{
options.IgnoredUrls.AddIfNotContains("/hangfire");
});
// 中文序列化的编码问题
Configure<AbpSystemTextJsonSerializerOptions>(options =>
{
options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
});
// 加解密
Configure<AbpStringEncryptionOptions>(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<AbpExceptionHandlingOptions>(options =>
{
// 加入需要处理的异常类型
options.Handlers.Add<Volo.Abp.Data.AbpDbConcurrencyException>();
options.Handlers.Add<AbpInitializationException>();
options.Handlers.Add<ObjectDisposedException>();
options.Handlers.Add<StackOverflowException>();
options.Handlers.Add<OutOfMemoryException>();
options.Handlers.Add<System.Data.Common.DbException>();
options.Handlers.Add<Microsoft.EntityFrameworkCore.DbUpdateException>();
options.Handlers.Add<System.Data.DBConcurrencyException>();
});
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpMessageServiceHttpApiHostModule>("LINGYUN.Abp.MessageService");
});
// 多租户
Configure<AbpMultiTenancyOptions>(options =>
{
options.IsEnabled = true;
});
var tenantResolveCfg = configuration.GetSection("App:Domains");
if (tenantResolveCfg.Exists())
{
Configure<AbpTenantResolveOptions>(options =>
{
var domains = tenantResolveCfg.Get<string[]>();
foreach (var domain in domains)
{
options.AddDomainTenantResolver(domain);
}
});
}
Configure<AbpDistributedCacheOptions>(options =>
{
// 最好统一命名,不然某个缓存变动其他应用服务有例外发生
options.KeyPrefix = "LINGYUN.Abp.Application";
// 滑动过期30天
options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30);
// 绝对过期60天
options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60);
});
Configure<RedisCacheOptions>(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<AbpLocalizationOptions>(options =>
{
options.Languages.Add(new LanguageInfo("en", "en", "English"));
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
options.Resources
.Get<MessageServiceResource>()
.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();
}
}
}

2
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj

@ -36,6 +36,7 @@
<PackageReference Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" Version="4.4.0" />
<PackageReference Include="Volo.Abp.Autofac" Version="4.4.0" />
<PackageReference Include="Volo.Abp.EntityFrameworkCore.MySQL" Version="4.4.0" />
<PackageReference Include="Volo.Abp.Identity.EntityFrameworkCore" Version="4.4.0" />
<PackageReference Include="Volo.Abp.TenantManagement.EntityFrameworkCore" Version="4.4.0" />
<PackageReference Include="Volo.Abp.SettingManagement.EntityFrameworkCore" Version="4.4.0" />
<PackageReference Include="Volo.Abp.PermissionManagement.EntityFrameworkCore" Version="4.4.0" />
@ -57,6 +58,7 @@
<ProjectReference Include="..\..\..\modules\message\LINGYUN.Abp.MessageService.HttpApi\LINGYUN.Abp.MessageService.HttpApi.csproj" />
<ProjectReference Include="..\..\..\modules\tenants\LINGYUN.Abp.MultiTenancy.DbFinder\LINGYUN.Abp.MultiTenancy.DbFinder.csproj" />
<ProjectReference Include="..\..\..\modules\tenants\LINGYUN.Abp.MultiTenancy\LINGYUN.Abp.MultiTenancy.csproj" />
<ProjectReference Include="..\..\..\modules\wechat\LINGYUN.Abp.Identity.WeChat\LINGYUN.Abp.Identity.WeChat.csproj" />
<ProjectReference Include="..\..\..\modules\wechat\LINGYUN.Abp.Notifications.WeChat.MiniProgram\LINGYUN.Abp.Notifications.WeChat.MiniProgram.csproj" />
</ItemGroup>

Loading…
Cancel
Save