Browse Source

Merge pull request #1360 from colinin/account-security-module

feat(account): add `AbpAccountSecurityModule`
pull/1361/head
yx lin 3 months ago
committed by GitHub
parent
commit
9b7985c427
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN.Abp.Account.Application.csproj
  2. 8
      aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AbpAccountApplicationModule.cs
  3. 12
      aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AccountAppService.cs
  4. 13
      aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/IAccountSmsSecurityCodeSender.cs
  5. 15
      aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/MyProfileAppService.cs
  6. 2
      aspnet-core/modules/account/LINGYUN.Abp.Account.Emailing/LINGYUN/Abp/Account/Emailing/AbpAccountEmailingModule.cs
  7. 1
      aspnet-core/modules/account/LINGYUN.Abp.Account.Emailing/LINGYUN/Abp/Account/Emailing/IAccountEmailConfirmSender.cs
  8. 4
      aspnet-core/modules/account/LINGYUN.Abp.Account.Emailing/LINGYUN/Abp/Account/Emailing/IAccountEmailVerifySender.cs
  9. 3
      aspnet-core/modules/account/LINGYUN.Abp.Account.Security/FodyWeavers.xml
  10. 30
      aspnet-core/modules/account/LINGYUN.Abp.Account.Security/FodyWeavers.xsd
  11. 29
      aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN.Abp.Account.Security.csproj
  12. 31
      aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/AbpAccountSecurityModule.cs
  13. 135
      aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/AccountEmailSecurityCodeSender.cs
  14. 48
      aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/AccountSmsSecurityCodeSender.cs
  15. 7
      aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/AccountUrlNames.cs
  16. 41
      aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/IAccountEmailSecurityCodeSender.cs
  17. 23
      aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/IAccountSmsSecurityCodeSender.cs
  18. 8
      aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/Localization/AccountSecurityResource.cs
  19. 16
      aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/Localization/Resources/en.json
  20. 16
      aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/Localization/Resources/zh-Hans.json
  21. 13
      aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/Templates/AccountEmailTemplates.cs
  22. 32
      aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/Templates/AccountTemplateDefinitionProvider.cs
  23. 7
      aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/Templates/MailConfirm.tpl
  24. 5
      aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/Templates/MailSecurityVerify.tpl
  25. 4
      aspnet-core/modules/account/LINGYUN.Abp.Account.Web/AbpAccountWebModule.cs
  26. 2
      aspnet-core/modules/account/LINGYUN.Abp.Account.Web/LINGYUN.Abp.Account.Web.csproj
  27. 1
      aspnet-core/modules/account/LINGYUN.Abp.Account.Web/Pages/Account/Login.cshtml
  28. 12
      aspnet-core/modules/account/LINGYUN.Abp.Account.Web/Pages/Account/SendCode.cshtml.cs

2
aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN.Abp.Account.Application.csproj

@ -25,7 +25,7 @@
<ProjectReference Include="..\..\..\framework\wechat\LINGYUN.Abp.WeChat.MiniProgram\LINGYUN.Abp.WeChat.MiniProgram.csproj" />
<ProjectReference Include="..\..\identity\LINGYUN.Abp.Identity.Domain\LINGYUN.Abp.Identity.Domain.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.Account.Application.Contracts\LINGYUN.Abp.Account.Application.Contracts.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.Account.Emailing\LINGYUN.Abp.Account.Emailing.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.Account.Security\LINGYUN.Abp.Account.Security.csproj" />
</ItemGroup>
</Project>

8
aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AbpAccountApplicationModule.cs

