.net core jwt
Nuget 下载
Microsoft.AspNetCore.Authentication.JwtBearer

System.IdentityModel.Tokens.Jwt


代码
1 public static class JwtHepler 2 { 3 4 /// <summary> 5 /// 颁发JWT字符串 6 /// </summary> 7 /// <param name="tokenModel"></param> 8 /// <returns></returns> 9 public static string IssueJwt(TokenModelJwt tokenModel) 10 { 11 string iss = AppSettings.app(new string[] { "Audience", "Issuer" }); 12 string aud = AppSettings.app(new string[] { "Audience", "Audience" }); 13 string secret = AppSettings.app(new string[] { "Audience", "Secret" }); 14 15 var claims = new List<Claim> 16 { 17 /* 18 * 特别重要: 19 1、这里将用户的部分信息,比如 uid 存到了Claim 中,如果你想知道如何在其他地方将这个 uid从 Token 中取出来,请看下边的SerializeJwt() 方法,或者在整个解决方案,搜索这个方法,看哪里使用了! 20 2、你也可以研究下 HttpContext.User.Claims ,具体的你可以看看 Policys/PermissionHandler.cs 类中是如何使用的。 21 */ 22 new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Id.ToString()), 23 new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"), 24 new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") , 25 //这个就是过期时间,目前是过期1000秒,可自定义,注意JWT有自己的缓冲过期时间 26 new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddSeconds(100000)).ToUnixTimeSeconds()}"), 27 new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(1000).ToString()), 28 new Claim(JwtRegisteredClaimNames.Iss,iss), 29 new Claim(JwtRegisteredClaimNames.Aud,aud), 30 }; 31 // 可以将一个用户的多个角色全部赋予; 32 claims.AddRange(tokenModel.Role.Split(',').Select(s => new Claim(ClaimTypes.Role, s))); 33 34 //秘钥 (SymmetricSecurityKey 对安全性的要求,密钥的长度太短会报出异常) 35 var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)); 36 var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); 37 38 var jwt = new JwtSecurityToken( 39 issuer: iss, 40 claims: claims, 41 signingCredentials: creds); 42 43 var jwtHandler = new JwtSecurityTokenHandler(); 44 var encodedJwt = jwtHandler.WriteToken(jwt); 45 return encodedJwt; 46 } 47 48 49 /// <summary> 50 /// 解析 51 /// </summary> 52 /// <param name="jwtStr"></param> 53 /// <returns></returns> 54 public static TokenModelJwt SerializeJwt(string jwtStr) 55 { 56 var jwtHandler = new JwtSecurityTokenHandler(); 57 TokenModelJwt tokenModelJwt = new TokenModelJwt(); 58 59 // token校验 60 if (!string.IsNullOrEmpty(jwtStr) && jwtHandler.CanReadToken(jwtStr)) 61 { 62 63 JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr); 64 65 object role; 66 67 jwtToken.Payload.TryGetValue(ClaimTypes.Role, out role); 68 69 tokenModelJwt = new TokenModelJwt 70 { 71 Id = Convert.ToInt32(jwtToken.Id), 72 Role = role == null ? "" : role.ToString() 73 }; 74 } 75 return tokenModelJwt; 76 } 77 78 /// <summary> 79 /// 授权解析jwt 80 /// </summary> 81 /// <param name="httpContext"></param> 82 /// <returns></returns> 83 public static TokenModelJwt ParsingJwtToken(HttpContext httpContext) 84 { 85 if (!httpContext.Request.Headers.ContainsKey("Authorization")) 86 return null; 87 var tokenHeader = httpContext.Request.Headers["Authorization"].ToString().Replace("Bearer ", ""); 88 TokenModelJwt tm = SerializeJwt(tokenHeader); 89 return tm; 90 } 91 }
Service注入
1 builder.Services.AddAuthentication(options => 2 { 3 options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; 4 options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; 5 }).AddJwtBearer(options => 6 { 7 //读取配置文件 8 var audienceConfig = builder.Configuration.GetSection("Audience"); 9 var symmetricKeyAsBase64 = audienceConfig["Secret"]; 10 var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64); 11 var signingKey = new SymmetricSecurityKey(keyByteArray); 12 options.TokenValidationParameters = new TokenValidationParameters 13 { 14 ValidateIssuerSigningKey = true, 15 IssuerSigningKey = signingKey, 16 ValidateIssuer = true, 17 ValidIssuer = audienceConfig["Issuer"],//发行人 18 ValidateAudience = true, 19 ValidAudience = audienceConfig["Audience"],//订阅人 20 ValidateLifetime = true, 21 ClockSkew = TimeSpan.Zero,//这个是缓冲过期时间,也就是说,即使我们配置了过期时间,这里也要考虑进去,过期时间+缓冲,默认好像是7分钟,你可以直接设置为0 22 RequireExpirationTime = true, 23 }; 24 });
AppSettings类
1 public class AppSettings 2 { 3 static IConfiguration Configuration { get; set; } 4 static string ContentPath { get; set; } 5 public AppSettings(IConfiguration configuration) 6 { 7 Configuration = configuration; 8 } 9 public AppSettings(string contentPath) 10 { 11 string path = "appsettings.json"; 12 13 Configuration = new ConfigurationBuilder() 14 .SetBasePath(contentPath).Add(new JsonConfigurationSource { Path = path, Optional = false, ReloadOnChange = true }).Build(); 15 } 16 17 public static string app(params string[] sections) 18 { 19 try 20 { 21 if (sections.Any()) 22 { 23 return Configuration[string.Join(":", sections)]; 24 } 25 } 26 catch (Exception) 27 { 28 29 throw; 30 } 31 return ""; 32 } 33 34 public static List<T> app<T>(params string[] sections) 35 { 36 List<T> list = new List<T>(); 37 Configuration.Bind(string.Join(":", sections), list); 38 return list; 39 } 40 }
TokenModelJwt
1 /// <summary> 2 /// token 3 /// </summary> 4 public class TokenModelJwt 5 { 6 /// <summary> 7 /// id 8 /// </summary> 9 public long Id { get; set; } 10 /// <summary> 11 /// 角色 12 /// </summary> 13 public string Role { get; set; } 14 /// <summary> 15 /// 职能 16 /// </summary> 17 public string Work { get; set; } 18 }
appsettings.json 配置
1 "Audience": { 2 "Secret": "sdfsdfsrty45634kkhllghtdgdfss345t678fs", //密钥 3 "Issuer": "SwiftCode.BBS", //发行人 4 "Audience": "wr" //订阅人 5 }
控制器
1 /// <summary> 2 /// 控制器 3 /// </summary> 4 [Route("api/[controller]")] 5 [ApiController] 6 public class LoginController : ControllerBase 7 { 8 /// <summary> 9 /// 10 /// </summary> 11 public LoginController() 12 { 13 14 } 15 /// <summary> 16 /// 获取令牌 17 /// </summary> 18 /// <param name="name"></param> 19 /// <param name="pass"></param> 20 /// <returns></returns> 21 [HttpGet] 22 public string GetJwtStr(string name, string pass) 23 { 24 string token = JwtHepler.IssueJwt(new TokenModelJwt { Id = 1, Role = "admin", Work = "开发" }); 25 return token; 26 } 27 }
JwtRegisteredClaimNames 属性说明
| 声明栏位 | 说明 | 连结 |
|---|---|---|
| Jti | 表示 JWT ID,Token 的唯一识别码 | http://tools.ietf.org/html/rfc7519#section-4 |
| Iss | 表示 Issuer,发送 Token 的发行者 | http://tools.ietf.org/html/rfc7519#section-4 |
| Iat | 表示 Issued At,Token 的建立时间 | http://tools.ietf.org/html/rfc7519#section-4 |
| Exp | 表示 Expiration Time,Token 的逾期时间 | http://tools.ietf.org/html/rfc7519#section-4 |
| Sub | 表示 Subject,Token 的主体内容 | http://tools.ietf.org/html/rfc7519#section-4 |
| Aud | 表示 Audience,接收 Token 的观众 | http://tools.ietf.org/html/rfc7519#section-4 |
| Typ | 表示 Token 的类型,例如 JWT 表示 JSON Web Token 类型 | http://tools.ietf.org/html/rfc7519#section-4 |
| Nbf | 表示 Not Before,定义在什麽时间之前,不可用 | http://tools.ietf.org/html/rfc7519#section-4 |
| Actort | 识别执行授权的代理是谁 | http://tools.ietf.org/html/rfc7519#section-4 |
| Prn | http://tools.ietf.org/html/rfc7519#section-4 | |
| Nonce | http://tools.ietf.org/html/rfc7519#section-4 | |
| NameId | 使用者识别码 | http://tools.ietf.org/html/rfc7519#section-4 |
| FamilyName | 使用者姓氏 | http://tools.ietf.org/html/rfc7519#section-4 |
| GivenName | 使用者名字 | http://tools.ietf.org/html/rfc7519#section-4 |
| Gender | 使用者性别 | http://tools.ietf.org/html/rfc7519#section-4 |
| 使用者的电子邮件 | http://tools.ietf.org/html/rfc7519#section-4 | |
| Birthdate | 使用者生日 | http://tools.ietf.org/html/rfc7519#section-4 |
| Website | 使用者的网站 | http://tools.ietf.org/html/rfc7519#section-4 |
| CHash | http://tools.ietf.org/html/rfc7519#section-4 | |
| UniqueName | http://tools.ietf.org/html/rfc7519#section-4 | |
| AtHash | http://openid.net/specs/openid-connect-core-1_0.html#CodeIDToken | |
| Acr | http://openid.net/specs/openid-connect-core-1_0.html#IDToken | |
| Amr | http://openid.net/specs/openid-connect-core-1_0.html#IDToken | |
| Azp | http://openid.net/specs/openid-connect-core-1_0.html#IDToken | |
| AuthTime | http://openid.net/specs/openid-connect-core-1_0.html#IDToken | |
| Sid | http://openid.net/specs/openid-connect-frontchannel-1_0.html#OPLogout |
浙公网安备 33010602011771号