using System.Net.Http.Headers; using System.Security.Cryptography; using System.Text; using Dlhis.Basic.Organization.Request; using Dlhis.Basic.Organization.Response; using Dlhis.Basic.Organization.Services; using HttpUtil; using Kurisu.AspNetCore.Utils.Extensions; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Dlhis.Basic.Organization.Controllers; /// /// 档案人脸 /// [Authorize] [Route("api/[controller]")] [ApiController] public class GainfoFacesController : ControllerBase { private readonly IGainfoFaceService _gainfoFaceService; private readonly IHttpClientFactory _httpClientFactory; public GainfoFacesController(IGainfoFaceService gainfoFaceService, IHttpClientFactory httpClientFactory) { _gainfoFaceService = gainfoFaceService; _httpClientFactory = httpClientFactory; } /// /// 人脸档案分页 /// /// /// [HttpGet("page")] public async Task GetPageAsync([FromQuery] GainfoFacePageRequest request) { return await _gainfoFaceService.GetPageAsync(request); } [AllowAnonymous] [HttpPost("test")] public async Task TestAsync(GainfoFaceValidateRequest request) { var client = _httpClientFactory.CreateClient("hik-openapi"); var body = request.ToJson(); var url = "/artemis/api/frs/v1/application/oneToOne"; var key = "27390082"; var secret = "MLl7Dv7p5Pgc9XYI3r4O"; var headers = InitRequest(url, body, key, secret); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(headers["Accept"])); var content = new StringContent(body, Encoding.UTF8, headers["Content-Type"]); foreach (var item in headers.Where(x => x.Key != "Accept").Where(x => x.Key != "Content-Type")) { content.Headers.Add(item.Key, item.Value); } var r = await client.PostAsync(url, content); return await r.Content.ReadAsStringAsync(); } private static Dictionary InitRequest(string url, string body, string key, string secret) { var header = new Dictionary(); // Accept header.Add("Accept", "application/json"); // ContentType header.Add("Content-Type", "application/json"); //if POST content-md5,be careful it must be lower case. string contentMd5 = computeContentMd5(body); header.Add("content-md5", contentMd5); // x-ca-timestamp string timestamp = ((DateTime.Now.Ticks - TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0)).Ticks) / 1000).ToString(); header.Add("x-ca-timestamp", timestamp); // x-ca-nonce string nonce = System.Guid.NewGuid().ToString(); header.Add("x-ca-nonce", nonce); // x-ca-key header.Add("x-ca-key", key); // build string to sign string strToSign = buildSignString("POST", url, header); string signedStr = computeForHMACSHA256(strToSign, secret); // x-ca-signature header.Add("x-ca-signature", signedStr); return header; } /// /// 计算content-md5 /// /// /// base64后的content-md5 private static string computeContentMd5(string body) { MD5 md5 = new MD5CryptoServiceProvider(); byte[] result = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(body)); return Convert.ToBase64String(result); } /// /// 计算HMACSHA265 /// /// 待计算字符串 /// 平台APPSecet /// HMAXH265计算结果字符串 private static string computeForHMACSHA256(string str, string secret) { var encoder = new System.Text.UTF8Encoding(); byte[] secretBytes = encoder.GetBytes(secret); byte[] strBytes = encoder.GetBytes(str); var opertor = new HMACSHA256(secretBytes); byte[] hashbytes = opertor.ComputeHash(strBytes); return Convert.ToBase64String(hashbytes); } /// /// 计算签名字符串 /// /// HTTP请求方法,如“POST” /// 接口Url,如/artemis/api/resource/v1/org/advance/orgList /// 请求头 /// 签名字符串 private static string buildSignString(string method, string url, Dictionary header) { StringBuilder sb = new StringBuilder(); sb.Append(method.ToUpper()).Append("\n"); if (null != header) { if (null != header["Accept"]) { sb.Append((string)header["Accept"]); sb.Append("\n"); } if (header.Keys.Contains("Content-MD5") && null != header["Content-MD5"]) { sb.Append((string)header["Content-MD5"]); sb.Append("\n"); } if (null != header["Content-Type"]) { sb.Append((string)header["Content-Type"]); sb.Append("\n"); } if (header.Keys.Contains("Date") && null != header["Date"]) { sb.Append((string)header["Date"]); sb.Append("\n"); } } // build and add header to sign string signHeader = buildSignHeader(header); sb.Append(signHeader); sb.Append(url); return sb.ToString(); } /// /// 计算签名头 /// /// 请求头 /// 签名头 private static string buildSignHeader(Dictionary header) { Dictionary sortedDicHeader = new Dictionary(); sortedDicHeader = header; var dic = from objDic in sortedDicHeader orderby objDic.Key ascending select objDic; StringBuilder sbSignHeader = new StringBuilder(); StringBuilder sb = new StringBuilder(); foreach (KeyValuePair kvp in dic) { if (kvp.Key.Replace(" ", "").Contains("x-ca-")) { sb.Append(kvp.Key + ":"); if (!string.IsNullOrWhiteSpace(kvp.Value)) { sb.Append(kvp.Value); } sb.Append("\n"); if (sbSignHeader.Length > 0) { sbSignHeader.Append(","); } sbSignHeader.Append(kvp.Key); } } header.Add("x-ca-signature-headers", sbSignHeader.ToString()); return sb.ToString(); } }