/
softailor
/
gridient
Обзор
Документация
Войти
/
softailor
/
gridient
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
backend/Gridient.Infrastructure.Authentication.Local/Services/LocalAuthService.cs
128 строк
6 KB
Jenkins
Auto add
18 фев 2026, 10:19
18 фев 2026, 10:19
1e6c4f8
Код
Авторство
О чём код?
using Gridient.Core.Services.Interfaces; using Gridient.Infrastructure.Authentication.Local.Models; using Gridient.Infrastructure.Authentication.Local.Options; using Gridient.Infrastructure.Authentication.Local.Repositories; using Microsoft.Extensions.Options; using System.Security.Claims; using UserModel = Gridient.Core.Models.User; namespace Gridient.Infrastructure.Authentication.Local.Services { public class LocalAuthService : ILocalAuthService { private readonly IAuthUserRepository _authUserRepository; private readonly IRefreshTokenRepository _refreshTokenRepository; private readonly IUserService _userService; private readonly IPasswordHasher _passwordHasher; private readonly ITokenService _tokenService; private readonly JwtOptions _jwtOptions; public LocalAuthService( IAuthUserRepository authUserRepository, IRefreshTokenRepository refreshTokenRepository, IUserService userService, IPasswordHasher passwordHasher, ITokenService tokenService, IOptions<JwtOptions> jwtOptions) { _authUserRepository = authUserRepository; _refreshTokenRepository = refreshTokenRepository; _userService = userService; _passwordHasher = passwordHasher; _tokenService = tokenService; _jwtOptions = jwtOptions.Value; } public async Task<AuthResponseModel?> LoginAsync(string username, string password, CancellationToken cancellationToken) { var authUser = await _authUserRepository.GetByLoginOrEmailAsync(username, cancellationToken); if (authUser == null) return null; var isPasswordValid = _passwordHasher.VerifyHashedPassword(authUser.PasswordHash, password); if (!isPasswordValid) return null; // Получаем пользователя Core для получения групп var coreUser = await _userService.GetByLoginAsync(authUser.Login, cancellationToken); if (coreUser == null) return null; // Обновляем время последнего входа await _authUserRepository.UpdateLastLoginAsync(authUser.Login, DateTime.UtcNow, cancellationToken); return await GenerateTokensAsync(coreUser, cancellationToken); } public async Task<AuthResponseModel?> RefreshTokenAsync(string refreshToken, CancellationToken cancellationToken) { var authUser = await _refreshTokenRepository.GetUserByRefreshTokenAsync(refreshToken, cancellationToken); if (authUser == null) return null; // Проверяем срок действия токена var tokenEntity = await _refreshTokenRepository.GetByTokenAsync(refreshToken, cancellationToken); if (tokenEntity == null || tokenEntity.ExpiresAt < DateTime.UtcNow) return null; // Получаем пользователя Core для получения групп var coreUser = await _userService.GetByLoginAsync(authUser.Login, cancellationToken); if (coreUser == null) return null; return await GenerateTokensAsync(coreUser, cancellationToken); } public async Task LogoutAsync(string refreshToken, CancellationToken cancellationToken) { await _refreshTokenRepository.DeleteTokenAsync(refreshToken, cancellationToken); } private async Task<AuthResponseModel> GenerateTokensAsync(UserModel coreUser, CancellationToken cancellationToken) { var accessTokenExpires = DateTime.UtcNow.AddMinutes(_jwtOptions.AccessTokenLifetimeMinutes); var refreshTokenExpires = DateTime.UtcNow.AddHours(_jwtOptions.RefreshTokenLifetimeHours); // Базовые claims var baseClaims = new List<Claim> { new(ClaimTypes.NameIdentifier, coreUser.Id.ToString()), new(ClaimTypes.Name, coreUser.Login), }; // Генерируем refresh token (без ролей) var refreshToken = _tokenService.GenerateRefreshToken(baseClaims, refreshTokenExpires); // Закомментировано: добавление ролей в токен не требуется при использовании ABAC, // где все проверки прав выполняются через IPolicyEvaluator и политики. // Роли могут быть не нужны, если проверка доступа основана на атрибутах и политиках. // var accessClaims = new List<Claim>(baseClaims); // if (coreUser.Groups != null) // { // accessClaims.AddRange(coreUser.Groups // .Where(g => g.IsDefault) // .Select(g => new Claim(ClaimTypes.Role, g.Caption))); // } // Используем базовые claims для access token (без ролей) var accessClaims = new List<Claim>(baseClaims); var accessToken = _tokenService.GenerateAccessToken(accessClaims, accessTokenExpires); // Сохраняем refresh token await _refreshTokenRepository.SaveTokenAsync( coreUser.Login, refreshToken, DateTime.UtcNow, refreshTokenExpires, cancellationToken); return new AuthResponseModel { AccessToken = accessToken, AccessTokenExp = accessTokenExpires, RefreshToken = refreshToken }; } } }