You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

132 lines
5.0 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using EntrustSettle.Common;
using EntrustSettle.Common.AppConfig;
using Microsoft.IdentityModel.Tokens;
namespace EntrustSettle.AuthHelper.OverWrite
{
public class JwtHelper
{
/// <summary>
/// 颁发JWT字符串
/// </summary>
/// <param name="tokenModel"></param>
/// <returns></returns>
public static string IssueJwt(TokenModelJwt tokenModel)
{
string iss = AppSettings.app(new string[] { "Audience", "Issuer" });
string aud = AppSettings.app(new string[] { "Audience", "Audience" });
string secret = AppSecretConfig.Audience_Secret_String;
//var claims = new Claim[] //old
var claims = new List<Claim>
{
/*
* 特别重要:
1、这里将用户的部分信息比如 uid 存到了Claim 中,如果你想知道如何在其他地方将这个 uid从 Token 中取出来请看下边的SerializeJwt() 方法,或者在整个解决方案,搜索这个方法,看哪里使用了!
2、你也可以研究下 HttpContext.User.Claims ,具体的你可以看看 Policys/PermissionHandler.cs 类中是如何使用的。
*/
new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Uid.ToString()),
new Claim(JwtRegisteredClaimNames.Iat, $"{DateTime.Now.DateToTimeStamp()}"),
new Claim(JwtRegisteredClaimNames.Nbf,$"{DateTime.Now.DateToTimeStamp()}") ,
//这个就是过期时间目前是过期1000秒可自定义注意JWT有自己的缓冲过期时间
new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddSeconds(1000)).ToUnixTimeSeconds()}"),
new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(1000).ToString()),
new Claim(JwtRegisteredClaimNames.Iss,iss),
new Claim(JwtRegisteredClaimNames.Aud,aud),
//new Claim(ClaimTypes.Role,tokenModel.Role),//为了解决一个用户多个角色(比如Admin,System),用下边的方法
};
// 可以将一个用户的多个角色全部赋予;
claims.AddRange(tokenModel.Role.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
//秘钥 (SymmetricSecurityKey 对安全性的要求,密钥的长度太短会报出异常)
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var jwt = new JwtSecurityToken(
issuer: iss,
claims: claims,
signingCredentials: creds);
var jwtHandler = new JwtSecurityTokenHandler();
var encodedJwt = jwtHandler.WriteToken(jwt);
return encodedJwt;
}
/// <summary>
/// 解析
/// </summary>
/// <param name="jwtStr"></param>
/// <returns></returns>
public static TokenModelJwt SerializeJwt(string jwtStr)
{
var jwtHandler = new JwtSecurityTokenHandler();
TokenModelJwt tokenModelJwt = new TokenModelJwt();
// token校验
if (jwtStr.IsNotEmptyOrNull() && jwtHandler.CanReadToken(jwtStr))
{
JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr);
object role;
jwtToken.Payload.TryGetValue(ClaimTypes.Role, out role);
tokenModelJwt = new TokenModelJwt
{
Uid = (jwtToken.Id).ObjToLong(),
Role = role != null ? role.ObjToString() : "",
};
}
return tokenModelJwt;
}
public static bool customSafeVerify(string token)
{
var jwtHandler = new JwtSecurityTokenHandler();
var symmetricKeyAsBase64 = AppSecretConfig.Audience_Secret_String;
var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64);
var signingKey = new SymmetricSecurityKey(keyByteArray);
var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
var jwt = jwtHandler.ReadJwtToken(token);
return jwt.RawSignature == Microsoft.IdentityModel.JsonWebTokens.JwtTokenUtilities.CreateEncodedSignature(jwt.RawHeader + "." + jwt.RawPayload, signingCredentials);
}
}
/// <summary>
/// 令牌
/// </summary>
public class TokenModelJwt
{
/// <summary>
/// Id
/// </summary>
public long Uid { get; set; }
/// <summary>
/// 角色
/// </summary>
public string Role { get; set; }
/// <summary>
/// 职能
/// </summary>
public string Work { get; set; }
}
}