JwtAuthExtension.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. using Microsoft.AspNetCore.Authentication.JwtBearer;
  2. using Microsoft.AspNetCore.Authorization;
  3. using Microsoft.Extensions.Configuration;
  4. using Microsoft.Extensions.DependencyInjection;
  5. using Microsoft.IdentityModel.Tokens;
  6. using System;
  7. using System.Threading.Tasks;
  8. using System.Security.Claims;
  9. using System.IdentityModel.Tokens.Jwt;
  10. using System.Collections.Generic;
  11. using System.Text;
  12. namespace TEAMModelOS.SDK.Extension
  13. {
  14. public static class JwtAuthExtension
  15. {
  16. public static string CreateAuthToken(string issuer, string id, string name, string picture, string salt, string scope,string Website, string schoolID = "", string standard = "", string[] roles = null, string[] permissions = null, int expire = 1, string[] ddDepts = null, string ddsub = null)
  17. {
  18. // 設定要加入到 JWT Token 中的聲明資訊(Claims)
  19. var payload = new JwtPayload {
  20. { JwtRegisteredClaimNames.Iss, issuer }, //發行者
  21. { JwtRegisteredClaimNames.Sub, id }, // 用戶ID
  22. { JwtRegisteredClaimNames.Azp,schoolID}, // 學校簡碼,如果有的話
  23. { JwtRegisteredClaimNames.Exp,DateTimeOffset.UtcNow.AddHours(expire).ToUnixTimeSeconds().ToString()}, // 到期的時間,必須為數字
  24. { "name",name}, // 用戶的顯示名稱
  25. { "picture",picture}, // 用戶頭像
  26. { "roles",roles}, // 登入者的角色,角色類型 (Admin、Teacher、Student)
  27. { "permissions",permissions}, //登入者的權限請求
  28. { "standard",standard} ,//登入者的能力点标准
  29. { "scope",scope}, //登入者的入口类型。 (teacher 教师端登录的醍摩豆ID、tmduser学生端登录的醍摩豆ID、student学生端登录校内账号的学生ID)
  30. { "dddepts",ddDepts}, //登陆者的钉钉部门id
  31. { "ddsub",ddsub } , //登陆者的钉钉用户id
  32. { JwtRegisteredClaimNames.Website,Website}, // 學校簡碼,如果有的話
  33. };
  34. // 建立一組對稱式加密的金鑰,主要用於 JWT 簽章之用
  35. var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(salt));
  36. // HmacSha256 有要求必須要大於 128 bits,所以 salt 不能太短,至少要 16 字元以上
  37. // https://stackoverflow.com/questions/47279947/idx10603-the-algorithm-hs256-requires-the-securitykey-keysize-to-be-greater
  38. var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
  39. var header = new JwtHeader(signingCredentials);
  40. var secToken = new JwtSecurityToken(header, payload);
  41. // 產出所需要的 JWT securityToken 物件,並取得序列化後的 Token 結果(字串格式)
  42. var tokenHandler = new JwtSecurityTokenHandler();
  43. //var securityToken = tokenHandler.CreateToken(tokenDescriptor);
  44. var serializeToken = tokenHandler.WriteToken(secToken);
  45. return serializeToken;
  46. }
  47. public static string CreateApiToken(string issuer, string id, string salt,string name,List<int> auth , string schoolID = "", int expire = 1)
  48. {
  49. // 設定要加入到 JWT Token 中的聲明資訊(Claims)
  50. var payload = new JwtPayload {
  51. { JwtRegisteredClaimNames.Iss, issuer }, //發行者 iss: jwt签发者
  52. { JwtRegisteredClaimNames.Sub, id }, // APPID sub: jwt所面向的用户
  53. { JwtRegisteredClaimNames.Aud, "" }, // aud: 接收jwt的一方
  54. { JwtRegisteredClaimNames.Azp,schoolID}, // 學校簡碼,如果有的話
  55. {JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString() },
  56. { "name",name}, // 用戶的顯示名稱
  57. //{ JwtRegisteredClaimNames.Exp,DateTimeOffset.UtcNow.AddHours(expire).ToUnixTimeSeconds().ToString()}, // 到期的時間,必須為數字
  58. //{ "name",name}, // 用戶的顯示名稱
  59. //{ "picture",picture}, // 用戶頭像
  60. { "auth",auth}, // 登入者的角色,角色類型 (Admin、Teacher、Student)
  61. // { "permissions",permissions} //登入者的權限請求
  62. };
  63. // 建立一組對稱式加密的金鑰,主要用於 JWT 簽章之用
  64. var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(salt));
  65. // HmacSha256 有要求必須要大於 128 bits,所以 salt 不能太短,至少要 16 字元以上
  66. // https://stackoverflow.com/questions/47279947/idx10603-the-algorithm-hs256-requires-the-securitykey-keysize-to-be-greater
  67. var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
  68. var header = new JwtHeader(signingCredentials);
  69. var secToken = new JwtSecurityToken(header, payload);
  70. // 產出所需要的 JWT securityToken 物件,並取得序列化後的 Token 結果(字串格式)
  71. var tokenHandler = new JwtSecurityTokenHandler();
  72. //var securityToken = tokenHandler.CreateToken(tokenDescriptor);
  73. var serializeToken = tokenHandler.WriteToken(secToken);
  74. return serializeToken;
  75. }
  76. public static bool ValidateApiToken(string token, string salt)
  77. {
  78. try
  79. {
  80. var handler = new JwtSecurityTokenHandler();
  81. var validationParameters = new TokenValidationParameters
  82. {
  83. RequireExpirationTime = false,
  84. ValidateIssuer = false,
  85. ValidateAudience = false,
  86. IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(salt)),
  87. ValidateLifetime = false,
  88. //LifetimeValidator = LifetimeValidator,
  89. ClockSkew = TimeSpan.Zero
  90. };
  91. ClaimsPrincipal principal = handler.ValidateToken(token, validationParameters, out SecurityToken securityToken);
  92. return true;
  93. }
  94. catch (Exception)
  95. {
  96. //Trace.WriteLine(ex.Message);
  97. return false;
  98. }
  99. }
  100. public static bool ValidateAuthToken(string token, string salt)
  101. {
  102. try
  103. {
  104. var handler = new JwtSecurityTokenHandler();
  105. var validationParameters = new TokenValidationParameters
  106. {
  107. RequireExpirationTime = true,
  108. ValidateIssuer = false,
  109. ValidateAudience = false,
  110. IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(salt)),
  111. ValidateLifetime = false,
  112. //LifetimeValidator = LifetimeValidator,
  113. ClockSkew = TimeSpan.Zero
  114. };
  115. ClaimsPrincipal principal = handler.ValidateToken(token, validationParameters, out SecurityToken securityToken);
  116. return true;
  117. }
  118. catch (Exception)
  119. {
  120. //Trace.WriteLine(ex.Message);
  121. return false;
  122. }
  123. }
  124. }
  125. }