AuthController.RefreshAsync() returns full UserTokenDto

This commit is contained in:
ngfrolov 2022-10-24 10:36:53 +05:00
parent 25cd263598
commit 33dd020b7e
3 changed files with 60 additions and 29 deletions

View File

@ -41,7 +41,8 @@ namespace AsbCloudApp.Services
/// </summary> /// </summary>
/// <param name="user"></param> /// <param name="user"></param>
/// <returns></returns> /// <returns></returns>
string Refresh(ClaimsPrincipal user); Task<UserTokenDto?> RefreshAsync(ClaimsPrincipal identity,
CancellationToken token);
/// <summary> /// <summary>
/// Регистрация нового пользователя /// Регистрация нового пользователя

View File

@ -14,8 +14,10 @@ using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
#nullable enable
namespace AsbCloudInfrastructure.Services namespace AsbCloudInfrastructure.Services
{ {
/// <inheritdoc/>
public class AuthService : IAuthService public class AuthService : IAuthService
{ {
private readonly IAsbCloudDbContext db; private readonly IAsbCloudDbContext db;
@ -42,29 +44,37 @@ namespace AsbCloudInfrastructure.Services
rnd = new Random((int)(DateTime.Now.Ticks % 2147480161)); rnd = new Random((int)(DateTime.Now.Ticks % 2147480161));
} }
public async Task<UserTokenDto> LoginAsync(string login, string password, /// <inheritdoc/>
public async Task<UserTokenDto?> LoginAsync(string login, string password,
CancellationToken token) CancellationToken token)
{ {
var (identity, user) = await GetClaimsUserAsync(login, password, token) var user = await GetUserByLoginAsync(login, token);
.ConfigureAwait(false); if (user is null)
if (identity == default || user.IdState == 0)
return null; return null;
var userDto = await userService.GetOrDefaultAsync(user.Id, token) if (!CheckPassword(user.PasswordHash, password))
.ConfigureAwait(false); return null;
var userTokenDto = userDto.Adapt<UserTokenDto>(); return await MakeUserTokenDto(user, token);
userTokenDto.Permissions = userService.GetNestedPermissions(userDto.Id);
userTokenDto.Token = MakeToken(identity.Claims);
return userTokenDto;
} }
public string Refresh(ClaimsPrincipal user) /// <inheritdoc/>
public async Task<UserTokenDto?> RefreshAsync(ClaimsPrincipal identity,
CancellationToken token)
{ {
return MakeToken(user.Claims); var login = identity.FindFirst(ClaimsIdentity.DefaultNameClaimType)?.Value;
if (string.IsNullOrEmpty(login))
return null;
var user = await GetUserByLoginAsync(login, token);
if (user is null)
return null;
var dto = await MakeUserTokenDto(user, token);
return dto;
} }
/// <inheritdoc/>
public int Register(UserRegistrationDto userDto) public int Register(UserRegistrationDto userDto)
{ {
if (userDto.Login is null || userDto.Login.Length is < 3 or > 50) if (userDto.Login is null || userDto.Login.Length is < 3 or > 50)
@ -123,6 +133,7 @@ namespace AsbCloudInfrastructure.Services
return 0; return 0;
} }
/// <inheritdoc/>
public int ChangePassword(string userLogin, string newPassword) public int ChangePassword(string userLogin, string newPassword)
{ {
var user = db.Users.AsNoTracking().FirstOrDefault(u => u.Login == userLogin); var user = db.Users.AsNoTracking().FirstOrDefault(u => u.Login == userLogin);
@ -135,6 +146,7 @@ namespace AsbCloudInfrastructure.Services
return 0; return 0;
} }
/// <inheritdoc/>
public int ChangePassword(int idUser, string newPassword) public int ChangePassword(int idUser, string newPassword)
{ {
var user = db.Users.FirstOrDefault(u => u.Id == idUser); var user = db.Users.FirstOrDefault(u => u.Id == idUser);
@ -147,6 +159,22 @@ namespace AsbCloudInfrastructure.Services
return 0; return 0;
} }
private async Task<UserTokenDto?> MakeUserTokenDto(User user, CancellationToken token)
{
var identity = MakeClaims(user);
if (identity is null || user.IdState == 0)
return null;
var userDto = await userService.GetOrDefaultAsync(user.Id, token);
if (userDto is null)
return null;
var dto = userDto.Adapt<UserTokenDto>();
dto.Permissions = userService.GetNestedPermissions(userDto.Id);
dto.Token = MakeToken(identity.Claims);
return dto;
}
private static string MakeToken(IEnumerable<Claim> claims) private static string MakeToken(IEnumerable<Claim> claims)
{ {
var now = DateTime.Now; var now = DateTime.Now;
@ -162,8 +190,7 @@ namespace AsbCloudInfrastructure.Services
return new JwtSecurityTokenHandler().WriteToken(jwt); return new JwtSecurityTokenHandler().WriteToken(jwt);
} }
private async Task<(ClaimsIdentity Identity, User User)> GetClaimsUserAsync(string login, private async Task<User?> GetUserByLoginAsync(string login, CancellationToken token = default)
string password, CancellationToken token = default)
{ {
var user = await db.Users var user = await db.Users
.Include(e => e.Company) .Include(e => e.Company)
@ -171,18 +198,16 @@ namespace AsbCloudInfrastructure.Services
.AsNoTracking() .AsNoTracking()
.FirstOrDefaultAsync(token) .FirstOrDefaultAsync(token)
.ConfigureAwait(false); .ConfigureAwait(false);
return user;
}
if (user is null) private ClaimsIdentity MakeClaims(User user)
return default; {
if (!CheckPassword(user.PasswordHash, password))
return default;
var claims = new List<Claim> var claims = new List<Claim>
{ {
new (claimIdUser, user.Id.ToString()), new (claimIdUser, user.Id.ToString()),
new (ClaimsIdentity.DefaultNameClaimType, user.Login), new (ClaimsIdentity.DefaultNameClaimType, user.Login),
new (claimNameIdCompany, user.IdCompany.ToString()), new (claimNameIdCompany, user.IdCompany?.ToString()!),
}; };
var roles = userService.GetRolesByIdUser(user.Id); var roles = userService.GetRolesByIdUser(user.Id);
if (roles is not null) if (roles is not null)
@ -190,7 +215,7 @@ namespace AsbCloudInfrastructure.Services
claims.Add(new Claim(ClaimsIdentity.DefaultRoleClaimType, role.Caption)); claims.Add(new Claim(ClaimsIdentity.DefaultRoleClaimType, role.Caption));
var claimsIdentity = new ClaimsIdentity(claims, "Token", ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType); var claimsIdentity = new ClaimsIdentity(claims, "Token", ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType);
return (claimsIdentity, user); return claimsIdentity;
} }
private bool CheckPassword(string passwordHash, string password) private bool CheckPassword(string passwordHash, string password)
@ -230,3 +255,4 @@ namespace AsbCloudInfrastructure.Services
} }
} }
} }
#nullable disable

