| New file |
| | |
| | | using System; |
| | | using System.Linq; |
| | | using System.Net.Http; |
| | | using System.Security.Cryptography; |
| | | using System.Text; |
| | | using System.Web.Http; |
| | | using System.Web.Http.Controllers; |
| | | using System.Web.Http.Filters; |
| | | using WebAPI.Service; |
| | | |
| | | namespace project.Filter |
| | | { |
| | | public class SignatureVerifyAttribute : AuthorizationFilterAttribute |
| | | { |
| | | private const string SecretKey = "MES_2026_SecretKey_XYZ!@#"; |
| | | |
| | | public override async System.Threading.Tasks.Task OnAuthorizationAsync( |
| | | HttpActionContext actionContext, |
| | | System.Threading.CancellationToken cancellationToken) |
| | | { |
| | | var hasAttr = actionContext.ActionDescriptor.GetCustomAttributes<RequireSignatureAttribute>(true).Any() |
| | | || actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<RequireSignatureAttribute>(true).Any(); |
| | | |
| | | if (!hasAttr) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | var headers = actionContext.Request.Headers; |
| | | string timestamp = null, nonce = null, clientSign = null; |
| | | |
| | | if (headers.Contains("X-Timestamp")) |
| | | timestamp = headers.GetValues("X-Timestamp").FirstOrDefault(); |
| | | if (headers.Contains("X-Nonce")) |
| | | nonce = headers.GetValues("X-Nonce").FirstOrDefault(); |
| | | if (headers.Contains("X-Sign")) |
| | | clientSign = headers.GetValues("X-Sign").FirstOrDefault(); |
| | | |
| | | if (string.IsNullOrEmpty(timestamp) || string.IsNullOrEmpty(nonce) || string.IsNullOrEmpty(clientSign)) |
| | | { |
| | | actionContext.Response = actionContext.Request.CreateResponse(System.Net.HttpStatusCode.BadRequest, |
| | | new { success = false, msg = "缺å°ç¾ååæ°ï¼X-Timestamp/X-Nonce/X-Signï¼" }); |
| | | return; |
| | | } |
| | | |
| | | |
| | | double ts; |
| | | if (!double.TryParse(timestamp, out ts)) |
| | | { |
| | | actionContext.Response = actionContext.Request.CreateResponse(System.Net.HttpStatusCode.BadRequest, |
| | | new { success = false, msg = "æ¶é´æ³æ ¼å¼é误" }); |
| | | return; |
| | | } |
| | | var currentTs = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds; |
| | | var diff = Math.Abs(currentTs - ts); |
| | | |
| | | if (diff > 300) // 300ç§ = 5åé |
| | | { |
| | | actionContext.Response = actionContext.Request.CreateResponse(System.Net.HttpStatusCode.BadRequest, |
| | | new { success = false, msg = "请æ±å·²è¿æ" }); |
| | | return; |
| | | } |
| | | |
| | | string rawData = ""; |
| | | |
| | | if (actionContext.Request.Method == HttpMethod.Get) |
| | | { |
| | | var query = actionContext.Request.RequestUri.Query; |
| | | if (!string.IsNullOrEmpty(query) && query.StartsWith("?")) |
| | | { |
| | | rawData = query.Substring(1); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | var bodyBytes = await actionContext.Request.Content.ReadAsByteArrayAsync(); |
| | | rawData = Encoding.UTF8.GetString(bodyBytes); |
| | | |
| | | actionContext.Request.Content = new ByteArrayContent(bodyBytes); |
| | | if (actionContext.Request.Content.Headers.ContentType != null) |
| | | { |
| | | actionContext.Request.Content.Headers.ContentType = |
| | | new System.Net.Http.Headers.MediaTypeHeaderValue( |
| | | actionContext.Request.Content.Headers.ContentType.MediaType); |
| | | } |
| | | } |
| | | var signStr = rawData + "×tamp=" + timestamp + "&nonce=" + nonce + "&key=" + SecretKey; |
| | | |
| | | var serverSign = ComputeHmacSha256(signStr, SecretKey); |
| | | |
| | | |
| | | if (serverSign != clientSign.ToUpper()) |
| | | { |
| | | actionContext.Response = actionContext.Request.CreateResponse(System.Net.HttpStatusCode.Unauthorized, |
| | | new { success = false, msg = "ç¾åéªè¯å¤±è´¥" }); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | private string ComputeHmacSha256(string data, string key) |
| | | { |
| | | var keyBytes = Encoding.UTF8.GetBytes(key); |
| | | var dataBytes = Encoding.UTF8.GetBytes(data); |
| | | |
| | | using (var hmac = new HMACSHA256(keyBytes)) |
| | | { |
| | | var hashBytes = hmac.ComputeHash(dataBytes); |
| | | return BitConverter.ToString(hashBytes).Replace("-", "").ToUpper(); |
| | | } |
| | | } |
| | | } |
| | | } |