Add hashing and other security features #12
82
Endpoint/Common/Services/Security/JwtTokenService.cs
Normal file
82
Endpoint/Common/Services/Security/JwtTokenService.cs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
using Mirea.Api.Security.Common.Interfaces;
|
||||||
|
using System;
|
||||||
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace Mirea.Api.Endpoint.Common.Services.Security;
|
||||||
|
|
||||||
|
public class JwtTokenService : IAccessToken
|
||||||
|
{
|
||||||
|
public required string Issuer { private get; init; }
|
||||||
|
public required string Audience { private get; init; }
|
||||||
|
public TimeSpan Lifetime { private get; init; }
|
||||||
|
|
||||||
|
public ReadOnlyMemory<byte> EncryptionKey { get; init; }
|
||||||
|
public ReadOnlyMemory<byte> SigningKey { private get; init; }
|
||||||
|
|
||||||
|
public (string Token, DateTime ExpireIn) GenerateToken(string userId)
|
||||||
|
{
|
||||||
|
var tokenHandler = new JwtSecurityTokenHandler();
|
||||||
|
var signingKey = new SymmetricSecurityKey(SigningKey.ToArray());
|
||||||
|
var encryptionKey = new SymmetricSecurityKey(EncryptionKey.ToArray());
|
||||||
|
var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha512);
|
||||||
|
|
||||||
|
var expires = DateTime.UtcNow.Add(Lifetime);
|
||||||
|
|
||||||
|
var tokenDescriptor = new SecurityTokenDescriptor
|
||||||
|
{
|
||||||
|
Issuer = Issuer,
|
||||||
|
Audience = Audience,
|
||||||
|
Expires = expires,
|
||||||
|
SigningCredentials = signingCredentials,
|
||||||
|
Subject = new ClaimsIdentity(
|
||||||
|
[
|
||||||
|
new Claim(ClaimTypes.Name, userId),
|
||||||
|
// todo: get role by userId
|
||||||
|
new Claim(ClaimTypes.Role, "")
|
||||||
|
]),
|
||||||
|
EncryptingCredentials = new EncryptingCredentials(encryptionKey, SecurityAlgorithms.Aes256KW, SecurityAlgorithms.Aes256CbcHmacSha512)
|
||||||
|
};
|
||||||
|
|
||||||
|
var token = tokenHandler.CreateToken(tokenDescriptor);
|
||||||
|
|
||||||
|
return (tokenHandler.WriteToken(token), expires);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTimeOffset GetExpireDateTime(string token)
|
||||||
|
{
|
||||||
|
var tokenHandler = new JwtSecurityTokenHandler();
|
||||||
|
var signingKey = new SymmetricSecurityKey(SigningKey.ToArray());
|
||||||
|
var encryptionKey = new SymmetricSecurityKey(EncryptionKey.ToArray());
|
||||||
|
|
||||||
|
var tokenValidationParameters = new TokenValidationParameters
|
||||||
|
{
|
||||||
|
ValidIssuer = Issuer,
|
||||||
|
ValidAudience = Audience,
|
||||||
|
IssuerSigningKey = signingKey,
|
||||||
|
TokenDecryptionKey = encryptionKey,
|
||||||
|
ValidateIssuer = true,
|
||||||
|
ValidateAudience = true,
|
||||||
|
ValidateIssuerSigningKey = true,
|
||||||
|
ValidateLifetime = false
|
||||||
|
};
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var claimsPrincipal = tokenHandler.ValidateToken(token, tokenValidationParameters, out _);
|
||||||
|
|
||||||
|
var expClaim = claimsPrincipal.Claims.FirstOrDefault(c => c.Type == "exp");
|
||||||
|
|
||||||
|
if (expClaim != null && long.TryParse(expClaim.Value, out var expUnix))
|
||||||
|
return DateTimeOffset.FromUnixTimeSeconds(expUnix);
|
||||||
|
}
|
||||||
|
catch (SecurityTokenException)
|
||||||
|
{
|
||||||
|
return DateTimeOffset.MinValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DateTimeOffset.MinValue;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user