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;
}
}
}