12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- using System.Security.Claims;
- using Hotline.Identity.Accounts;
- using Hotline.Share.Dtos.Identity;
- using Hotline.Share.Enums.Identity;
- using Hotline.Users;
- using IdentityModel;
- using Microsoft.AspNetCore.Identity;
- using Microsoft.Extensions.Options;
- using XF.Domain.Authentications;
- using XF.Domain.Dependency;
- using XF.Domain.Exceptions;
- using XF.Domain.Options;
- using XF.Utility.AppIdentityModel;
- namespace Hotline.Application.Identity;
- public class IdentityAppService : IIdentityAppService, IScopeDependency
- {
- private readonly IAccountRepository _accountRepository;
- private readonly IAccountDomainService _accountDomainService;
- private readonly IUserRepository _userRepository;
- private readonly IJwtSecurity _jwtSecurity;
- private readonly IOptionsSnapshot<IdentityConfiguration> _identityOptionsAccessor;
- public IdentityAppService(
- IAccountRepository accountRepository,
- IAccountDomainService accountDomainService,
- IUserRepository userRepository,
- IJwtSecurity jwtSecurity,
- IOptionsSnapshot<IdentityConfiguration> identityOptionsAccessor)
- {
- _accountRepository = accountRepository;
- _accountDomainService = accountDomainService;
- _userRepository = userRepository;
- _jwtSecurity = jwtSecurity;
- _identityOptionsAccessor = identityOptionsAccessor;
- }
- public async Task<string> LoginAsync(LoginDto dto, CancellationToken cancellationToken)
- {
- var account = await _accountRepository.GetExtAsync(
- d => d.UserName == dto.UserName,
- d => d.Includes(x => x.Roles));
- if (account == null)
- throw UserFriendlyException.SameMessage("用户名或密码错误!");
- if (account.Status != EAccountStatus.Normal)
- throw UserFriendlyException.SameMessage("用户名或密码错误!");
- if (account.LockoutEnabled && account.LockoutEnd >= DateTime.Now)
- throw UserFriendlyException.SameMessage("账号被锁定!");
- var verifyResult = _accountDomainService.VerifyPassword(account, dto.Password);
- if (verifyResult == PasswordVerificationResult.Failed)
- {
- var lockoutOptions = _identityOptionsAccessor.Value.Lockout;
- account.AccessFailedCount += 1;
- if (account.LockoutEnabled && account.AccessFailedCount >= lockoutOptions.MaxFailedAccessAttempts)
- account.LockoutEnd = DateTime.Now.Add(lockoutOptions.DefaultLockoutTimeSpan);
- await _accountRepository.UpdateAsync(account, cancellationToken);
- throw UserFriendlyException.SameMessage("账号名或密码错误!");
- }
- account.LockoutEnd = null;
- account.AccessFailedCount = 0;
- await _accountRepository.UpdateAsync(account, cancellationToken);
- var user = await _userRepository.Queryable()
- .Includes(d => d.Organization)
- .FirstAsync(d => d.Id == account.Id);
- if (user == null)
- throw UserFriendlyException.SameMessage("未查询到用户数据");
- var jwtOptions = _identityOptionsAccessor.Value.Jwt;
- var claims = new List<Claim>
- {
- //new(JwtClaimTypes.Id, account.Id),
- new(JwtClaimTypes.Subject, account.Id),
- new(JwtClaimTypes.PhoneNumber, account.PhoneNo ?? string.Empty),
- new(AppClaimTypes.UserDisplayName, account.Name),
- new(JwtClaimTypes.Scope,jwtOptions.Scope),
- new(AppClaimTypes.UserPasswordChanged, account.PasswordChanged.ToString()),
- new(AppClaimTypes.DepartmentId, user.OrgId??string.Empty),
- new(AppClaimTypes.DepartmentCode, user.OrgCode??string.Empty),
- new(AppClaimTypes.DepartmentName, user.Organization?.OrgName??string.Empty),
- };
- claims.AddRange(account.Roles.Select(d => new Claim(JwtClaimTypes.Role, d.Name)));
- var token = _jwtSecurity.EncodeJwtToken(claims);
- return token;
- }
- }
|