using FlexJobApi.Core.Entities.Common; using Furion; using Furion.Authorization; using Furion.DatabaseAccessor; using Furion.DataEncryption; using Furion.DistributedIDGenerator; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Threading.Tasks; namespace FlexJobApi.Core; public class JwtHandler : AppAuthorizeHandler { public override async Task HandleAsync(AuthorizationHandlerContext context, DefaultHttpContext httpContext) { // 自动刷新 token if (JWTEncryption.AutoRefreshToken(context, context.GetCurrentHttpContext())) { await AuthorizeHandleAsync(context); } else { var resourceLog = new ResourceLog(); resourceLog.CreatedTime = DateTimeOffset.Now; var stopwatch = Stopwatch.StartNew(); var serviceScopeFactory = App.GetService(); var serviceScope = serviceScopeFactory.CreateScope(); var rep = serviceScope.ServiceProvider.GetRequiredService>(); resourceLog.Id = IDGen.NextID(); resourceLog.TraceId = App.GetTraceId(); resourceLog.Method = EnumUtils.GetEnum(httpContext.Request.Method); resourceLog.Domain = $"{httpContext.Request.Scheme}://{httpContext.Request.Host}"; resourceLog.Path = httpContext.Request.Path; resourceLog.ClientIpAddress = httpContext.GetRemoteIpAddressToIPv4(); if (httpContext.Request.ContentType?.Contains("application/json") == true) { httpContext.Request.EnableBuffering(); // 允许多次读取 var body = await new StreamReader(httpContext.Request.Body).ReadToEndAsync(); httpContext.Request.Body.Position = 0; // 重置流位置 resourceLog.Request = body; } else { resourceLog.Request = httpContext.Request.Query.ToJson(); } resourceLog.RequestHeaders = httpContext.Request.Headers.ToJson(); context.Fail(); resourceLog.UpdatedTime = DateTimeOffset.Now; resourceLog.Response = new FriendlyResult { TraceId = resourceLog.TraceId, Code = 401, Success = false, Timestamp = DateTime.Now.ToTimeStamp() }.ToJson(); resourceLog.ResponseHeaders = httpContext.Response.Headers.ToJson(); resourceLog.IsSuccess = false; stopwatch.Stop(); resourceLog.ElapsedMilliseconds = stopwatch.ElapsedMilliseconds; await rep.InsertNowAsync(resourceLog); } } /// /// 验证管道,也就是验证核心代码 /// /// /// /// public override Task PipelineAsync(AuthorizationHandlerContext context, DefaultHttpContext httpContext) { // 检查权限,如果方法是异步的就不用 Task.FromResult 包裹,直接使用 async/await 即可 return Task.FromResult(true); } }