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.
85 lines
2.9 KiB
85 lines
2.9 KiB
2 years ago
|
using Microsoft.Extensions.Options;
|
||
|
using Microsoft.IdentityModel.Tokens;
|
||
|
using System.IdentityModel.Tokens.Jwt;
|
||
|
using System.Security.Claims;
|
||
|
using System.Text;
|
||
|
|
||
|
namespace BuaaLocationServer.Middlewares.Jwts
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// JWT 服务。
|
||
|
/// </summary>
|
||
|
public class JwtService : IJwtService
|
||
|
{
|
||
|
private readonly IOptionsMonitor<JwtOptions> options;
|
||
|
|
||
|
public JwtService(IOptionsMonitor<JwtOptions> options)
|
||
|
{
|
||
|
this.options = options;
|
||
|
//var jwtOptions = options.CurrentValue;
|
||
|
}
|
||
|
|
||
|
/// <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)
|
||
|
{
|
||
|
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
|
||
|
{
|
||
|
principal = new ClaimsPrincipal();
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|