using LearningOfficer.OA.Common.Configs; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using System.Text; namespace LearningOfficer.OA.Mobile.Api.CollectionExtensions { public static class JWTAuthServiceCollectionExtensions { /// /// Jwt认证服务 /// /// /// /// public static IServiceCollection AddJwtAuth(this IServiceCollection services, IConfiguration configuration) { //将配置文件中的相关内容反序列化 var jwtOption = configuration.GetSection("Jwt").Get(); services.AddAuthentication(options => { options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(options => { options.Events = new JwtBearerEvents { //验证失败时的处理 OnAuthenticationFailed = context => { //若失败类型为过期,则返回特定Header,便于客户端判断 if (context.Exception.GetType() == typeof(SecurityTokenExpiredException)) context.Response.Headers.Add("tokenErr", "expired"); return Task.CompletedTask; }, // 配置 SignalR 使用 JWT OnMessageReceived = context => { var accessToken = context.Request.Query["access_token"]; var path = context.HttpContext.Request.Path; if (!string.IsNullOrEmpty(accessToken) && path.StartsWithSegments("/signalr")) { context.Token = accessToken; } return Task.CompletedTask; } }; options.RequireHttpsMetadata = false; options.SaveToken = true; options.TokenValidationParameters = new TokenValidationParameters() { ValidateIssuer = true, //是否验证Issuer ValidIssuer = jwtOption.Issuer, //发行人Issuer ValidateAudience = true, //是否验证Audience ValidAudience = jwtOption.Audience, //订阅人Audience ValidateIssuerSigningKey = true, //是否验证SecurityKey IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOption.AccessSecret)), //SecurityKey ValidateLifetime = true, //是否验证失效时间 ClockSkew = TimeSpan.FromSeconds(jwtOption.ClockSkew), //过期时间容错值,解决服务器端时间不同步问题(秒) RequireExpirationTime = true, }; }); services.AddAuthorization(); return services; } } }