From 54d812d9a307f3db88a51a17573b80f54c85c6cd Mon Sep 17 00:00:00 2001 From: kazelee <1847801760@qq.com> Date: 星期五, 20 六月 2025 17:25:21 +0800 Subject: [PATCH] 针对NDCAGV的Request请求授权,添加报文检验功能备用 --- api/AgvController.cs | 148 +++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 143 insertions(+), 5 deletions(-) diff --git a/api/AgvController.cs b/api/AgvController.cs index f2b6e1d..2de0b6f 100644 --- a/api/AgvController.cs +++ b/api/AgvController.cs @@ -1,11 +1,18 @@ -锘縰sing System.Web.Http; +锘縰sing System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Security.Cryptography; +using System.Text; +using System.Web.Http; using HH.WCS.Mobox3.DSZSH.core; using Newtonsoft.Json; using static HH.WCS.Mobox3.DSZSH.api.ApiModel; - +using static HH.WCS.Mobox3.DSZSH.dispatch.NDC; namespace HH.WCS.Mobox3.DSZSH.api { /// <summary> @@ -21,9 +28,7 @@ /// <returns></returns> [HttpPost] [Route("AGVCallbackState")] - - public ReturnResult AGVCallbackState(AgvTaskState model) - { + public ReturnResult AGVCallbackState(AgvTaskState model){ LogHelper.Info("NDC HostToAGV 浠诲姟鐘舵�鍥炴姤锛� + JsonConvert.SerializeObject(model), "HosttoagvTask"); return WCSCore.OperateAgvTaskStatus(model); } @@ -36,7 +41,140 @@ [HttpPost] [Route("SafetyInteraction")] public ReturnResult SafetyInteraction(SafetyInteractionInfo model) { + LogHelper.Info("AGV涓庝骇绾胯繘琛屽畨鍏ㄤ氦浜掞細" + JsonConvert.SerializeObject(model), "HosttoagvTask"); return WCSCore.SafetyInteraction(model); } + + + + // 澶囩敤锛歊equest 璇锋眰鎺堟潈 --------------------------------------------- + + // 妯℃嫙瀛樺偍鐨凙ppKey鍜孉ppSecret锛堝疄闄呭簲瀛樺偍鍦ㄦ暟鎹簱鎴栭厤缃腑锛�+ private static readonly Dictionary<string, string> AppSecrets = new Dictionary<string, string> { + { "testAppKey", "7a8f9b3d2e1c6a5b4c8d7e6f" } + }; + + // 鍏佽鐨勬椂闂村樊锛堢锛夛紝鐢ㄤ簬楠岃瘉鏃堕棿鎴�+ private const int AllowedTimeDiff = 300; // 5鍒嗛挓 + + private CheckHeadersResult CheckHeaders(System.Net.Http.Headers.HttpRequestHeaders headers) { + // 蹇呴』瀛楁楠岃瘉 + if (!headers.Contains("AppKey") || !headers.Contains("ReqVerify") || !headers.Contains("ReqTime")) { + return CreateCheckHeadersResult(false, HttpStatusCode.BadRequest, "缂哄皯蹇呰璇锋眰澶村弬鏁�); + } + + var headerModel = new SecureRequest { + AppKey = headers.GetValues("AppKey").First(), + ReqVerify = headers.GetValues("ReqVerify").First(), + ReqTime = long.Parse(headers.GetValues("ReqTime").First()), + }; + + // 楠岃瘉Header + var validationResult = ValidateHeaders(headerModel); + if (validationResult != null) { + return validationResult; + } + + return CreateCheckHeadersResult(true); + } + + private CheckHeadersResult ValidateHeaders(SecureRequest request) { + // 瀹炵幇鎵�湁Header楠岃瘉閫昏緫 + + // 楠岃瘉AppKey鏄惁瀛樺湪 + if (!AppSecrets.TryGetValue(request.AppKey, out var appSecret)) { + return CreateCheckHeadersResult(false, HttpStatusCode.Unauthorized, "鏃犳晥鐨凙ppKey"); + } + + // 楠岃瘉鏃堕棿鎴虫槸鍚﹀湪鍏佽鑼冨洿鍐�+ var currentTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); + if (Math.Abs(currentTime - request.ReqTime) > AllowedTimeDiff) { + return CreateCheckHeadersResult(false, HttpStatusCode.Unauthorized, "璇锋眰宸茶繃鏈�); + } + + // 璁$畻楠岃瘉涓�+ var expectedVerify = CalculateRequestVerify(request.AppKey, appSecret, request.ReqTime); + + // 楠岃瘉璇锋眰绛惧悕 + if (!string.Equals(expectedVerify, request.ReqVerify, StringComparison.OrdinalIgnoreCase)) { + return CreateCheckHeadersResult(false, HttpStatusCode.Unauthorized, "楠岃瘉澶辫触"); + } + + return null; + } + + /// <summary> + /// 鏋勯�涓�釜鎴愬姛缁撴灉鐨凴esponseMessage + /// </summary> + /// <example><code><![CDATA[ + /// var res = ApiHelper.OperateAgvTaskStatus(model); + /// return CreateSuccessResponse(res); + /// ]]></code></example> + /// <param name="code"></param> + /// <param name="data"></param> + /// <returns></returns> + private IHttpActionResult CreateSuccessResponse(HttpStatusCode code, object data) { + return ResponseMessage(new HttpResponseMessage(code) { + Headers = { }, + Content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json") + }); + } + + /// <summary> + /// 鏋勯�涓�釜澶辫触缁撴灉鐨凴esponseMessage + /// </summary> + /// <example><code><![CDATA[ + /// var headers = Request.Headers; + /// var checkRes = CheckHeaders(headers); + /// if (!checkRes.isSuccess) { + /// return CreateErrorResponse(checkRes.code, checkRes.message); + /// } + /// ]]></code></example> + /// <param name="code"></param> + /// <param name="message"></param> + /// <returns></returns> + private IHttpActionResult CreateErrorResponse(HttpStatusCode code, string message) { + return ResponseMessage(new HttpResponseMessage(code) { + Headers = { }, + Content = new StringContent(message) + }); + } + + private CheckHeadersResult CreateCheckHeadersResult(bool isSuccess, HttpStatusCode code = HttpStatusCode.OK, string message = "") { + return new CheckHeadersResult { + code = code, + message = message, + isSuccess = isSuccess + }; + } + + // 璁$畻璇锋眰楠岃瘉涓�+ private string CalculateRequestVerify(string appKey, string appSecret, long reqTime) { + using (var md5 = MD5.Create()) { + var input = $"{appKey}{appSecret}{reqTime}"; + var inputBytes = Encoding.UTF8.GetBytes(input); + var hashBytes = md5.ComputeHash(inputBytes); + + // 灏嗗瓧鑺傛暟缁勮浆鎹负鍗佸叚杩涘埗瀛楃涓�+ var sb = new StringBuilder(); + foreach (var b in hashBytes) { + sb.Append(b.ToString("x2")); + } + return sb.ToString(); + } + } + } + + // 璇锋眰妯″瀷 + public class SecureRequest { + public string AppKey { get; set; } + public long ReqTime { get; set; } + public string ReqVerify { get; set; } + } + + public class CheckHeadersResult { + public bool isSuccess { get; set; } + public HttpStatusCode code { get; set; } + public string message { get; set; } } } -- Gitblit v1.9.1