Files
IM_NEW/IM.Jwt/WebApplicationJwtExtension.cs
T
2026-05-09 17:06:30 +08:00

83 lines
3.6 KiB
C#

using IM.Commons;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System.Text;
namespace IM.Jwt
{
public static class WebApplicationJwtExtension
{
public static IServiceCollection AddJwt(this IServiceCollection services, JwtOptions jwtOptions)
{
services.AddAuthentication(options =>
{
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = jwtOptions.Issuer,
ValidateAudience = true,
ValidAudience = jwtOptions.Audience,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero,
// 验证签名秘钥(防止 Token 被篡改)
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOptions.Key)),
};
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) && path.StartsWithSegments("/hub")) // 假设你的 SignalR 路径是 /hub
{
context.Token = accessToken;
}
return Task.CompletedTask;
},
OnAuthenticationFailed = context =>
{
// 在这里打断点,查看 context.Exception
// 常见的有:SecurityTokenExpiredException (过期)
// 或 SecurityTokenInvalidSignatureException (密钥不对)
Console.WriteLine("验证失败原因: " + context.Exception.Message);
return Task.CompletedTask;
},
OnChallenge = async context =>
{
context.HandleResponse();
context.Response.ContentType = "application/json";
context.Response.StatusCode = StatusCodes.Status200OK;
var result = Result<object>.Fail(ResultCode.AUTH_FAILED);
await context.Response.WriteAsJsonAsync(result);
},
OnForbidden = async context =>
{
context.Response.ContentType = "application/json";
context.Response.StatusCode = StatusCodes.Status200OK;
var result = Result<object>.Fail(ResultCode.PERMISSION_DENIED);
await context.Response.WriteAsJsonAsync(result);
}
};
});
return services;
}
}
}