JwtAuthExtension.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. using TEAMModelOS.SDK.Extension.JwtAuth.Models;
  2. using IdentityModel;
  3. using Microsoft.AspNetCore.Authentication.JwtBearer;
  4. using Microsoft.AspNetCore.Authorization;
  5. using Microsoft.Extensions.Configuration;
  6. using Microsoft.Extensions.DependencyInjection;
  7. using Microsoft.IdentityModel.Tokens;
  8. using System;
  9. using System.Threading.Tasks;
  10. using TEAMModelOS.SDK.Context.Configuration;
  11. using TEAMModelOS.SDK.Helper.Security.RSACrypt;
  12. using TEAMModelOS.SDK.Extension.JwtAuth.Requirements;
  13. namespace TEAMModelOS.SDK.Extension.JwtAuth
  14. {
  15. public static class JwtAuthExtension
  16. {
  17. public static void JwtAuth(this IServiceCollection services , IConfigurationSection configuration)
  18. {
  19. services.Configure<JwtSetting>(configuration);
  20. // var creds = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["SecurityKey"]), SecurityAlgorithms.RsaSha256Signature);
  21. //var creds = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["SecurityKey"]));
  22. string path = BaseConfigModel.ContentRootPath;
  23. RsaSecurityKey creds = new RsaSecurityKey(RsaHelper.LoadCertificateFile(path + "/JwtRsaFile/private.pem"));
  24. //RsaSecurityKey creds = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["SecurityKey"])), SecurityAlgorithms.RsaSha256Signature);
  25. // 令牌验证参数
  26. var tokenValidationParameters = new TokenValidationParameters
  27. {
  28. NameClaimType = JwtClaimTypes.Name,
  29. RoleClaimType = JwtClaimTypes.Role,
  30. ValidateIssuerSigningKey = true,
  31. IssuerSigningKey = creds,
  32. ValidateIssuer = true,
  33. ValidIssuer = configuration["Issuer"],//发行人
  34. ValidateAudience = true,
  35. ValidAudience = configuration["Audience"],//订阅人
  36. // 是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比
  37. ValidateLifetime = true,
  38. //允许的服务器时间偏移量
  39. ClockSkew = TimeSpan.Zero,
  40. //是否要求Token的Claims中必须包含Expires
  41. RequireExpirationTime = true,
  42. };
  43. services.AddAuthentication(x => {
  44. x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
  45. x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
  46. }).AddJwtBearer(o =>
  47. {
  48. o.TokenValidationParameters = tokenValidationParameters;
  49. o.Events = new JwtBearerEvents
  50. {
  51. OnAuthenticationFailed = context =>
  52. {
  53. // 如果过期,则把<是否过期>添加到,返回头信息中
  54. if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
  55. {
  56. context.Response.Headers.Add("Token-Expired", "true");
  57. }
  58. return Task.CompletedTask;
  59. },
  60. //Url中添加access_token=[token],直接在浏览器中访问
  61. OnMessageReceived = context => {
  62. context.Token = context.Request.Query["access_token"];
  63. return Task.CompletedTask;
  64. },
  65. //URL未授权调用
  66. OnChallenge = context => {
  67. return Task.CompletedTask;
  68. },
  69. //在Token验证通过后调用
  70. OnTokenValidated = context => {
  71. //编写业务
  72. return Task.CompletedTask;
  73. },
  74. };
  75. });
  76. //自定义授权
  77. services.AddAuthorization(auth =>
  78. {
  79. auth.AddPolicy("Admin", policy => policy.RequireRole("Admin,Root,SchoolAdmin,Teacher").Build());
  80. auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
  81. .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
  82. .RequireAuthenticatedUser()
  83. .AddRequirements(new ValidJtiRequirement()) // 添加上面的验证要求
  84. .Build());
  85. });
  86. // 注册验证要求的处理器,可通过这种方式对同一种要求添加多种验证
  87. services.AddSingleton<IAuthorizationHandler, ValidJtiHandler>();
  88. }
  89. }
  90. }