JwtAuthExtension.cs 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  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 schoolID = "", string[] roles = null, string[] permissions = null, int expire = 1)
  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. };
  29. // 建立一組對稱式加密的金鑰,主要用於 JWT 簽章之用
  30. var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(salt));
  31. // HmacSha256 有要求必須要大於 128 bits,所以 salt 不能太短,至少要 16 字元以上
  32. // https://stackoverflow.com/questions/47279947/idx10603-the-algorithm-hs256-requires-the-securitykey-keysize-to-be-greater
  33. var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
  34. var header = new JwtHeader(signingCredentials);
  35. var secToken = new JwtSecurityToken(header, payload);
  36. // 產出所需要的 JWT securityToken 物件,並取得序列化後的 Token 結果(字串格式)
  37. var tokenHandler = new JwtSecurityTokenHandler();
  38. //var securityToken = tokenHandler.CreateToken(tokenDescriptor);
  39. var serializeToken = tokenHandler.WriteToken(secToken);
  40. return serializeToken;
  41. }
  42. public static bool ValidateAuthToken(string token, string salt)
  43. {
  44. try
  45. {
  46. var handler = new JwtSecurityTokenHandler();
  47. var validationParameters = new TokenValidationParameters
  48. {
  49. RequireExpirationTime = true,
  50. ValidateIssuer = false,
  51. ValidateAudience = false,
  52. IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(salt)),
  53. ValidateLifetime = false,
  54. //LifetimeValidator = LifetimeValidator,
  55. ClockSkew = TimeSpan.Zero
  56. };
  57. ClaimsPrincipal principal = handler.ValidateToken(token, validationParameters, out SecurityToken securityToken);
  58. return true;
  59. }
  60. catch (Exception)
  61. {
  62. //Trace.WriteLine(ex.Message);
  63. return false;
  64. }
  65. }
  66. }
  67. }