using TEAMModelOS.SDK.Extension.JwtAuth.Models; using IdentityModel; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.IdentityModel.Tokens; using System; using System.Threading.Tasks; using TEAMModelOS.SDK.Context.Configuration; using TEAMModelOS.SDK.Helper.Security.RSACrypt; using TEAMModelOS.SDK.Extension.JwtAuth.Filters; namespace TEAMModelOS.SDK.Extension.JwtAuth { public static class JwtAuthExtension { public static void JwtAuth(this IServiceCollection services , IConfigurationSection configuration) { services.Configure(configuration); // var creds = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["SecurityKey"]), SecurityAlgorithms.RsaSha256Signature); //var creds = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["SecurityKey"])); string path = BaseConfigModel.ContentRootPath; // RsaSecurityKey creds = new RsaSecurityKey(RsaHelper.LoadCertificateFile(path + "/private.pem")); SecurityKey creds = RsaHelper.GenerateValidationKey(path + "/public.pem"); //RsaSecurityKey creds = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["SecurityKey"])), SecurityAlgorithms.RsaSha256Signature); // 令牌验证参数 var tokenValidationParameters = new TokenValidationParameters { NameClaimType = JwtClaimTypes.Name, RoleClaimType = JwtClaimTypes.Role, ValidateIssuerSigningKey = true, IssuerSigningKey = creds, ValidateIssuer = true, ValidIssuer = configuration["Issuer"],//发行人 ValidateAudience = true, ValidAudience = configuration["Audience"],//订阅人 // 是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比 ValidateLifetime = true, //允许的服务器时间偏移量 ClockSkew = TimeSpan.Zero, //是否要求Token的Claims中必须包含Expires RequireExpirationTime = true, }; services.AddAuthentication(x => { x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(o => { ///https://blog.csdn.net/sinat_14899485/article/details/88591848 jwt 黑名单 //o.SecurityTokenValidators.Clear(); o.SecurityTokenValidators.Add(new BlackListJwtSecurityTokenHandler()); /// 自定义黑名单拦截 o.TokenValidationParameters = tokenValidationParameters; o.Events = new JwtBearerEvents { OnAuthenticationFailed = context => { // 如果过期,则把<是否过期>添加到,返回头信息中 if (context.Exception.GetType() == typeof(SecurityTokenExpiredException)) { context.Response.Headers.Add("Token-Expired", "true"); } return Task.CompletedTask; }, //Url中添加access_token=[token],直接在浏览器中访问 OnMessageReceived = context => { context.Token = context.Request.Query["access_token"]; return Task.CompletedTask; }, //URL未授权调用 OnChallenge = context => { return Task.CompletedTask; }, //在Token验证通过后调用 OnTokenValidated = context => { //编写业务 return Task.CompletedTask; }, }; }); if (services == null) throw new ArgumentNullException(nameof(services)); // 1【授权】、这个和上边的异曲同工,好处就是不用在controller中,写多个 roles 。 // 然后这么写 [Authorize(Policy = "Admin")] services.AddAuthorization(options => { //options.AddPolicy(Constant.Role_Root, policy => policy.RequireRole("root").Build()); //options.AddPolicy(Constant.Role_Admin, policy => policy.RequireRole("admin").Build()); //options.AddPolicy(Constant.Role_Lecturer, policy => policy.RequireRole("lecturer").Build()); //options.AddPolicy(Constant.Role_Learner, policy => policy.RequireRole("learner").Build()); //options.AddPolicy(Constant.Role_RootAdmin, policy => policy.RequireRole("root", "admin").Build()); //options.AddPolicy(Constant.Role_WebAll, policy => policy.RequireRole("root", "admin", "lecturer").Build()); //options.AddPolicy(Constant.Role_LecturerLearner, policy => policy.RequireRole("lecturer", "learner").Build()); }); } } }