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
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; |
|
} |
|
} |
|
}
|
|
|