131 lines
3.6 KiB
C#
131 lines
3.6 KiB
C#
using TechHelper.Context;
|
|
using Entities.Configuration;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Microsoft.Extensions.Options;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using System.IdentityModel.Tokens.Jwt;
|
|
using System.Security.Claims;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using Entities.Contracts;
|
|
|
|
namespace TechHelper.Services
|
|
{
|
|
public class AuthenticationService : IAuthenticationService
|
|
{
|
|
private readonly JwtConfiguration _jwtSettings;
|
|
private readonly JwtSecurityTokenHandler _jwtHandler;
|
|
private readonly UserManager<User> _userManager;
|
|
private readonly IClassService _classService;
|
|
public AuthenticationService(IOptions<JwtConfiguration> jwtSettings, UserManager<User> userManager, IClassService classService)
|
|
{
|
|
_jwtSettings = jwtSettings.Value;
|
|
_jwtHandler = new JwtSecurityTokenHandler();
|
|
_userManager = userManager;
|
|
_classService = classService;
|
|
}
|
|
|
|
public async Task<string> GetToken(User user)
|
|
{
|
|
var signingCredentials = GetSigningCredentials();
|
|
|
|
var claims = await GetClaims(user);
|
|
|
|
var tokenOptions = GenerateTokenOptions(signingCredentials, claims);
|
|
|
|
return _jwtHandler.WriteToken(tokenOptions);
|
|
}
|
|
|
|
private SigningCredentials GetSigningCredentials()
|
|
{
|
|
var key = Encoding.UTF8.GetBytes(_jwtSettings.SecurityKey);
|
|
var secret = new SymmetricSecurityKey(key);
|
|
|
|
return new SigningCredentials(secret, SecurityAlgorithms.HmacSha256);
|
|
}
|
|
|
|
private async Task<IEnumerable<Claim>> GetClaims(User user)
|
|
{
|
|
var claims = new List<Claim>
|
|
{
|
|
new Claim(ClaimTypes.Name, user.Email)
|
|
};
|
|
|
|
var roles = await _userManager.GetRolesAsync(user);
|
|
foreach (var role in roles)
|
|
{
|
|
claims.Add(new Claim(ClaimTypes.Role, role));
|
|
}
|
|
|
|
var classInfo = await _classService.GetUserClass(user.Id);
|
|
if (classInfo.Status)
|
|
{
|
|
var classs = classInfo.Result as List<Class>;
|
|
|
|
classs?.ForEach(c =>
|
|
{
|
|
|
|
claims.Add(new Claim("Grade", c.Grade.ToString()));
|
|
claims.Add(new Claim("Class", c.Number.ToString()));
|
|
});
|
|
}
|
|
|
|
return claims;
|
|
}
|
|
|
|
private JwtSecurityToken GenerateTokenOptions(SigningCredentials signingCredentials, IEnumerable<Claim> claims)
|
|
{
|
|
var tokenOptions = new JwtSecurityToken(
|
|
issuer: _jwtSettings.ValidIssuer,
|
|
audience: _jwtSettings.ValidAudience,
|
|
claims: claims,
|
|
expires: DateTime.UtcNow.AddMinutes(Convert.ToDouble(
|
|
_jwtSettings.ExpiryInMinutes)),
|
|
signingCredentials: signingCredentials);
|
|
|
|
return tokenOptions;
|
|
}
|
|
|
|
public string GenerateRefreshToken()
|
|
{
|
|
var randomNumber = new byte[32];
|
|
using (var rng = RandomNumberGenerator.Create())
|
|
{
|
|
rng.GetBytes(randomNumber);
|
|
return Convert.ToBase64String(randomNumber);
|
|
}
|
|
}
|
|
|
|
public ClaimsPrincipal GetPrincipalFromExpiredToken(string token)
|
|
{
|
|
var tokenValidationParameters = new TokenValidationParameters
|
|
{
|
|
ValidateAudience = true,
|
|
ValidateIssuer = true,
|
|
ValidateIssuerSigningKey = true,
|
|
IssuerSigningKey = new SymmetricSecurityKey(
|
|
Encoding.UTF8.GetBytes(_jwtSettings.SecurityKey)),
|
|
ValidateLifetime = false,
|
|
ValidIssuer = _jwtSettings.ValidIssuer,
|
|
ValidAudience = _jwtSettings.ValidAudience,
|
|
};
|
|
|
|
var tokenHandler = new JwtSecurityTokenHandler();
|
|
SecurityToken securityToken;
|
|
|
|
var principal = tokenHandler.ValidateToken(token,
|
|
tokenValidationParameters, out securityToken);
|
|
|
|
var jwtSecurityToken = securityToken as JwtSecurityToken;
|
|
if (jwtSecurityToken == null ||
|
|
!jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256,
|
|
StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
throw new SecurityTokenException("Invalid token");
|
|
}
|
|
|
|
return principal;
|
|
}
|
|
}
|
|
}
|