using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using System.Text; using YuanXuan.IM.Common.Configs; namespace YuanXuan.IM.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; } } }