侧边栏壁纸
博主头像
分享你我博主等级

行动起来,活在当下

  • 累计撰写 118 篇文章
  • 累计创建 13 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

.net core实现全局请求参数解密

管理员
2025-05-14 / 0 评论 / 0 点赞 / 6 阅读 / 5485 字
 /// <summary>
 /// 解密请求中间件
 /// </summary>
 public class DecryptionRequestMiddleware
 {
     private readonly RequestDelegate _next;
     private readonly ILogger<DecryptionRequestMiddleware> _logger;

     public DecryptionRequestMiddleware(RequestDelegate next, ILogger<DecryptionRequestMiddleware> logger)
     {
         _next = next;
         _logger = logger;
     }

     public async Task InvokeAsync(HttpContext context)
     {
         try
         {
             _logger.LogInformation($"Processing request: {context.Request.Method} {context.Request.Path}");

             // 检查是否需要跳过加密处理
             if (ShouldSkipEncryption(context))
             {
                 await _next(context);
                 return;
             }

             // 检查加密版本头
             if (!context.Request.Headers.TryGetValue("X-Encryption-Version", out var version))
             {
                 _logger.LogWarning("Missing X-Encryption-Version header");
                 await ReturnErrorResponse(context, (int)ResultCode.MISSING_ENCRYPTION_VERSION_HEADER, "");//缺少加密版本头
                 return;
             }

             // 根据请求方法处理解密
             switch (context.Request.Method.ToUpper())
             {
                 case "GET":
                 case "DELETE":
                     await HandleQueryStringDecryption(context);
                     break;
                 case "POST":
                 case "PUT":
                     await HandleBodyDecryption(context);
                     break;
                 default:
                     _logger.LogWarning($"Unsupported HTTP method: {context.Request.Method}");
                     await ReturnErrorResponse(context, (int)ResultCode.ILLEGAL_REQUEST, "");
                     break;
             }

             await _next(context);
         }
         catch (Exception ex)
         {
             _logger.LogError(ex, "Error processing encrypted request");
             await ReturnErrorResponse(context, (int)ResultCode.REQUEST_PROCESSING_FAILED, "");
         }
     }

     private bool ShouldSkipEncryption(HttpContext context)
     {
         var endpoint = context.Features.Get<IEndpointFeature>()?.Endpoint;
         if (endpoint == null) return true;

         var skipEncryption = endpoint.Metadata.GetMetadata<SkipEncryptionAttribute>();
         return skipEncryption != null;
     }

     private async Task HandleQueryStringDecryption(HttpContext context)
     {
         string encryptedParam = context.Request.Query["data"];
         if (!string.IsNullOrEmpty(encryptedParam))
         {
             var decryptedQuery = RSAHelper.Decrypt(encryptedParam);
             context.Request.QueryString = new QueryString($"?{decryptedQuery}");
             _logger.LogDebug("Query string decrypted successfully");
         }
     }

     private async Task HandleBodyDecryption(HttpContext context)
     {
         if (context.Request.ContentType == null)
         {
             _logger.LogWarning("Missing Content-Type header");
             return;
         }

         context.Request.EnableBuffering();
         string requestBody;
         using (var reader = new StreamReader(context.Request.Body, Encoding.UTF8, leaveOpen: true))
         {
             requestBody = await reader.ReadToEndAsync();
         }
         context.Request.Body.Position = 0;

         string encryptedData = ExtractEncryptedData(requestBody, context.Request.ContentType);
         if (string.IsNullOrEmpty(encryptedData))
         {
             _logger.LogWarning("No encrypted data found in request body");
             return;
         }

         var decryptedBody = RSAHelper.Decrypt(encryptedData);
         byte[] decryptedBytes = Encoding.UTF8.GetBytes(decryptedBody);
         context.Request.Body = new MemoryStream(decryptedBytes);
         context.Request.ContentLength = decryptedBytes.Length;
         context.Request.Body.Position = 0;
         _logger.LogDebug("Request body decrypted successfully");
     }

     private string ExtractEncryptedData(string requestBody, string contentType)
     {
         if (contentType.StartsWith("application/x-www-form-urlencoded"))
         {
             return requestBody;
         }
         else if (contentType.StartsWith("application/json"))
         {
             var json = JsonConvert.DeserializeObject<JObject>(requestBody);
             return json["data"]?.ToString();
         }
         else if (contentType.Contains("text/plain"))
         {
             return requestBody;
         }

         throw new NotSupportedException($"Unsupported Content-Type: {contentType}");
     }

     private async Task ReturnErrorResponse(HttpContext context, int code, string message)
     {
         context.Response.StatusCode = StatusCodes.Status400BadRequest;
         context.Response.ContentType = "application/json";

         var response = new
         {
             Code = code,
             Msg = message,
             Data = new { }
         };

         var jsonResponse = JsonConvert.SerializeObject(response);
         await context.Response.WriteAsync(jsonResponse);
     }
 }

定义不需要请求参数解密的特性

    /// <summary>
    /// 标记不需要加密解密的特性
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
    public class SkipDecryptionAttribute : Attribute
    {

    }

0

评论区