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