Skip to content

Commit

Permalink
Merge pull request #1133 from colinin/wecom-login
Browse files Browse the repository at this point in the history
feat: 增加企业微信登录
  • Loading branch information
colinin authored Mar 8, 2025
2 parents d14f2ba + b7d330b commit 1cf3b29
Show file tree
Hide file tree
Showing 71 changed files with 1,069 additions and 941 deletions.
7 changes: 7 additions & 0 deletions aspnet-core/LINGYUN.MicroService.All.sln
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Exporter.Magico
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Auditing.HttpApi.Client", "modules\auditing\LINGYUN.Abp.Auditing.HttpApi.Client\LINGYUN.Abp.Auditing.HttpApi.Client.csproj", "{7C48C1CA-7E53-4261-A477-454DD3A8402C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.WeChat.Work.AspNetCore", "framework\wechat\LINGYUN.Abp.WeChat.Work.AspNetCore\LINGYUN.Abp.WeChat.Work.AspNetCore.csproj", "{A54344EB-05A7-A405-5368-4A9C0A60B078}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -2105,6 +2107,10 @@ Global
{7C48C1CA-7E53-4261-A477-454DD3A8402C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7C48C1CA-7E53-4261-A477-454DD3A8402C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7C48C1CA-7E53-4261-A477-454DD3A8402C}.Release|Any CPU.Build.0 = Release|Any CPU
{A54344EB-05A7-A405-5368-4A9C0A60B078}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A54344EB-05A7-A405-5368-4A9C0A60B078}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A54344EB-05A7-A405-5368-4A9C0A60B078}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A54344EB-05A7-A405-5368-4A9C0A60B078}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -2500,6 +2506,7 @@ Global
{ECE61F58-1AEC-1E4F-1543-76C2242B6F70} = {A4633711-7FB6-411A-8D08-BB9A0A778046}
{B7B63E08-8F62-34F6-FEA5-063267F1FC85} = {A4633711-7FB6-411A-8D08-BB9A0A778046}
{7C48C1CA-7E53-4261-A477-454DD3A8402C} = {67DAB2A0-D407-4CAB-8414-AE3D0AC52FC4}
{A54344EB-05A7-A405-5368-4A9C0A60B078} = {DD9BE9E7-F6BF-4869-BCD2-82F5072BDA21}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718}
Expand Down
7 changes: 7 additions & 0 deletions aspnet-core/LINGYUN.MicroService.SingleProject.sln
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.OpenIddict.QrCo
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Identity.AspNetCore.QrCode", "modules\identity\LINGYUN.Abp.Identity.AspNetCore.QrCode\LINGYUN.Abp.Identity.AspNetCore.QrCode.csproj", "{C9266D5D-3860-09C3-F566-489BBB57A534}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.WeChat.Work.AspNetCore", "framework\wechat\LINGYUN.Abp.WeChat.Work.AspNetCore\LINGYUN.Abp.WeChat.Work.AspNetCore.csproj", "{40DC9A79-2E8A-4C6F-A637-5C09D6F26B0E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -1756,6 +1758,10 @@ Global
{C9266D5D-3860-09C3-F566-489BBB57A534}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C9266D5D-3860-09C3-F566-489BBB57A534}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C9266D5D-3860-09C3-F566-489BBB57A534}.Release|Any CPU.Build.0 = Release|Any CPU
{40DC9A79-2E8A-4C6F-A637-5C09D6F26B0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{40DC9A79-2E8A-4C6F-A637-5C09D6F26B0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{40DC9A79-2E8A-4C6F-A637-5C09D6F26B0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{40DC9A79-2E8A-4C6F-A637-5C09D6F26B0E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -2078,6 +2084,7 @@ Global
{E40CB92D-6C03-4A61-9A47-057CA504A46B} = {D94D6AFE-20BD-4F21-8708-03F5E34F49FC}
{4C7594CE-FB2F-4309-B95C-D4460892CF6E} = {7C714185-D3D9-4D94-B5CB-D857A0091F04}
{C9266D5D-3860-09C3-F566-489BBB57A534} = {D94D6AFE-20BD-4F21-8708-03F5E34F49FC}
{40DC9A79-2E8A-4C6F-A637-5C09D6F26B0E} = {91867618-0D86-4410-91C6-B1166A9ACDF9}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {711A43C0-A2F8-4E5C-9B9F-F2551E4B3FF1}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using LINGYUN.Abp.Encryption.SM4;
using System.Text;
using Volo.Abp.Modularity;
using Volo.Abp.Security;
using Volo.Abp.Security.Encryption;

namespace LINGYUN.Abp.Encryption.Console;

[DependsOn(typeof(AbpEncryptionSM4Module))]
//[DependsOn(typeof(AbpEncryptionSM4Module))]
[DependsOn(typeof(AbpSecurityModule))]
public class AbpEncryptionConsoleModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,40 @@ static void Main(string[] args)

application.Initialize();

WriteLine("D:解密 E:加密");

var opt = ReadLine();
bool en = false;
if ("E".Equals(opt, StringComparison.InvariantCultureIgnoreCase))
{
en = true;
WriteLine("请输入需要加密的字符串");
}
else
while (true)
{
WriteLine("请输入需要解密的字符串");
WriteLine("D:解密 E:加密 Q: 退出");

var opt = ReadLine();
var en = false;

if (opt == "Q")
{
break;
}

if ("E".Equals(opt, StringComparison.InvariantCultureIgnoreCase))
{
en = true;
WriteLine("请输入需要加密的字符串");
}
else
{
WriteLine("请输入需要解密的字符串");
}

var sourceChr = ReadLine();
var encryptionService = application.ServiceProvider.GetRequiredService<IStringEncryptionService>();
WriteLine(en ? encryptionService.Encrypt(sourceChr) : encryptionService.Decrypt(sourceChr));

WriteLine("按任意键继续");

ReadKey();

Clear();
}

var sourceChr = ReadLine();
var encryptionService = application.ServiceProvider.GetRequiredService<IStringEncryptionService>();
WriteLine(en ? encryptionService.Encrypt(sourceChr) : encryptionService.Decrypt(sourceChr));

application.Shutdown();

ReadKey();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@ namespace LINGYUN.Abp.WeChat.Work.Authorize;
public interface IWeChatWorkAuthorizeAppService : IApplicationService
{
Task<string> GenerateOAuth2AuthorizeAsync(
string agentid,
string redirectUri,
string responseType = "code",
string scope = "snsapi_base");

Task<string> GenerateOAuth2LoginAsync(
string redirectUri,
string loginType = "ServiceApp",
string agentid = "");
string loginType = "ServiceApp");
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,16 @@ public interface IWeChatWorkMessageAppService : IApplicationService
/// <remarks>
/// 参考文档:<see cref="https://developer.work.weixin.qq.com/document/path/90238"/>
/// </remarks>
/// <param name="agentId"></param>
/// <param name="input"></param>
/// <returns></returns>
Task<string> Handle(string agentId, MessageValidationInput input);
Task<string> Handle(MessageValidationInput input);
/// <summary>
/// 处理企业微信消息
/// </summary>
/// <remarks>
/// 参考文档:<see cref="https://developer.work.weixin.qq.com/document/path/90238"/>
/// </remarks>
/// <param name="agentId"></param>
/// <param name="input"></param>
/// <returns></returns>
Task<string> Handle(string agentId, MessageHandleInput input);
Task<string> Handle(MessageHandleInput input);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,22 @@ public WeChatWorkAuthorizeAppService(
_authorizeGenerator = authorizeGenerator;
}

public async virtual Task<string> GenerateOAuth2AuthorizeAsync(string agentid, string redirectUri, string responseType = "code", string scope = "snsapi_base")
public async virtual Task<string> GenerateOAuth2AuthorizeAsync(string redirectUri, string responseType = "code", string scope = "snsapi_base")
{
var state = _encryptionService.Encrypt($"agentid={agentid}&redirectUri={redirectUri}&responseType={responseType}&scope={scope}&random={Guid.NewGuid():D}").ToMd5();

return await _authorizeGenerator.GenerateOAuth2AuthorizeAsync(agentid, redirectUri, state, responseType, scope);
var state = _encryptionService.Encrypt($"redirectUri={redirectUri}&responseType={responseType}&scope={scope}&random={Guid.NewGuid():D}").ToMd5();

return await _authorizeGenerator.GenerateOAuth2AuthorizeAsync(redirectUri, state, responseType, scope);
}

public async virtual Task<string> GenerateOAuth2LoginAsync(string redirectUri, string loginType = "ServiceApp", string agentid = "")
public async virtual Task<string> GenerateOAuth2LoginAsync(string redirectUri, string loginType = "ServiceApp")
{
var state = _encryptionService.Encrypt($"agentid={agentid}&redirectUri={redirectUri}&loginType={loginType}&agentid={agentid}&random={Guid.NewGuid():D}").ToMd5();
var state = _encryptionService.Encrypt($"redirectUri={redirectUri}&loginType={loginType}&random={Guid.NewGuid():D}").ToMd5();

var corpId = await SettingProvider.GetOrNullAsync(WeChatWorkSettingNames.Connection.CorpId);

Check.NotNullOrEmpty(corpId, nameof(corpId));

return await _authorizeGenerator.GenerateOAuth2LoginAsync(corpId, redirectUri, state, loginType, agentid);
return await _authorizeGenerator.GenerateOAuth2LoginAsync(corpId, redirectUri, state, loginType);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using LINGYUN.Abp.WeChat.Work.Settings;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Services;
Expand All @@ -13,33 +13,40 @@ namespace LINGYUN.Abp.WeChat.Work.Message;
public class WeChatWorkMessageAppService : ApplicationService, IWeChatWorkMessageAppService
{
private readonly IWeChatCryptoService _cryptoService;
private readonly WeChatWorkOptions _options;
private readonly IDistributedEventBus _distributedEventBus;
private readonly IMessageResolver _messageResolver;
public WeChatWorkMessageAppService(
IMessageResolver messageResolver,
IWeChatCryptoService cryptoService,
IDistributedEventBus distributedEventBus,
IOptionsMonitor<WeChatWorkOptions> options)
IDistributedEventBus distributedEventBus)
{
_cryptoService = cryptoService;
_messageResolver = messageResolver;
_distributedEventBus = distributedEventBus;
_options = options.CurrentValue;
}

public async virtual Task<string> Handle(string agentId, MessageValidationInput input)
public async virtual Task<string> Handle(MessageValidationInput input)
{
var corpId = await SettingProvider.GetOrNullAsync(WeChatWorkSettingNames.Connection.CorpId);
var allSettings = await SettingProvider.GetAllAsync(
new[] {
WeChatWorkSettingNames.Connection.CorpId,
WeChatWorkSettingNames.Connection.Token,
WeChatWorkSettingNames.Connection.EncodingAESKey,
} );

var corpId = allSettings.FirstOrDefault(x => x.Name == WeChatWorkSettingNames.Connection.CorpId)?.Value;
var token = allSettings.FirstOrDefault(x => x.Name == WeChatWorkSettingNames.Connection.Token)?.Value;
var aesKey = allSettings.FirstOrDefault(x => x.Name == WeChatWorkSettingNames.Connection.EncodingAESKey)?.Value;

Check.NotNullOrEmpty(corpId, nameof(corpId));
Check.NotNullOrEmpty(token, nameof(token));
Check.NotNullOrEmpty(aesKey, nameof(aesKey));

var applicationConfiguration = _options.Applications.GetConfiguration(agentId);
var cryptoConfiguration = applicationConfiguration.GetCryptoConfiguration("Message");
var echoData = new WeChatCryptoEchoData(
input.EchoStr,
corpId,
cryptoConfiguration.Token,
cryptoConfiguration.EncodingAESKey,
token,
aesKey,
input.Msg_Signature,
input.TimeStamp.ToString(),
input.Nonce);
Expand All @@ -49,18 +56,27 @@ public async virtual Task<string> Handle(string agentId, MessageValidationInput
return echoStr;
}

public async virtual Task<string> Handle(string agentId, MessageHandleInput input)
public async virtual Task<string> Handle(MessageHandleInput input)
{
var corpId = await SettingProvider.GetOrNullAsync(WeChatWorkSettingNames.Connection.CorpId);
Check.NotNullOrEmpty(corpId, nameof(corpId));
var allSettings = await SettingProvider.GetAllAsync(
new[] {
WeChatWorkSettingNames.Connection.CorpId,
WeChatWorkSettingNames.Connection.Token,
WeChatWorkSettingNames.Connection.EncodingAESKey,
});

var applicationConfiguration = _options.Applications.GetConfiguration(agentId);
var cryptoConfiguration = applicationConfiguration.GetCryptoConfiguration("Message");
var corpId = allSettings.FirstOrDefault(x => x.Name == WeChatWorkSettingNames.Connection.CorpId)?.Value;
var token = allSettings.FirstOrDefault(x => x.Name == WeChatWorkSettingNames.Connection.Token)?.Value;
var aesKey = allSettings.FirstOrDefault(x => x.Name == WeChatWorkSettingNames.Connection.EncodingAESKey)?.Value;

Check.NotNullOrEmpty(corpId, nameof(corpId));
Check.NotNullOrEmpty(token, nameof(token));
Check.NotNullOrEmpty(aesKey, nameof(aesKey));

var messageData = new MessageResolveData(
corpId,
cryptoConfiguration.Token,
cryptoConfiguration.EncodingAESKey,
token,
aesKey,
input.Msg_Signature,
input.TimeStamp,
input.Nonce,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

<Import Project="..\..\..\..\configureawait.props" />
<Import Project="..\..\..\..\common.props" />

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<AssemblyName>LINGYUN.Abp.WeChat.Work.AspNetCore</AssemblyName>
<PackageId>LINGYUN.Abp.WeChat.Work.AspNetCore</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Volo.Abp.AspNetCore" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.WeChat.Work\LINGYUN.Abp.WeChat.Work.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Volo.Abp.AspNetCore;
using Volo.Abp.Modularity;

namespace LINGYUN.Abp.WeChat.Work.AspNetCore;

[DependsOn(
typeof(AbpWeChatWorkModule),
typeof(AbpAspNetCoreModule))]
public class AbpWeChatWorkAspNetCoreModule : AbpModule
{
}
Loading

0 comments on commit 1cf3b29

Please sign in to comment.