JwtAuth.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. using IdentityModel;
  2. using Microsoft.AspNetCore.Authentication.JwtBearer;
  3. using Microsoft.AspNetCore.Authorization;
  4. using Microsoft.Extensions.Configuration;
  5. using Microsoft.Extensions.DependencyInjection;
  6. using Microsoft.IdentityModel.Tokens;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Threading.Tasks;
  11. using TEAMModelOS.SDK.Context.Configuration;
  12. using TEAMModelOS.SDK.Helper.Security.RSACrypt;
  13. namespace HiTeachCE.Extension
  14. {
  15. public static class JwtAuth
  16. {
  17. public static void Auth(this IServiceCollection services, IConfigurationSection configuration)
  18. {
  19. services.Configure<JwtSetting>(configuration);
  20. string path = BaseConfigModel.ContentRootPath;
  21. SecurityKey creds = RsaHelper.GenerateValidationKey(path + "/public.pem");
  22. // 令牌验证参数
  23. var tokenValidationParameters = new TokenValidationParameters
  24. {
  25. //NameClaimType = JwtClaimTypes.Name,
  26. //RoleClaimType = JwtClaimTypes.Role,
  27. ValidateIssuerSigningKey = true,
  28. IssuerSigningKey = creds,
  29. ValidateIssuer = true,
  30. ValidIssuer = configuration["Issuer"],//发行人
  31. ValidateAudience = true,
  32. ValidAudience = configuration["Audience"],//订阅人
  33. ValidateLifetime = true,// 是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比
  34. //允许的服务器时间偏移量
  35. ClockSkew = TimeSpan.Zero,
  36. //是否要求Token的Claims中必须包含Expires
  37. RequireExpirationTime = true,
  38. };
  39. //https://github.com/HeartofTheForce/Heart.Auth/blob/22df97c854dc48ed9fbadf0bc185a6489aa25354/Heart.Auth.Api/Setup/Extensions/SetupAuth.cs
  40. //RSA public private
  41. services.AddAuthentication
  42. (x =>
  43. {
  44. x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
  45. x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
  46. x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
  47. })
  48. .AddJwtBearer(o =>
  49. {
  50. ///https://blog.csdn.net/sinat_14899485/article/details/88591848 jwt 黑名单
  51. //o.SecurityTokenValidators.Clear();
  52. o.SecurityTokenValidators.Add(new BlackListJwtSecurityTokenHandler()); /// 自定义黑名单拦截
  53. o.TokenValidationParameters = tokenValidationParameters;
  54. o.Events = new JwtBearerEvents
  55. {
  56. OnAuthenticationFailed = context =>
  57. {
  58. // 如果过期,则把<是否过期>添加到,返回头信息中
  59. if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
  60. {
  61. context.Response.Headers.Add("Token-Expired", "true");
  62. }
  63. return Task.CompletedTask;
  64. },
  65. //Url中添加access_token=[token],直接在浏览器中访问
  66. OnMessageReceived = context => {
  67. context.Token = context.Request.Query["access_token"];
  68. return Task.CompletedTask;
  69. },
  70. //URL未授权调用
  71. OnChallenge = context => {
  72. return Task.CompletedTask;
  73. },
  74. //在Token验证通过后调用
  75. OnTokenValidated = context => {
  76. //编写业务
  77. return Task.CompletedTask;
  78. },
  79. };
  80. });
  81. if (services == null) throw new ArgumentNullException(nameof(services));
  82. // 1【授权】、这个和上边的异曲同工,好处就是不用在controller中,写多个 roles 。
  83. // 然后这么写 [Authorize(Policy = "Admin")]
  84. services.AddAuthorization(options =>
  85. {
  86. options.AddPolicy("root", policy => policy.RequireRole("root").Build());
  87. options.AddPolicy("admin", policy => policy.RequireRole("admin").Build());
  88. options.AddPolicy("lecturer", policy => policy.RequireRole("lecturer").Build());
  89. options.AddPolicy("learner", policy => policy.RequireRole("learner").Build());
  90. options.AddPolicy("rootOrlearner", policy => policy.RequireRole("root","learner").Build());
  91. options.AddPolicy("all", policy => policy.RequireRole("root","admin" ,"learner").Build());
  92. });
  93. }
  94. }
  95. }