@ -1,5 +1,5 @@
using LINGYUN.Abp.Account.Emailing;
using LINGYUN.Abp.Account.Emailing.Localization;
using LINGYUN.Abp.Account.Security;
using LINGYUN.Abp.Account.Security.Localization;
using LINGYUN.Abp.Identity;
using LINGYUN.Abp.WeChat.MiniProgram;
using Microsoft.Extensions.DependencyInjection;
@ -16,7 +16,7 @@ namespace LINGYUN.Abp.Account;
[DependsOn(
typeof(Volo.Abp.Account.AbpAccountApplicationModule),
typeof(AbpAccountApplicationContractsModule),
typeof(AbpAccountEmailingModule),
typeof(AbpAccountSecurityModule),
typeof(AbpIdentityDomainModule),
typeof(AbpBlobStoringModule),
typeof(AbpWeChatMiniProgramModule))]
@ -45,7 +45,7 @@ public class AbpAccountApplicationModule : AbpModule
{
options.Resources
.Get<AccountResource>()
.AddBaseTypes(typeof(AccountEmailingResource));
.AddBaseTypes(typeof(AccountSecurityResource));
});
}
}

12
aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AccountAppService.cs

@ -1,4 +1,4 @@
using LINGYUN.Abp.Account.Emailing;
using LINGYUN.Abp.Account.Security;
using LINGYUN.Abp.Identity;
using LINGYUN.Abp.Identity.Security;
using LINGYUN.Abp.Identity.Settings;
@ -123,7 +123,7 @@ public class AccountAppService : AccountApplicationServiceBase, IAccountAppServi
var code = TotpService.GenerateCode(Encoding.Unicode.GetBytes(securityToken), securityTokenCacheKey);
securityTokenCacheItem = new SecurityTokenCacheItem(code.ToString(), securityToken);
await SecurityCodeSender.SendSmsCodeAsync(
await SecurityCodeSender.SendAsync(
input.PhoneNumber, securityTokenCacheItem.Token, template);
await SecurityTokenCache
@ -227,7 +227,7 @@ public class AccountAppService : AccountApplicationServiceBase, IAccountAppServi
// 生成二次认证码
var code = await UserManager.GenerateTwoFactorTokenAsync(user, TokenOptions.DefaultPhoneProvider);
// 发送短信验证码
await SecurityCodeSender.SendSmsCodeAsync(input.PhoneNumber, code, template);
await SecurityCodeSender.SendAsync(input.PhoneNumber, code, template);
// 缓存这个手机号的记录,防重复
securityTokenCacheItem = new SecurityTokenCacheItem(code, user.SecurityStamp);
await SecurityTokenCache
@ -294,7 +294,7 @@ public class AccountAppService : AccountApplicationServiceBase, IAccountAppServi
var template = await SettingProvider.GetOrNullAsync(IdentitySettingNames.User.SmsUserSignin);
// 发送登录验证码短信
await SecurityCodeSender.SendSmsCodeAsync(input.PhoneNumber, code, template);
await SecurityCodeSender.SendAsync(input.PhoneNumber, code, template);
// 缓存登录验证码状态,防止同一手机号重复发送
securityTokenCacheItem = new SecurityTokenCacheItem(code, user.SecurityStamp);
await SecurityTokenCache
@ -307,7 +307,7 @@ public class AccountAppService : AccountApplicationServiceBase, IAccountAppServi
public async virtual Task SendEmailSigninCodeAsync(SendEmailSigninCodeDto input)
{
var sender = LazyServiceProvider.LazyGetRequiredService<IAccountEmailVerifySender>();
var sender = LazyServiceProvider.LazyGetRequiredService<IAccountEmailSecurityCodeSender>();
var user = await UserManager.FindByEmailAsync(input.EmailAddress);
@ -322,7 +322,7 @@ public class AccountAppService : AccountApplicationServiceBase, IAccountAppServi
var code = await UserManager.GenerateTwoFactorTokenAsync(user, TokenOptions.DefaultEmailProvider);
await sender.SendMailLoginVerifyCodeAsync(code, user.UserName, user.Email);
await sender.SendLoginCodeAsync(code, user.UserName, user.Email);
}
public async virtual Task<ListResultDto<NameValue>> GetTwoFactorProvidersAsync(GetTwoFactorProvidersInput input)

13
aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/IAccountSmsSecurityCodeSender.cs

@ -1,13 +0,0 @@
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Abp.Account;
public interface IAccountSmsSecurityCodeSender
{
Task SendSmsCodeAsync(
string phone,
string token,
string template, // 传递模板号
CancellationToken cancellation = default);
}

15
aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/MyProfileAppService.cs

@ -1,4 +1,4 @@
using LINGYUN.Abp.Account.Emailing;
using LINGYUN.Abp.Account.Security;
using LINGYUN.Abp.Identity;
using LINGYUN.Abp.Identity.Security;
using LINGYUN.Abp.Identity.Session;
@ -7,7 +7,6 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Options;
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
@ -20,7 +19,6 @@ using Volo.Abp.Caching;
using Volo.Abp.Content;
using Volo.Abp.Data;
using Volo.Abp.Identity;
using Volo.Abp.Security.Claims;
using Volo.Abp.Settings;
using Volo.Abp.Users;
using IIdentitySessionRepository = LINGYUN.Abp.Identity.IIdentitySessionRepository;
@ -31,23 +29,21 @@ namespace LINGYUN.Abp.Account;
public class MyProfileAppService : AccountApplicationServiceBase, IMyProfileAppService
{
protected IDistributedCache<SecurityTokenCacheItem> SecurityTokenCache { get; }
protected IAccountSmsSecurityCodeSender SecurityCodeSender { get; }
protected Identity.IIdentityUserRepository UserRepository { get; }
protected IdentitySecurityLogManager IdentitySecurityLogManager { get; }
protected IAccountSmsSecurityCodeSender SmsSecurityCodeSender => LazyServiceProvider.LazyGetRequiredService<IAccountSmsSecurityCodeSender>();
protected IAccountEmailSecurityCodeSender EmailSecurityCodeSender => LazyServiceProvider.LazyGetRequiredService<IAccountEmailSecurityCodeSender>();
protected IAuthenticatorUriGenerator AuthenticatorUriGenerator => LazyServiceProvider.LazyGetRequiredService<IAuthenticatorUriGenerator>();
protected IIdentitySessionManager IdentitySessionManager => LazyServiceProvider.LazyGetRequiredService<IIdentitySessionManager>();
protected IIdentitySessionRepository IdentitySessionRepository => LazyServiceProvider.LazyGetRequiredService<IIdentitySessionRepository>();
protected IUserPictureProvider UserPictureProvider => LazyServiceProvider.LazyGetRequiredService<IUserPictureProvider>();
public MyProfileAppService(
Identity.IIdentityUserRepository userRepository,
IAccountSmsSecurityCodeSender securityCodeSender,
IdentitySecurityLogManager identitySecurityLogManager,
IDistributedCache<SecurityTokenCacheItem> securityTokenCache)
{
UserRepository = userRepository;
SecurityCodeSender = securityCodeSender;
IdentitySecurityLogManager = identitySecurityLogManager;
SecurityTokenCache = securityTokenCache;
@ -147,7 +143,7 @@ public class MyProfileAppService : AccountApplicationServiceBase, IMyProfileAppS
var template = await SettingProvider.GetOrNullAsync(Identity.Settings.IdentitySettingNames.User.SmsPhoneNumberConfirmed);
var token = await UserManager.GenerateChangePhoneNumberTokenAsync(user, input.NewPhoneNumber);
// 发送验证码
await SecurityCodeSender.SendSmsCodeAsync(input.NewPhoneNumber, token, template);
await SmsSecurityCodeSender.SendAsync(input.NewPhoneNumber, token, template);
securityTokenCacheItem = new SecurityTokenCacheItem(token, user.ConcurrencyStamp);
await SecurityTokenCache
@ -191,9 +187,8 @@ public class MyProfileAppService : AccountApplicationServiceBase, IMyProfileAppS
var token = await UserManager.GenerateEmailConfirmationTokenAsync(user);
var confirmToken = WebUtility.UrlEncode(token);
var sender = LazyServiceProvider.LazyGetRequiredService<IAccountEmailConfirmSender>();
await sender.SendEmailConfirmLinkAsync(
await EmailSecurityCodeSender.SendConfirmLinkAsync(
user.Id,
user.Email,
confirmToken,

2
aspnet-core/modules/account/LINGYUN.Abp.Account.Emailing/LINGYUN/Abp/Account/Emailing/AbpAccountEmailingModule.cs

@ -1,4 +1,5 @@
using LINGYUN.Abp.Account.Emailing.Localization;
using System;
using Volo.Abp.Emailing;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
@ -10,6 +11,7 @@ namespace LINGYUN.Abp.Account.Emailing;
[DependsOn(
typeof(AbpEmailingModule),
typeof(AbpUiNavigationModule))]
[Obsolete("This module has been deprecated. Please use AbpAccountSecurityModule.")]
public class AbpAccountEmailingModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)

1
aspnet-core/modules/account/LINGYUN.Abp.Account.Emailing/LINGYUN/Abp/Account/Emailing/IAccountEmailConfirmSender.cs

@ -3,6 +3,7 @@ using System.Threading.Tasks;
namespace LINGYUN.Abp.Account.Emailing;
[Obsolete("This interface has been deprecated. Please use LINGYUN.Abp.Account.Security.IAccountEmailSecurityCodeSender.")]
public interface IAccountEmailConfirmSender
{
Task SendEmailConfirmLinkAsync(

4
aspnet-core/modules/account/LINGYUN.Abp.Account.Emailing/LINGYUN/Abp/Account/Emailing/IAccountEmailVerifySender.cs

@ -1,7 +1,9 @@
using System.Threading.Tasks;
using System;
using System.Threading.Tasks;
namespace LINGYUN.Abp.Account.Emailing;
[Obsolete("This interface has been deprecated. Please use LINGYUN.Abp.Account.Security.IAccountEmailSecurityCodeSender.")]
public interface IAccountEmailVerifySender
{
Task SendMailLoginVerifyCodeAsync(

3
aspnet-core/modules/account/LINGYUN.Abp.Account.Security/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
aspnet-core/modules/account/LINGYUN.Abp.Account.Security/FodyWeavers.xsd

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

29
aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN.Abp.Account.Security.csproj

@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\configureawait.props" />
<Import Project="..\..\..\..\common.props" />
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0;net9.0</TargetFrameworks>
<AssemblyName>LINGYUN.Abp.Account.Security</AssemblyName>
<PackageId>LINGYUN.Abp.Account.Security</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<None Remove="LINGYUN\Abp\Account\Security\Templates\*.tpl" />
<None Remove="LINGYUN\Abp\Account\Security\Localization\Resources\*.json" />
<EmbeddedResource Include="LINGYUN\Abp\Account\Security\Templates\*.tpl" />
<EmbeddedResource Include="LINGYUN\Abp\Account\Security\Localization\Resources\*.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Emailing" />
<PackageReference Include="Volo.Abp.Sms" />
<PackageReference Include="Volo.Abp.UI.Navigation" />
</ItemGroup>
</Project>

31
aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/AbpAccountSecurityModule.cs

@ -0,0 +1,31 @@
using LINGYUN.Abp.Account.Security.Localization;
using Volo.Abp.Emailing;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.Sms;
using Volo.Abp.UI.Navigation;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.Account.Security;
[DependsOn(
typeof(AbpEmailingModule),
typeof(AbpSmsModule),
typeof(AbpUiNavigationModule))]
public class AbpAccountSecurityModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpAccountSecurityModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<AccountSecurityResource>("en")
.AddVirtualJson("/LINGYUN/Abp/Account/Security/Localization/Resources");
});
}
}

135
aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/AccountEmailSecurityCodeSender.cs

@ -0,0 +1,135 @@
using LINGYUN.Abp.Account.Security.Localization;
using LINGYUN.Abp.Account.Security.Templates;
using Microsoft.Extensions.Localization;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using System.Web;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Emailing;
using Volo.Abp.MultiTenancy;
using Volo.Abp.TextTemplating;
using Volo.Abp.UI.Navigation.Urls;
namespace LINGYUN.Abp.Account.Security;
[Dependency(ReplaceServices = true)]
[ExposeServices(
typeof(IAccountEmailSecurityCodeSender),
typeof(AccountEmailSecurityCodeSender))]
public class AccountEmailSecurityCodeSender :
IAccountEmailSecurityCodeSender,
ITransientDependency
{
protected ITemplateRenderer TemplateRenderer { get; }
protected IEmailSender EmailSender { get; }
protected IStringLocalizer<AccountSecurityResource> StringLocalizer { get; }
protected IAppUrlProvider AppUrlProvider { get; }
protected ICurrentTenant CurrentTenant { get; }
public AccountEmailSecurityCodeSender(
IEmailSender emailSender,
ICurrentTenant currentTenant,
IAppUrlProvider appUrlProvider,
ITemplateRenderer templateRenderer,
IStringLocalizer<AccountSecurityResource> accountLocalizer)
{
EmailSender = emailSender;
CurrentTenant = currentTenant;
AppUrlProvider = appUrlProvider;
StringLocalizer = accountLocalizer;
TemplateRenderer = templateRenderer;
}
public async virtual Task SendLoginCodeAsync(
string code,
string userName,
string emailAddress)
{
var emailContent = await TemplateRenderer.RenderAsync(
AccountEmailTemplates.MailSecurityVerifyLink,
new { code = code, user = userName }
);
await EmailSender.SendAsync(
emailAddress,
StringLocalizer["MailSecurityVerify"],
emailContent
);
}
public async virtual Task SendConfirmLinkAsync(
Guid userId,
string userEmail,
string confirmToken,
string appName,
string returnUrl = null,
string returnUrlHash = null,
Guid? userTenantId = null)
{
Debug.Assert(CurrentTenant.Id == userTenantId, "This method can only work for current tenant!");
var url = await AppUrlProvider.GetUrlAsync(appName, AccountUrlNames.EmailConfirm);
var link = $"{url}?userId={userId}&{TenantResolverConsts.DefaultTenantKey}={userTenantId}&confirmToken={UrlEncoder.Default.Encode(confirmToken)}";
if (!returnUrl.IsNullOrEmpty())
{
link += "&returnUrl=" + NormalizeReturnUrl(returnUrl);
}
if (!returnUrlHash.IsNullOrEmpty())
{
link += "&returnUrlHash=" + returnUrlHash;
}
var emailContent = await TemplateRenderer.RenderAsync(
AccountEmailTemplates.MailConfirmLink,
new { link = link }
);
await EmailSender.SendAsync(
userEmail,
StringLocalizer["EmailConfirm"],
emailContent
);
}
protected virtual string NormalizeReturnUrl(string returnUrl)
{
if (returnUrl.IsNullOrEmpty())
{
return returnUrl;
}
//Handling openid connect login
if (returnUrl.StartsWith("/connect/authorize/callback", StringComparison.OrdinalIgnoreCase))
{
if (returnUrl.Contains("?"))
{
var queryPart = returnUrl.Split('?')[1];
var queryParameters = queryPart.Split('&');
foreach (var queryParameter in queryParameters)
{
if (queryParameter.Contains("="))
{
var queryParam = queryParameter.Split('=');
if (queryParam[0] == "redirect_uri")
{
return HttpUtility.UrlDecode(queryParam[1]);
}
}
}
}
}
if (returnUrl.StartsWith("/connect/authorize?", StringComparison.OrdinalIgnoreCase))
{
return HttpUtility.UrlEncode(returnUrl);
}
return returnUrl;
}
}

48
aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AccountSmsSecurityCodeSender.cs → aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/AccountSmsSecurityCodeSender.cs

@ -4,29 +4,29 @@ using Volo.Abp;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Sms;
namespace LINGYUN.Abp.Account;
namespace LINGYUN.Abp.Account.Security;
public class AccountSmsSecurityCodeSender : IAccountSmsSecurityCodeSender, ITransientDependency
{
protected ISmsSender SmsSender { get; }
public AccountSmsSecurityCodeSender(ISmsSender smsSender)
{
SmsSender = smsSender;
}
public async virtual Task SendSmsCodeAsync(
string phone,
string token,
string template,
CancellationToken cancellation = default)
{
Check.NotNullOrWhiteSpace(template, nameof(template));
var smsMessage = new SmsMessage(phone, token);
smsMessage.Properties.Add("code", token);
smsMessage.Properties.Add("TemplateCode", template);
await SmsSender.SendAsync(smsMessage);
}
public class AccountSmsSecurityCodeSender : IAccountSmsSecurityCodeSender, ITransientDependency
{
protected ISmsSender SmsSender { get; }
public AccountSmsSecurityCodeSender(ISmsSender smsSender)
{
SmsSender = smsSender;
}
public async virtual Task SendAsync(
string phone,
string token,
string template,
CancellationToken cancellation = default)
{
Check.NotNullOrWhiteSpace(template, nameof(template));
var smsMessage = new SmsMessage(phone, token);
smsMessage.Properties.Add("code", token);
smsMessage.Properties.Add("TemplateCode", template);
await SmsSender.SendAsync(smsMessage);
}
}

7
aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/AccountUrlNames.cs

@ -0,0 +1,7 @@
namespace LINGYUN.Abp.Account.Security;
public static class AccountUrlNames
{
public const string EmailConfirm = "Abp.Account.EmailConfirm";
public const string EmailVerifyLogin = "Abp.Account.EmailVerifyLogin";
}

41
aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/IAccountEmailSecurityCodeSender.cs

@ -0,0 +1,41 @@
using System;
using System.Threading.Tasks;
namespace LINGYUN.Abp.Account.Security;
/// <summary>
/// 邮件安全码发送接口
/// </summary>
public interface IAccountEmailSecurityCodeSender
{
/// <summary>
/// 发送邮件登录验证码
/// </summary>
/// <param name="code">验证码</param>
/// <param name="userName">用户名</param>
/// <param name="emailAddress">邮件地址</param>
/// <returns></returns>
Task SendLoginCodeAsync(
string code,
string userName,
string emailAddress);
/// <summary>
/// 发送邮件确认链接
/// </summary>
/// <param name="userId">用户Id</param>
/// <param name="userEmail">用户邮件</param>
/// <param name="confirmToken">确认Token</param>
/// <param name="appName">应用名称</param>
/// <param name="returnUrl">回调路径</param>
/// <param name="returnUrlHash">回调路径Hash</param>
/// <param name="userTenantId">用户租户Id</param>
/// <returns></returns>
Task SendConfirmLinkAsync(
Guid userId,
string userEmail,
string confirmToken,
string appName,
string returnUrl = null,
string returnUrlHash = null,
Guid? userTenantId = null
);
}

23
aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/IAccountSmsSecurityCodeSender.cs

@ -0,0 +1,23 @@
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Abp.Account.Security;
/// <summary>
/// 短信安全码发送接口
/// </summary>
public interface IAccountSmsSecurityCodeSender
{
/// <summary>
/// 发送短信验证码
/// </summary>
/// <param name="phone">手机号</param>
/// <param name="code">短信验证码</param>
/// <param name="templateCode">短信验证模板</param>
/// <param name="cancellation"></param>
/// <returns></returns>
Task SendAsync(
string phone,
string code,
string templateCode,
CancellationToken cancellation = default);
}

8
aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/Localization/AccountSecurityResource.cs

@ -0,0 +1,8 @@
using Volo.Abp.Localization;
namespace LINGYUN.Abp.Account.Security.Localization;
[LocalizationResourceName("AbpAccountSecurity")]
public class AccountSecurityResource
{
}

16
aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/Localization/Resources/en.json

@ -0,0 +1,16 @@
{
"culture": "en",
"texts": {
"TextTemplate:Abp.Account.MailSecurityVerifyLink": "Mail security validation template",
"TextTemplate:Abp.Account.MailConfirmLink": "Mail confirm template",
"MailSecurityVerify": "Mail security verification",
"VerifyMyEmailAddress": "Hello {0}<br/><p>Your email security verification code is as follows. Please enter the verification code to proceed to the next step.</p><p>If not operated by you, please ignore this email.</p>",
"MailSecurityVerifyRemarks": "<p>(If it is not in the form of a link, copy the address to the browser address bar for further access)</p><p>Thank you for your visit and have a good time!</p>",
"ClickToValidation": "Click link verification",
"Validation": "Validation",
"EmailConfirm": "Email confirm",
"EmailConfirmInfo": "We received an email confirmation request! If you initiated this request, please click the link below to confirm the email address.",
"ConfirmMyEmail": "Bind my email address",
"YourEmailIsSuccessfullyConfirm": "Your email address was bound successfully."
}
}

16
aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/Localization/Resources/zh-Hans.json

@ -0,0 +1,16 @@
{
"culture": "zh-Hans",
"texts": {
"TextTemplate:Abp.Account.MailSecurityVerifyLink": "邮件验证模板",
"TextTemplate:Abp.Account.MailConfirmLink": "邮件确认模板",
"MailSecurityVerify": "邮件安全验证",
"VerifyMyEmailAddress": "您好<br/><p>您此次邮件安全验证码如下,请输入验证码进行下一步操作。</p><p>如非你本人操作,请忽略此邮件。</p>",
"MailSecurityVerifyRemarks": "此邮件为系统所发,请勿直接回复。",
"ClickToValidation": "点击进行验证",
"Validation": "验证",
"EmailConfirm": "邮件确认",
"EmailConfirmInfo": "我们收到了邮件确认请求!如果你发起了此请求,请单击以下链接以确认邮件地址.",
"ConfirmMyEmail": "绑定我的邮箱地址",
"YourEmailIsSuccessfullyConfirm": "您的邮件地址绑定成功."
}
}

13
aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/Templates/AccountEmailTemplates.cs

@ -0,0 +1,13 @@
namespace LINGYUN.Abp.Account.Security.Templates;
public static class AccountEmailTemplates
{
/// <summary>
/// 邮件地址确认
/// </summary>
public const string MailConfirmLink = "Abp.Account.MailConfirmLink";
/// <summary>
/// 邮件安全验证
/// </summary>
public const string MailSecurityVerifyLink = "Abp.Account.MailSecurityVerifyLink";
}

32
aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/Templates/AccountTemplateDefinitionProvider.cs

@ -0,0 +1,32 @@
using LINGYUN.Abp.Account.Security.Localization;
using Volo.Abp.Emailing.Templates;
using Volo.Abp.Localization;
using Volo.Abp.TextTemplating;
namespace LINGYUN.Abp.Account.Security.Templates;
public class AccountTemplateDefinitionProvider : TemplateDefinitionProvider
{
public override void Define(ITemplateDefinitionContext context)
{
context.Add(
new TemplateDefinition(
AccountEmailTemplates.MailSecurityVerifyLink,
displayName: L($"TextTemplate:{AccountEmailTemplates.MailSecurityVerifyLink}"),
layout: StandardEmailTemplates.Layout,
localizationResource: typeof(AccountSecurityResource)
).WithVirtualFilePath("/LINGYUN/Abp/Account/Security/Templates/MailSecurityVerify.tpl", true),
new TemplateDefinition(
AccountEmailTemplates.MailConfirmLink,
displayName: L($"TextTemplate:{AccountEmailTemplates.MailConfirmLink}"),
layout: StandardEmailTemplates.Layout,
localizationResource: typeof(AccountSecurityResource)
).WithVirtualFilePath("/LINGYUN/Abp/Account/Security/Templates/MailConfirm.tpl", true)
);
}
private static ILocalizableString L(string name)
{
return LocalizableString.Create<AccountSecurityResource>(name);
}
}

7
aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/Templates/MailConfirm.tpl

@ -0,0 +1,7 @@
<h3>{{L "EmailConfirm"}}</h3>
<p>{{L "EmailConfirmInfo"}}</p>
<div>
<a href="{{model.link}}">{{L "ConfirmMyEmail"}}</a>
</div>

5
aspnet-core/modules/account/LINGYUN.Abp.Account.Security/LINGYUN/Abp/Account/Security/Templates/MailSecurityVerify.tpl

@ -0,0 +1,5 @@
<div style="position: absolute;">
<span>{{L "VerifyMyEmailAddress"}}{{model.user}}</span>
<p style="display:block; padding:0 50px; width: 150px; height:48px; line-height:48px; color:#cc0000; font-size:26px; background:#9c9797; font-weight:bold;">{{model.code}}</p>
<span>{{L "MailSecurityVerifyRemarks"}}</span>
</div>

4
aspnet-core/modules/account/LINGYUN.Abp.Account.Web/AbpAccountWebModule.cs

@ -1,4 +1,4 @@
using LINGYUN.Abp.Account.Emailing;
using LINGYUN.Abp.Account.Security;
using LINGYUN.Abp.Account.Web.Bundling;
using LINGYUN.Abp.Account.Web.ProfileManagement;
using LINGYUN.Abp.Identity;
@ -25,8 +25,8 @@ namespace LINGYUN.Abp.Account.Web;
[DependsOn(
typeof(AbpSmsModule),
typeof(VoloAbpAccountWebModule),
typeof(AbpAccountSecurityModule),
typeof(AbpIdentityDomainModule),
typeof(AbpAccountEmailingModule),
typeof(AbpIdentityAspNetCoreQrCodeModule),
typeof(AbpAccountApplicationContractsModule))]
public class AbpAccountWebModule : AbpModule

2
aspnet-core/modules/account/LINGYUN.Abp.Account.Web/LINGYUN.Abp.Account.Web.csproj

@ -44,7 +44,7 @@
<ProjectReference Include="..\..\identity\LINGYUN.Abp.Identity.Domain\LINGYUN.Abp.Identity.Domain.csproj" />
<ProjectReference Include="..\..\identity\LINGYUN.Abp.Identity.AspNetCore.QrCode\LINGYUN.Abp.Identity.AspNetCore.QrCode.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.Account.Application.Contracts\LINGYUN.Abp.Account.Application.Contracts.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.Account.Emailing\LINGYUN.Abp.Account.Emailing.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.Account.Security\LINGYUN.Abp.Account.Security.csproj" />
</ItemGroup>
<ItemGroup>

1
aspnet-core/modules/account/LINGYUN.Abp.Account.Web/Pages/Account/Login.cshtml

@ -63,6 +63,7 @@
</strong>
}
<div class="d-grid gap-2">
@* <abp-button type="submit" button-type="Primary" name="Action" value="PlatformLogin" class="btn-lg mt-3">@L["PlatformLogin"]</abp-button> *@
<abp-button type="submit" button-type="Primary" name="Action" value="Login" class="btn-lg mt-3">@L["Login"]</abp-button>
@if (Model.ShowCancelButton)
{

12
aspnet-core/modules/account/LINGYUN.Abp.Account.Web/Pages/Account/SendCode.cshtml.cs

@ -1,4 +1,4 @@
using LINGYUN.Abp.Account.Emailing;
using LINGYUN.Abp.Account.Security;
using LINGYUN.Abp.Identity.Settings;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
@ -33,14 +33,14 @@ namespace LINGYUN.Abp.Account.Web.Pages.Account
protected ISmsSender SmsSender { get; }
protected IAccountEmailVerifySender AccountEmailVerifySender { get; }
protected IAccountEmailSecurityCodeSender EmailSecurityCodeSender { get; }
public SendCodeModel(
ISmsSender smsSender,
IAccountEmailVerifySender accountEmailVerifySender)
IAccountEmailSecurityCodeSender emailSecurityCodeSender)
{
SmsSender = smsSender;
AccountEmailVerifySender = accountEmailVerifySender;
EmailSecurityCodeSender = emailSecurityCodeSender;
LocalizationResourceType = typeof(AccountResource);
}
@ -91,8 +91,8 @@ namespace LINGYUN.Abp.Account.Web.Pages.Account
if (Input.SelectedProvider == "Email")
{
await AccountEmailVerifySender
.SendMailLoginVerifyCodeAsync(
await EmailSecurityCodeSender
.SendLoginCodeAsync(
code,
user.UserName,
user.Email);

Loading…
Cancel
Save