/// <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
{
}
评论区