View File

@ -37,8 +37,7 @@ namespace AsbCloudWebApi.Controllers
[ProducesResponseType(typeof(UserTokenDto), (int)System.Net.HttpStatusCode.OK)] [ProducesResponseType(typeof(UserTokenDto), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> LoginAsync([FromBody] AuthDto auth, CancellationToken token = default) public async Task<IActionResult> LoginAsync([FromBody] AuthDto auth, CancellationToken token = default)
{ {
var userToken = await authService.LoginAsync(auth.Login, var userToken = await authService.LoginAsync(auth.Login, auth.Password, token);
auth.Password, token).ConfigureAwait(false);
if (userToken is null) if (userToken is null)
Forbid(); Forbid();
@ -52,10 +51,15 @@ namespace AsbCloudWebApi.Controllers
/// <returns code="200">новый токен</returns> /// <returns code="200">новый токен</returns>
[Authorize] [Authorize]
[HttpGet("refresh")] [HttpGet("refresh")]
public IActionResult Refresh() [ProducesResponseType(typeof(UserTokenDto), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> RefreshAsync(CancellationToken token = default)
{ {
var newToken = authService.Refresh(User); var userToken = await authService.RefreshAsync(User, token);
return Ok(newToken);
if (userToken is null)
Forbid();
return Ok(userToken);
} }
/// <summary> /// <summary>