VzSignInManager.cs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. using Abp.Configuration;
  2. using Abp.Dependency;
  3. using Abp.Domain.Uow;
  4. using Abp.Extensions;
  5. using Abp.Runtime.Security;
  6. using Microsoft.AspNetCore.Authentication;
  7. using Microsoft.AspNetCore.Identity;
  8. using Microsoft.Extensions.Options;
  9. using System.Security.Claims;
  10. using VberZero.Authorization.Users;
  11. using VberZero.BaseSystem.Users;
  12. using VberZero.Settings;
  13. namespace VberZero.Authorization;
  14. public class VzSignInManager : SignInManager<User>, ITransientDependency
  15. {
  16. private readonly IUnitOfWorkManager _unitOfWorkManager;
  17. private readonly ISettingManager _settingManager;
  18. private readonly IConfiguration _configuration;
  19. public VzSignInManager(
  20. VzUserManager userManager,
  21. IHttpContextAccessor contextAccessor,
  22. VzUserClaimsPrincipalFactory claimsFactory,
  23. IOptions<IdentityOptions> optionsAccessor,
  24. ILogger<VzSignInManager> logger,
  25. IUnitOfWorkManager unitOfWorkManager,
  26. ISettingManager settingManager,
  27. IAuthenticationSchemeProvider schemes,
  28. IUserConfirmation<User> userConfirmation, IConfiguration configuration)
  29. : base(
  30. userManager,
  31. contextAccessor,
  32. claimsFactory,
  33. optionsAccessor,
  34. logger,
  35. schemes,
  36. userConfirmation)
  37. {
  38. _unitOfWorkManager = unitOfWorkManager;
  39. _settingManager = settingManager;
  40. _configuration = configuration;
  41. }
  42. public virtual async Task<SignInResult> SignInOrTwoFactorAsync(AbpLoginResult loginResult,
  43. bool isPersistent, bool? rememberBrowser = null, string loginProvider = null, bool bypassTwoFactor = false)
  44. {
  45. if (loginResult.Result != VzLoginResultType.Success)
  46. {
  47. throw new ArgumentException("loginResult.Result should be success in order to sign in!");
  48. }
  49. using (_unitOfWorkManager.Current.SetTenantId(loginResult.Tenant.Id))
  50. {
  51. await UserManager.As<VzUserManager>().InitializeOptionsAsync(loginResult.Tenant.Id);
  52. if (!bypassTwoFactor && IsTrue(VzSettingNames.UserManagement.TwoFactorLogin.IsEnabled,
  53. loginResult.Tenant.Id))
  54. {
  55. if (await UserManager.GetTwoFactorEnabledAsync(loginResult.User))
  56. {
  57. if ((await UserManager.GetValidTwoFactorProvidersAsync(loginResult.User)).Count > 0)
  58. {
  59. if (!await IsTwoFactorClientRememberedAsync(loginResult.User) || rememberBrowser == false)
  60. {
  61. await Context.SignInAsync(
  62. IdentityConstants.TwoFactorUserIdScheme,
  63. StoreTwoFactorInfo(loginResult.User, loginProvider)
  64. );
  65. return SignInResult.TwoFactorRequired;
  66. }
  67. }
  68. }
  69. }
  70. if (loginProvider != null)
  71. {
  72. await Context.SignOutAsync(IdentityConstants.ExternalScheme);
  73. }
  74. await SignInAsync(loginResult.User, isPersistent, loginProvider);
  75. return SignInResult.Success;
  76. }
  77. }
  78. public virtual async Task SignOutAndSignInAsync(ClaimsIdentity identity, bool isPersistent)
  79. {
  80. await SignOutAsync();
  81. await SignInAsync(identity, isPersistent);
  82. }
  83. /// <summary>
  84. ///
  85. /// </summary>
  86. /// <param name="identity"></param>
  87. /// <param name="isPersistent"></param>
  88. /// <returns></returns>
  89. public virtual async Task SignInAsync(ClaimsIdentity identity, bool isPersistent)
  90. {
  91. if (!int.TryParse(_configuration["AuthSession:ExpireTimeInMinutes"], out int expireTime))
  92. {
  93. expireTime = VzConsts.SignInExpireMinutes;
  94. }
  95. await Context.SignInAsync(IdentityConstants.ApplicationScheme, new ClaimsPrincipal(identity), new AuthenticationProperties
  96. {
  97. IsPersistent = isPersistent,
  98. ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(expireTime),
  99. AllowRefresh = true
  100. });
  101. }
  102. public override async Task SignInAsync(User user, bool isPersistent, string authenticationMethod = null)
  103. {
  104. await _unitOfWorkManager.WithUnitOfWorkAsync(async () =>
  105. {
  106. await base.SignInAsync(user, isPersistent, authenticationMethod);
  107. });
  108. }
  109. protected virtual ClaimsPrincipal StoreTwoFactorInfo(User user, string loginProvider)
  110. {
  111. var identity = new ClaimsIdentity(IdentityConstants.TwoFactorUserIdScheme);
  112. identity.AddClaim(new Claim(ClaimTypes.Name, user.Id.ToString()));
  113. if (user.TenantId.HasValue)
  114. {
  115. identity.AddClaim(new Claim(AbpClaimTypes.TenantId, user.TenantId.Value.ToString()));
  116. }
  117. if (loginProvider != null)
  118. {
  119. identity.AddClaim(new Claim(ClaimTypes.AuthenticationMethod, loginProvider));
  120. }
  121. return new ClaimsPrincipal(identity);
  122. }
  123. public async Task<int?> GetVerifiedTenantIdAsync()
  124. {
  125. var result = await Context.AuthenticateAsync(IdentityConstants.TwoFactorUserIdScheme);
  126. if (result.Principal == null)
  127. {
  128. return null;
  129. }
  130. return VzClaimsIdentityHelper.GetTenantId(result.Principal);
  131. }
  132. public override async Task<bool> IsTwoFactorClientRememberedAsync(User user)
  133. {
  134. var result = await Context.AuthenticateAsync(IdentityConstants.TwoFactorRememberMeScheme);
  135. return result.Principal != null &&
  136. result.Principal.FindFirstValue(ClaimTypes.Name) == user.Id.ToString() &&
  137. VzClaimsIdentityHelper.GetTenantId(result.Principal) == user.TenantId;
  138. }
  139. public override async Task RememberTwoFactorClientAsync(User user)
  140. {
  141. //var rememberBrowserIdentity = new ClaimsIdentity(IdentityConstants.TwoFactorRememberMeScheme);
  142. //rememberBrowserIdentity.AddClaim(new Claim(ClaimTypes.Name, user.Id.ToString()));
  143. //if (user.TenantId.HasValue)
  144. //{
  145. // rememberBrowserIdentity.AddClaim(new Claim(AbpClaimTypes.TenantId, user.TenantId.Value.ToString()));
  146. //}
  147. //if (UserManager.SupportsUserSecurityStamp)
  148. //{
  149. // var stamp = await UserManager.GetSecurityStampAsync(user);
  150. // rememberBrowserIdentity.AddClaim(new Claim(Options.ClaimsIdentity.SecurityStampClaimType, stamp));
  151. //}
  152. //await Context.SignInAsync(IdentityConstants.TwoFactorRememberMeScheme,
  153. // new ClaimsPrincipal(rememberBrowserIdentity),
  154. // new AuthenticationProperties { IsPersistent = true });
  155. var principal = await StoreRememberClient(user);
  156. await Context.SignInAsync(IdentityConstants.TwoFactorRememberMeScheme, principal, new AuthenticationProperties { IsPersistent = true });
  157. }
  158. protected virtual async Task<ClaimsPrincipal> StoreRememberClient(User user)
  159. {
  160. var rememberBrowserIdentity = new ClaimsIdentity(IdentityConstants.TwoFactorRememberMeScheme);
  161. rememberBrowserIdentity.AddClaim(new Claim(ClaimTypes.Name, user.Id.ToString()));
  162. if (user.TenantId.HasValue)
  163. {
  164. rememberBrowserIdentity.AddClaim(new Claim(AbpClaimTypes.TenantId, user.TenantId.Value.ToString()));
  165. }
  166. if (UserManager.SupportsUserSecurityStamp)
  167. {
  168. var stamp = await UserManager.GetSecurityStampAsync(user);
  169. rememberBrowserIdentity.AddClaim(new Claim(Options.ClaimsIdentity.SecurityStampClaimType, stamp));
  170. }
  171. return new ClaimsPrincipal(rememberBrowserIdentity);
  172. }
  173. private bool IsTrue(string settingName, int? tenantId)
  174. {
  175. return tenantId == null
  176. ? _settingManager.GetSettingValueForApplication<bool>(settingName)
  177. : _settingManager.GetSettingValueForTenant<bool>(settingName, tenantId.Value);
  178. }
  179. }