using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Net.Http; using System.Security.Cryptography; using Newtonsoft.Json; using System.Text; using System.Net; using Microsoft.AspNetCore.DataProtection; using Microsoft.Extensions.Hosting; namespace NewPdaSqlServer.Controllers { [Route("api/[controller]")] [ApiController] public class AuthController : ControllerBase { // 以下常量建议放在appsettings.json配置文件中 private const string APPID = "303233EF-AC39-40C1-8364-AC989C6258A5"; private const string SECRET = "30b41949-bcfb-48f8-9847-feb6e043fe72"; // private const string SPK = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApobID/gwmD9OofMG1gEcE94NCMeTYUq1cam/7ADZmxHCVpF143GaHWhqDdY0TTVbcUElsQ71DzAG2j3itWlIJBK5fVGwCo3sPpAvUDdKMh+Uivcp7yxdy/IDRA/PS4JARuEyM4cVJLhIOU2KnSlbIkheeoDkDgfaxu9kKrWnozJLiYraVTVDz9PdRX7fQdP+Zu/xB9txAGw4kvOm9HwgrzaSRdZEhisTJ5yyoNW/dLXtWKXA0cKhKOOIFu12TOrv/It6hl1ShTUuy79Pa51M9Oc2dEfVs1tluNXPWo1uFXQbBaJxdqZEJJlK7iW2uQFIao2O4XFHYThwy2+6116LtwIDAQAB"; private const string HOST = "http://192.168.1.149:8099"; private const string SPK = @"-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApobID/gwmD9OofMG1gEc E94NCMeTYUq1cam/7ADZmxHCVpF143GaHWhqDdY0TTVbcUElsQ71DzAG2j3itWlI JBK5fVGwCo3sPpAvUDdKMh+Uivcp7yxdy/IDRA/PS4JARuEyM4cVJLhIOU2KnSlb IkheeoDkDgfaxu9kKrWnozJLiYraVTVDz9PdRX7fQdP+Zu/xB9txAGw4kvOm9Hwg rzaSRdZEhisTJ5yyoNW/dLXtWKXA0cKhKOOIFu12TOrv/It6hl1ShTUuy79Pa51M 9Oc2dEfVs1tluNXPWo1uFXQbBaJxdqZEJJlK7iW2uQFIao2O4XFHYThwy2+6116L twIDAQAB -----END PUBLIC KEY-----"; [HttpGet("token")] public ActionResult GetToken() { var http = new HttpManager(); var headers = new Dictionary { ["appid"] = APPID, ["secret"] = RsaHelper.Encrypt(SECRET, SPK) }; try { var response = http.PostDataSSL($"{HOST}/api/ec/dev/auth/applytoken", new Dictionary(), headers); if (!string.IsNullOrEmpty(response)) { var res = JsonConvert.DeserializeObject(response); if (res.status == "true") { return res.token.ToString(); } } return BadRequest("Failed to get token"); } catch (Exception ex) { // 建议使用ILogger记录日志 return StatusCode(500, ex.Message); } } [HttpPost("getUserId")] public ActionResult GetUserId() { var http = new HttpManager(); var tokenResult = http.GetToken(); if (tokenResult is not null) { Uri url = new Uri($"{HOST}/api/T100/GetSecretUserId"); return http.GetOaKqInfo(url, tokenResult, "DQ000344"); } return BadRequest("无法获取有效Token"); } [HttpPost("createWorkflow")] public ActionResult CreateWorkflowRequest([FromBody] WorkflowRequestDto request) { try { // 加密用户ID var encryptedUserId = RsaHelper.Encrypt(request.UserId, SPK); var token = GetToken().ToString(); // 设置请求头 var headers = new Dictionary { ["token"] = token, ["appid"] = APPID, ["userid"] = encryptedUserId }; // 构建请求参数 var parameters = new Dictionary { ["mainData"] = JsonConvert.SerializeObject(request.MainData), ["workflowId"] = "", ["requestName"] = request.RequestName }; // 添加可选参数 if (request.DetailData != null) parameters.Add("detailData", JsonConvert.SerializeObject(request.DetailData)); if (request.OtherParams != null) parameters.Add("otherParams", JsonConvert.SerializeObject(request.OtherParams)); // 发送请求 var response = new HttpManager().PostDataSSL( $"{HOST}/api/workflow/paService/doCreateRequest", parameters, headers); dynamic res = JsonConvert.DeserializeObject(response); if (res.code == "SUCCESS") return Ok(res.data.requestid.ToString()); return BadRequest($"创建失败:{res.errMsg}"); } catch (Exception ex) { return StatusCode(500, $"系统异常:{ex.Message}"); } } } public static class RsaHelper { public static string Encrypt(string plainText, string publicKeyPem) { // 将PEM格式的公钥转换为XML格式 var rsa = RSA.Create(); rsa.ImportFromPem(publicKeyPem); // 使用.NET 5+ 内置PEM解析方法 var parameters = rsa.ExportParameters(false); string publicKeyXml = $"{Convert.ToBase64String(parameters.Modulus)}{Convert.ToBase64String(parameters.Exponent)}"; using var rsaProvider = new RSACryptoServiceProvider(); rsaProvider.FromXmlString(publicKeyXml); // 使用转换后的XML格式公钥 var data = Encoding.UTF8.GetBytes(plainText); var encrypted = rsaProvider.Encrypt(data, false); return Convert.ToBase64String(encrypted); } } public class HttpManager { private readonly HttpClient _client = new HttpClient(); // 以下常量建议放在appsettings.json配置文件中 private const string APPID = "303233EF-AC39-40C1-8364-AC989C6258A5"; private const string SECRET = "30b41949-bcfb-48f8-9847-feb6e043fe72"; // private const string SPK = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApobID/gwmD9OofMG1gEcE94NCMeTYUq1cam/7ADZmxHCVpF143GaHWhqDdY0TTVbcUElsQ71DzAG2j3itWlIJBK5fVGwCo3sPpAvUDdKMh+Uivcp7yxdy/IDRA/PS4JARuEyM4cVJLhIOU2KnSlbIkheeoDkDgfaxu9kKrWnozJLiYraVTVDz9PdRX7fQdP+Zu/xB9txAGw4kvOm9HwgrzaSRdZEhisTJ5yyoNW/dLXtWKXA0cKhKOOIFu12TOrv/It6hl1ShTUuy79Pa51M9Oc2dEfVs1tluNXPWo1uFXQbBaJxdqZEJJlK7iW2uQFIao2O4XFHYThwy2+6116LtwIDAQAB"; private const string HOST = "http://192.168.1.149:8099"; private const string SPK = @"-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApobID/gwmD9OofMG1gEc E94NCMeTYUq1cam/7ADZmxHCVpF143GaHWhqDdY0TTVbcUElsQ71DzAG2j3itWlI JBK5fVGwCo3sPpAvUDdKMh+Uivcp7yxdy/IDRA/PS4JARuEyM4cVJLhIOU2KnSlb IkheeoDkDgfaxu9kKrWnozJLiYraVTVDz9PdRX7fQdP+Zu/xB9txAGw4kvOm9Hwg rzaSRdZEhisTJ5yyoNW/dLXtWKXA0cKhKOOIFu12TOrv/It6hl1ShTUuy79Pa51M 9Oc2dEfVs1tluNXPWo1uFXQbBaJxdqZEJJlK7iW2uQFIao2O4XFHYThwy2+6116L twIDAQAB -----END PUBLIC KEY-----"; public string PostDataSSL(string url, Dictionary parameters, Dictionary headers) { var request = new HttpRequestMessage(HttpMethod.Post, url); foreach (var header in headers) { request.Headers.Add(header.Key, header.Value); } // 如果需要表单参数 if (parameters.Count > 0) { request.Content = new FormUrlEncodedContent(parameters); } var response = _client.SendAsync(request).Result; return response.Content.ReadAsStringAsync().Result; } public string GetToken() { var http = new HttpManager(); var headers = new Dictionary { ["appid"] = APPID, ["secret"] = RsaHelper.Encrypt(SECRET, SPK) }; try { var response = http.PostDataSSL($"{HOST}/api/ec/dev/auth/applytoken", new Dictionary(), headers); if (!string.IsNullOrEmpty(response)) { var res = JsonConvert.DeserializeObject(response); if (res.status == "true") { return res.token.ToString(); } } return "token不存在!"; } catch (Exception ex) { // 建议使用ILogger记录日志 return ex.Message; } } public string GetOaKqInfo(Uri url, string token, string userId) { try { ServicePointManager.ServerCertificateValidationCallback += (s, cert, chain, sslPolicyErrors) => true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; var request = WebRequest.Create(url) as HttpWebRequest; request.Method = "POST"; request.Timeout = 20000; // 20秒超时 request.ContentType = "application/x-www-form-urlencoded; charset=utf-8"; // 明确指定编码 // 添加调试头信息 request.Headers.Add("appid", APPID); request.Headers.Add("token", token); request.Headers.Add("userId", userId); // 构建带时区的日期参数 var postData = new StringBuilder(); var dateParam = DateTime.Now.AddDays(-1).ToString("yyyy-MM-ddTHH:mm:sszzz"); postData.AppendFormat("KQSDATE={0}&KQEDATE={1}", Uri.EscapeDataString(dateParam), Uri.EscapeDataString(dateParam)); byte[] byteData = Encoding.UTF8.GetBytes(postData.ToString()); // 改用UTF8编码 // 更完善的请求写入 using (var stream = request.GetRequestStream()) { stream.Write(byteData, 0, byteData.Length); } // 处理HTTP错误状态码 using (var response = request.GetResponse() as HttpWebResponse) { if (response.StatusCode != HttpStatusCode.OK) { throw new WebException($"服务器返回错误状态码: {(int)response.StatusCode} {response.StatusDescription}"); } using (var stream = response.GetResponseStream()) using (var reader = new StreamReader(stream, Encoding.UTF8)) { return reader.ReadToEnd(); } } } catch (WebException ex) when (ex.Response is HttpWebResponse response) { // 记录详细错误信息 var errorStream = response.GetResponseStream(); using (var reader = new StreamReader(errorStream)) { string errorDetails = reader.ReadToEnd(); throw new Exception($"请求失败 [Status: {response.StatusCode}]: {errorDetails}", ex); } } catch (Exception ex) { throw new Exception($"请求异常: {ex.Message}", ex); } } } // 新增DTO类 public class WorkflowRequestDto { /// /// 用户认证令牌 /// public string Token { get; set; } /// /// 原始用户ID(加密前) /// public string UserId { get; set; } /// /// 流程ID(必填) /// public int WorkflowId { get; set; } /// /// 流程标题(必填) /// public string RequestName { get; set; } /// /// 主表数据(必填) /// public Dictionary MainData { get; set; } /// /// 明细表数据(选填) /// public Dictionary DetailData { get; set; } /// /// 其他参数(选填) /// public Dictionary OtherParams { get; set; } } }