From 33dd020b7ec4bdc452aa6bc4a1b081004c0c6784 Mon Sep 17 00:00:00 2001 From: ngfrolov Date: Mon, 24 Oct 2022 10:36:53 +0500 Subject: [PATCH] AuthController.RefreshAsync() returns full UserTokenDto --- AsbCloudApp/Services/IAuthService.cs | 3 +- .../Services/AuthService.cs | 72 +++++++++++++------ AsbCloudWebApi/Controllers/AuthController.cs | 14 ++-- 3 files changed, 60 insertions(+), 29 deletions(-) diff --git a/AsbCloudApp/Services/IAuthService.cs b/AsbCloudApp/Services/IAuthService.cs index 34030c24..80e9e3d7 100644 --- a/AsbCloudApp/Services/IAuthService.cs +++ b/AsbCloudApp/Services/IAuthService.cs @@ -41,7 +41,8 @@ namespace AsbCloudApp.Services /// /// /// - string Refresh(ClaimsPrincipal user); + Task RefreshAsync(ClaimsPrincipal identity, + CancellationToken token); /// /// Регистрация нового пользователя diff --git a/AsbCloudInfrastructure/Services/AuthService.cs b/AsbCloudInfrastructure/Services/AuthService.cs index 084962dd..bf81ed4b 100644 --- a/AsbCloudInfrastructure/Services/AuthService.cs +++ b/AsbCloudInfrastructure/Services/AuthService.cs @@ -14,8 +14,10 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +#nullable enable namespace AsbCloudInfrastructure.Services { + /// public class AuthService : IAuthService { private readonly IAsbCloudDbContext db; @@ -42,29 +44,37 @@ namespace AsbCloudInfrastructure.Services rnd = new Random((int)(DateTime.Now.Ticks % 2147480161)); } - public async Task LoginAsync(string login, string password, + /// + public async Task LoginAsync(string login, string password, CancellationToken token) { - var (identity, user) = await GetClaimsUserAsync(login, password, token) - .ConfigureAwait(false); - - if (identity == default || user.IdState == 0) + var user = await GetUserByLoginAsync(login, token); + if (user is null) return null; - var userDto = await userService.GetOrDefaultAsync(user.Id, token) - .ConfigureAwait(false); + if (!CheckPassword(user.PasswordHash, password)) + return null; - var userTokenDto = userDto.Adapt(); - userTokenDto.Permissions = userService.GetNestedPermissions(userDto.Id); - userTokenDto.Token = MakeToken(identity.Claims); - return userTokenDto; + return await MakeUserTokenDto(user, token); } - public string Refresh(ClaimsPrincipal user) + /// + public async Task 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; } + /// public int Register(UserRegistrationDto userDto) { if (userDto.Login is null || userDto.Login.Length is < 3 or > 50) @@ -123,6 +133,7 @@ namespace AsbCloudInfrastructure.Services return 0; } + /// public int ChangePassword(string userLogin, string newPassword) { var user = db.Users.AsNoTracking().FirstOrDefault(u => u.Login == userLogin); @@ -135,6 +146,7 @@ namespace AsbCloudInfrastructure.Services return 0; } + /// public int ChangePassword(int idUser, string newPassword) { var user = db.Users.FirstOrDefault(u => u.Id == idUser); @@ -147,6 +159,22 @@ namespace AsbCloudInfrastructure.Services return 0; } + private async Task 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(); + dto.Permissions = userService.GetNestedPermissions(userDto.Id); + dto.Token = MakeToken(identity.Claims); + return dto; + } + private static string MakeToken(IEnumerable claims) { var now = DateTime.Now; @@ -162,8 +190,7 @@ namespace AsbCloudInfrastructure.Services return new JwtSecurityTokenHandler().WriteToken(jwt); } - private async Task<(ClaimsIdentity Identity, User User)> GetClaimsUserAsync(string login, - string password, CancellationToken token = default) + private async Task GetUserByLoginAsync(string login, CancellationToken token = default) { var user = await db.Users .Include(e => e.Company) @@ -171,18 +198,16 @@ namespace AsbCloudInfrastructure.Services .AsNoTracking() .FirstOrDefaultAsync(token) .ConfigureAwait(false); + return user; + } - if (user is null) - return default; - - if (!CheckPassword(user.PasswordHash, password)) - return default; - + private ClaimsIdentity MakeClaims(User user) + { var claims = new List { new (claimIdUser, user.Id.ToString()), new (ClaimsIdentity.DefaultNameClaimType, user.Login), - new (claimNameIdCompany, user.IdCompany.ToString()), + new (claimNameIdCompany, user.IdCompany?.ToString()!), }; var roles = userService.GetRolesByIdUser(user.Id); if (roles is not null) @@ -190,7 +215,7 @@ namespace AsbCloudInfrastructure.Services claims.Add(new Claim(ClaimsIdentity.DefaultRoleClaimType, role.Caption)); var claimsIdentity = new ClaimsIdentity(claims, "Token", ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType); - return (claimsIdentity, user); + return claimsIdentity; } private bool CheckPassword(string passwordHash, string password) @@ -230,3 +255,4 @@ namespace AsbCloudInfrastructure.Services } } } +#nullable disable \ No newline at end of file diff --git a/AsbCloudWebApi/Controllers/AuthController.cs b/AsbCloudWebApi/Controllers/AuthController.cs index 6245313f..aeec1f81 100644 --- a/AsbCloudWebApi/Controllers/AuthController.cs +++ b/AsbCloudWebApi/Controllers/AuthController.cs @@ -37,8 +37,7 @@ namespace AsbCloudWebApi.Controllers [ProducesResponseType(typeof(UserTokenDto), (int)System.Net.HttpStatusCode.OK)] public async Task LoginAsync([FromBody] AuthDto auth, CancellationToken token = default) { - var userToken = await authService.LoginAsync(auth.Login, - auth.Password, token).ConfigureAwait(false); + var userToken = await authService.LoginAsync(auth.Login, auth.Password, token); if (userToken is null) Forbid(); @@ -52,10 +51,15 @@ namespace AsbCloudWebApi.Controllers /// новый токен [Authorize] [HttpGet("refresh")] - public IActionResult Refresh() + [ProducesResponseType(typeof(UserTokenDto), (int)System.Net.HttpStatusCode.OK)] + public async Task RefreshAsync(CancellationToken token = default) { - var newToken = authService.Refresh(User); - return Ok(newToken); + var userToken = await authService.RefreshAsync(User, token); + + if (userToken is null) + Forbid(); + + return Ok(userToken); } ///