using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using QRCodeService.Application.Queries; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Text.Json; using System.Text.Json.Serialization; using QRCodeService.Extensions; namespace QRCodeService.Infrastructure.Middlewares { /// /// 报文签名验证中间件 /// public class CheckSignMiddleware { readonly RequestDelegate next; public CheckSignMiddleware(RequestDelegate next) { this.next = next; } public async Task Invoke(HttpContext context, IAppQueries appQueries) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var endpoint = context.GetEndpoint(); if (endpoint != null) { var attribute = endpoint.Metadata.GetMetadata(); if (attribute != null) { context.Request.EnableBuffering(); var requestReader = new StreamReader(context.Request.Body); var requestContent = await requestReader.ReadToEndAsync(); var param = JsonSerializer.Deserialize>(requestContent); var appid = param.Where(kv=>kv.Key.ToLower()=="appid").Single().Value.GetInt32(); var time = param.Where(kv=>kv.Key.ToLower()=="time").Single().Value.GetString(); var sign = param.Where(kv=>kv.Key.ToLower()== "sign").Single().Value.GetString(); var timeDate = time.ToDate("yyyyMMddHHmmss"); if (timeDate == null||Math.Abs((timeDate.Value - DateTime.Now).TotalSeconds) > 60)//时间不同步 { context.Response.StatusCode = StatusCodes.Status400BadRequest; await context.Response.BodyWriter.WriteAsync(Encoding.UTF8.GetBytes("check sign failed")); return; } var app = await appQueries.GetAppAsync(appid); if (app == null) { context.Response.StatusCode = StatusCodes.Status400BadRequest; await context.Response.BodyWriter.WriteAsync(Encoding.UTF8.GetBytes("check sign failed")); return; } var appKey = app.Appkey; var signStr = string.Join(null, param.Where(kv =>kv.Key.ToLower() != "sign").OrderBy(kv => kv.Key).Select(kv => kv.Value.ToString())); var checkSign = BitConverter.ToString( (signStr + appKey).ToMD5()).Replace("-",""); if(checkSign.ToLower() != sign.ToLower()) { context.Response.StatusCode = StatusCodes.Status400BadRequest; await context.Response.BodyWriter.WriteAsync(Encoding.UTF8.GetBytes("check sign failed")); return; } context.Request.Body.Position = 0; } } await next(context); } } }