|
@@ -0,0 +1,77 @@
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.IdentityModel.Tokens.Jwt;
|
|
|
+using System.Linq;
|
|
|
+using System.Security.Authentication;
|
|
|
+using System.Security.Claims;
|
|
|
+using System.Text;
|
|
|
+using System.Threading.Tasks;
|
|
|
+using Microsoft.AspNetCore.Http;
|
|
|
+using Microsoft.AspNetCore.Mvc;
|
|
|
+using Microsoft.Extensions.Options;
|
|
|
+using Microsoft.IdentityModel.Tokens;
|
|
|
+using XF.Domain.Dependency;
|
|
|
+using XF.Domain.Exceptions;
|
|
|
+using XF.Domain.Options;
|
|
|
+
|
|
|
+namespace XF.Domain.Authentications
|
|
|
+{
|
|
|
+ public interface IJwtSecurity
|
|
|
+ {
|
|
|
+ string EncodeJwtToken(ICollection<Claim> claims);
|
|
|
+ void DecodeJwtToken(string jwt);
|
|
|
+ }
|
|
|
+
|
|
|
+ public class JwtSecurity : IJwtSecurity, IScopeDependency
|
|
|
+ {
|
|
|
+ private readonly IOptions<IdentityConfiguration> _jwtConfigOptionAccessor;
|
|
|
+ private readonly IHttpContextAccessor _contextAccessor;
|
|
|
+
|
|
|
+ public JwtSecurity(IOptions<IdentityConfiguration> jwtConfigOptionAccessor, IHttpContextAccessor contextAccessor)
|
|
|
+ {
|
|
|
+ _jwtConfigOptionAccessor = jwtConfigOptionAccessor;
|
|
|
+ _contextAccessor = contextAccessor;
|
|
|
+ }
|
|
|
+
|
|
|
+ public string EncodeJwtToken(ICollection<Claim> claims)
|
|
|
+ {
|
|
|
+ var jwtOptions = _jwtConfigOptionAccessor.Value.Jwt;
|
|
|
+ if (jwtOptions == null)
|
|
|
+ throw new ArgumentNullException(nameof(jwtOptions));
|
|
|
+
|
|
|
+ var bytes = Encoding.UTF8.GetBytes(jwtOptions.SecretKey);
|
|
|
+ var securityKey = new SymmetricSecurityKey(bytes);
|
|
|
+ var signingCredentials =
|
|
|
+ new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
|
|
|
+ var expired = DateTime.Now.AddMinutes(jwtOptions.Expired);
|
|
|
+ var jwtSecurityToken = new JwtSecurityToken(jwtOptions.Issuer, jwtOptions.Audience, claims, DateTime.Now, expired,
|
|
|
+ signingCredentials);
|
|
|
+ var tokenHandler = new JwtSecurityTokenHandler();
|
|
|
+ var token = tokenHandler.WriteToken(jwtSecurityToken);
|
|
|
+ return token;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void DecodeJwtToken(string jwt)
|
|
|
+ {
|
|
|
+ var jwtOptions = _jwtConfigOptionAccessor.Value.Jwt;
|
|
|
+ if (jwtOptions == null)
|
|
|
+ throw new ArgumentNullException(nameof(jwtOptions));
|
|
|
+
|
|
|
+ JwtSecurityTokenHandler tokenHandler = new();
|
|
|
+ TokenValidationParameters valParam = new();
|
|
|
+ var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOptions.SecretKey));
|
|
|
+ valParam.IssuerSigningKey = securityKey;
|
|
|
+ valParam.ValidateIssuer = false;
|
|
|
+ valParam.ValidateAudience = false;
|
|
|
+ ClaimsPrincipal claimsPrincipal = tokenHandler.ValidateToken(jwt, valParam, out SecurityToken secToken);
|
|
|
+ //foreach (var claim in claimsPrincipal.Claims)
|
|
|
+ //{
|
|
|
+ // Console.WriteLine($"{claim.Type}={claim.Value}");
|
|
|
+
|
|
|
+ //}
|
|
|
+ if (_contextAccessor.HttpContext is null)
|
|
|
+ throw new AuthenticationException($"{nameof(_contextAccessor.HttpContext)} is null");
|
|
|
+ _contextAccessor.HttpContext.User = claimsPrincipal;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|