消防培训系统服务器
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

97 lines
3.1 KiB

using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
namespace AX.FireTrainingSys.Services
{
/// <summary>
/// JWT 服务。
/// </summary>
public class JwtService : IJwtService
{
private readonly IOptionsMonitor<JwtOptions> options;
public JwtService(IOptionsMonitor<JwtOptions> options)
{
this.options = options;
}
/// <summary>
/// 创建一个 JWT。
/// </summary>
/// <param name="identity"></param>
/// <returns></returns>
public string Create(ClaimsIdentity identity)
{
var jwtOptions = options.CurrentValue;
var now = DateTimeOffset.Now;
var expires = now.AddMinutes(jwtOptions.Expires);
var secret = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOptions.Secret));
var creds = new SigningCredentials(secret, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: jwtOptions.Issuer,
audience: jwtOptions.Audience,
claims: identity.Claims,
notBefore: now.DateTime,
expires: expires.DateTime,
signingCredentials: creds);
var handler = new JwtSecurityTokenHandler();
var jwt = handler.WriteToken(token);
return jwt;
}
/// <summary>
/// 验证 JWT 是否有效。
/// </summary>
/// <param name="token"></param>
/// <param name="principal"></param>
/// <returns></returns>
public bool Validate(string token, out ClaimsPrincipal principal)
{
principal = null;
var jwtOptions = options.CurrentValue;
var secret = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOptions.Secret));
var validationParameters = new TokenValidationParameters
{
NameClaimType = JwtClaimTypes.Name,
RoleClaimType = JwtClaimTypes.Role,
ValidateIssuer = true,
ValidIssuer = jwtOptions.Issuer,
ValidateAudience = true,
ValidAudience = jwtOptions.Audience,
ValidateIssuerSigningKey = true,
IssuerSigningKey = secret,
RequireExpirationTime = true,
ValidateLifetime = false
};
var handler = new JwtSecurityTokenHandler();
try
{
principal = handler.ValidateToken(token, validationParameters, out var jwt);
return true;
}
catch
{
return false;
}
}
/// <summary>
/// 解析 JWT,但不验证。
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
public JwtSecurityToken Decode(string token)
{
var handler = new JwtSecurityTokenHandler();
var jwt = handler.ReadJwtToken(token);
return jwt;
}
}
}