JwtAuthExtension.cs 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. using Microsoft.IdentityModel.Tokens;
  2. using System.IdentityModel.Tokens.Jwt;
  3. using System.Security.Claims;
  4. using System.Text;
  5. namespace IES.ExamServer
  6. {
  7. public class JwtAuthExtension
  8. {
  9. public static bool ValidateAuthToken(string token, string salt)
  10. {
  11. try
  12. {
  13. var handler = new JwtSecurityTokenHandler();
  14. var validationParameters = new TokenValidationParameters
  15. {
  16. RequireExpirationTime = false,
  17. ValidateIssuer = false,
  18. ValidateAudience = false,
  19. IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(salt)),
  20. ValidateLifetime = false,
  21. //LifetimeValidator = LifetimeValidator,
  22. ClockSkew = TimeSpan.Zero
  23. };
  24. ClaimsPrincipal principal = handler.ValidateToken(token, validationParameters, out SecurityToken securityToken);
  25. return true;
  26. }
  27. catch (Exception)
  28. {
  29. //Trace.WriteLine(ex.Message);
  30. return false;
  31. }
  32. }
  33. public static string CreateAuthToken(string? issuer, string? id, string? name, string? picture, string? salt, string? scope, int timezone, string? schoolID =null,string[]? roles = null, int expire = 1, int year = -1)
  34. {
  35. // 設定要加入到 JWT Token 中的聲明資訊(Claims)
  36. var payload = new JwtPayload {
  37. { JwtRegisteredClaimNames.Iss, issuer }, //發行者
  38. { JwtRegisteredClaimNames.Azp,schoolID}, // 學校簡碼,如果有的話
  39. { JwtRegisteredClaimNames.Sub, id }, // 用戶ID
  40. { JwtRegisteredClaimNames.Exp,DateTimeOffset.UtcNow.AddHours(expire).ToUnixTimeSeconds()}, // 到期的時間,必須為數字
  41. { "name",name}, // 用戶的顯示名稱
  42. { "picture",picture}, // 用戶頭像
  43. { "roles",roles}, // 登入者的角色,角色類型 (Admin、Teacher、Student)
  44. { "scope",scope}, //登入者的入口类型。 (teacher 教师端登录的醍摩豆ID、tmduser学生端登录的醍摩豆ID、student学生端登录校内账号的学生ID)
  45. { "timezone",timezone},
  46. { JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString()}
  47. };
  48. // 建立一組對稱式加密的金鑰,主要用於 JWT 簽章之用
  49. var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(salt));
  50. // HmacSha256 有要求必須要大於 128 bits,所以 salt 不能太短,至少要 16 字元以上
  51. // https://stackoverflow.com/questions/47279947/idx10603-the-algorithm-hs256-requires-the-securitykey-keysize-to-be-greater
  52. //var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
  53. var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
  54. var header = new JwtHeader(signingCredentials);
  55. var secToken = new JwtSecurityToken(header, payload);
  56. // 產出所需要的 JWT securityToken 物件,並取得序列化後的 Token 結果(字串格式)
  57. var tokenHandler = new JwtSecurityTokenHandler();
  58. //var securityToken = tokenHandler.CreateToken(tokenDescriptor);
  59. var serializeToken = tokenHandler.WriteToken(secToken);
  60. return serializeToken;
  61. }
  62. }
  63. }