New file |
| | |
| | | using Microsoft.AspNetCore.Mvc; |
| | | using Microsoft.AspNetCore.Mvc.Filters; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using Utility.Tools; |
| | | using static System.Net.Mime.MediaTypeNames; |
| | | |
| | | namespace Utility |
| | | { |
| | | /// <summary> |
| | | /// 验签 |
| | | /// </summary> |
| | | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] |
| | | public class VerificationAttribute : ActionFilterAttribute |
| | | { |
| | | private static readonly string appKey = "signature";//后面改成拿配置文件的 |
| | | private static readonly double Minutes = 5;//时间戳必须5分钟内的,否则不通过 |
| | | public VerificationAttribute() |
| | | { |
| | | |
| | | } |
| | | |
| | | public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) |
| | | { |
| | | var request = context.HttpContext.Request; |
| | | |
| | | // 获取请求中的时间戳和签名 |
| | | var timestamp = request.Headers["Timestamp"].FirstOrDefault(); |
| | | var signature = request.Headers["Signature"].FirstOrDefault(); |
| | | |
| | | if (string.IsNullOrEmpty(timestamp) || string.IsNullOrEmpty(signature)) |
| | | { |
| | | context.Result = new UnauthorizedResult(); |
| | | return; |
| | | } |
| | | |
| | | // 验证时间戳是否在允许的时间范围内 |
| | | if (!IsTimestampValid(timestamp)) |
| | | { |
| | | context.Result = new UnauthorizedResult(); |
| | | return; |
| | | } |
| | | |
| | | // 读取请求体中的 JSON 参数 |
| | | string jsonParams; |
| | | using (var reader = new System.IO.StreamReader(request.Body, Encoding.UTF8, true, 1024, true)) |
| | | { |
| | | char[] buffer = new char[500]; |
| | | int bytesRead = await reader.ReadAsync(buffer, 0, buffer.Length); |
| | | jsonParams = new string(buffer, 0, bytesRead); |
| | | } |
| | | |
| | | // 构建待签名字符串 |
| | | var signatureBaseString = appKey + jsonParams + timestamp; |
| | | |
| | | // 计算 MD5 值 |
| | | var computedSignature = Md5Tools.CalcMd5(Encoding.UTF8.GetBytes(signatureBaseString)); |
| | | |
| | | // 验证签名 |
| | | if (computedSignature != signature) |
| | | { |
| | | context.Result = new UnauthorizedResult(); |
| | | return; |
| | | } |
| | | |
| | | await base.OnActionExecutionAsync(context, next); |
| | | } |
| | | |
| | | private bool IsTimestampValid(string timestamp) |
| | | { |
| | | if (long.TryParse(timestamp, out var timestampSeconds)) |
| | | { |
| | | var requestDateTime = DateTimeOffset.FromUnixTimeSeconds(timestampSeconds); |
| | | var currentDateTime = DateTimeOffset.UtcNow; |
| | | |
| | | // 计算时间差 |
| | | var timeDifference = currentDateTime - requestDateTime; |
| | | |
| | | // 比较时间差是否在允许的范围内 |
| | | return timeDifference.TotalMinutes <= 5; |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | } |
| | | } |