mirror of
https://github.com/anjoy8/Blog.Core.git
synced 2024-09-20 23:48:27 +08:00
feat: 自定义请求参数解密和响应加密中间件
This commit is contained in:
parent
c85f51a901
commit
908e170a79
|
@ -70,7 +70,7 @@ namespace Blog.Core.Controllers
|
|||
var user = await _sysUserInfoServices.GetUserRoleNameStr(name, MD5Helper.MD5Encrypt32(pass));
|
||||
if (user != null)
|
||||
{
|
||||
TokenModelJwt tokenModel = new TokenModelJwt {Uid = 1, Role = user};
|
||||
TokenModelJwt tokenModel = new TokenModelJwt { Uid = 1, Role = user };
|
||||
|
||||
jwtStr = JwtHelper.IssueJwt(tokenModel);
|
||||
suc = true;
|
||||
|
@ -121,7 +121,7 @@ namespace Blog.Core.Controllers
|
|||
|
||||
var result = new
|
||||
{
|
||||
data = new {success = suc, token = jwtStr}
|
||||
data = new { success = suc, token = jwtStr }
|
||||
};
|
||||
|
||||
return new MessageModel<string>()
|
||||
|
@ -197,6 +197,14 @@ namespace Blog.Core.Controllers
|
|||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("GetJwtTokenSecret")]
|
||||
public async Task<MessageModel<TokenInfoViewModel>> GetJwtTokenSecret(string name = "", string pass = "")
|
||||
{
|
||||
var rlt = await GetJwtToken3(name, pass);
|
||||
return rlt;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 请求刷新Token(以旧换新)
|
||||
/// </summary>
|
||||
|
@ -297,7 +305,7 @@ namespace Blog.Core.Controllers
|
|||
{
|
||||
if (loginRequest is null)
|
||||
{
|
||||
return new {result = false};
|
||||
return new { result = false };
|
||||
}
|
||||
|
||||
try
|
||||
|
@ -307,7 +315,7 @@ namespace Blog.Core.Controllers
|
|||
{
|
||||
HttpContext.SuccessSwagger();
|
||||
HttpContext.SuccessSwaggerJwt(result.response.token);
|
||||
return new {result = true};
|
||||
return new { result = true };
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -315,7 +323,7 @@ namespace Blog.Core.Controllers
|
|||
_logger.LogWarning(ex, "Swagger登录异常");
|
||||
}
|
||||
|
||||
return new {result = false};
|
||||
return new { result = false };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -326,7 +334,7 @@ namespace Blog.Core.Controllers
|
|||
[Route("wxLogin")]
|
||||
public dynamic WxLogin(string g = "", string token = "")
|
||||
{
|
||||
return new {g, token};
|
||||
return new { g, token };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -144,6 +144,9 @@ else
|
|||
//app.UseHsts();
|
||||
}
|
||||
|
||||
app.UseEncryptionRequest();
|
||||
app.UseEncryptionResponse();
|
||||
|
||||
app.UseExceptionHandlerMiddle();
|
||||
app.UseIpLimitMiddle();
|
||||
app.UseRequestResponseLogMiddle();
|
||||
|
|
|
@ -265,6 +265,20 @@
|
|||
},
|
||||
"IpRateLimit": {
|
||||
"Enabled": true
|
||||
},
|
||||
"EncryptionResponse": {
|
||||
"Enabled": true,
|
||||
"AllApis": false,
|
||||
"LimitApis": [
|
||||
"/api/Login/GetJwtTokenSecret"
|
||||
]
|
||||
},
|
||||
"EncryptionRequest": {
|
||||
"Enabled": true,
|
||||
"AllApis": false,
|
||||
"LimitApis": [
|
||||
"/api/Login/GetJwtTokenSecret"
|
||||
]
|
||||
}
|
||||
},
|
||||
"IpRateLimiting": {
|
||||
|
|
116
Blog.Core.Extensions/Middlewares/EncryptionRequestMiddleware.cs
Normal file
116
Blog.Core.Extensions/Middlewares/EncryptionRequestMiddleware.cs
Normal file
|
@ -0,0 +1,116 @@
|
|||
using Blog.Core.Common;
|
||||
using Blog.Core.Common.Extensions;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Blog.Core.Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 自定义中间件
|
||||
/// 通过配置,对指定接口返回数据进行加密返回
|
||||
/// 可过滤文件流
|
||||
/// </summary>
|
||||
public class EncryptionRequestMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
|
||||
public EncryptionRequestMiddleware(RequestDelegate next)
|
||||
{
|
||||
_next = next;
|
||||
}
|
||||
|
||||
public async Task InvokeAsync(HttpContext context)
|
||||
{
|
||||
// 配置开关,过滤接口
|
||||
if (AppSettings.app("Middleware", "EncryptionRequest", "Enabled").ObjToBool())
|
||||
{
|
||||
var isAllApis = AppSettings.app("Middleware", "EncryptionRequest", "AllApis").ObjToBool();
|
||||
var needEnApis = AppSettings.app<string>("Middleware", "EncryptionRequest", "LimitApis");
|
||||
var path = context.Request.Path.Value.ToLower();
|
||||
if (isAllApis || (path.Length > 5 && needEnApis.Any(d => d.ToLower().Contains(path))))
|
||||
{
|
||||
Console.WriteLine($"{isAllApis} -- {path}");
|
||||
|
||||
if (context.Request.Method.ToLower() == "post")
|
||||
{
|
||||
// 读取请求主体
|
||||
using StreamReader reader = new(context.Request.Body, Encoding.UTF8);
|
||||
string requestBody = await reader.ReadToEndAsync();
|
||||
|
||||
// 检查是否有要解密的数据
|
||||
if (!string.IsNullOrEmpty(requestBody) && context.Request.Headers.ContainsKey("Content-Type") &&
|
||||
context.Request.Headers["Content-Type"].ToString().ToLower().Contains("application/json"))
|
||||
{
|
||||
// 解密数据
|
||||
string decryptedString = DecryptData(requestBody);
|
||||
|
||||
// 更新请求主体中的数据
|
||||
context.Request.Body = GenerateStreamFromString(decryptedString);
|
||||
}
|
||||
}
|
||||
else if (context.Request.Method.ToLower() == "get")
|
||||
{
|
||||
// 获取url参数
|
||||
string param = context.Request.Query["param"];
|
||||
|
||||
// 检查是否有要解密的数据
|
||||
if (!string.IsNullOrEmpty(param))
|
||||
{
|
||||
// 解密数据
|
||||
string decryptedString = DecryptData(param);
|
||||
|
||||
// 更新url参数值
|
||||
context.Request.QueryString = new QueryString($"?{decryptedString}");
|
||||
}
|
||||
}
|
||||
|
||||
await _next(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _next(context);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await _next(context);
|
||||
}
|
||||
}
|
||||
private string DecryptData(string encryptedData)
|
||||
{
|
||||
// 解密逻辑实现,可以根据你使用的加密算法和密钥进行自定义
|
||||
byte[] bytes = Convert.FromBase64String(encryptedData);
|
||||
string originalString = Encoding.UTF8.GetString(bytes);
|
||||
Console.WriteLine(originalString);
|
||||
return originalString;
|
||||
}
|
||||
private static Stream GenerateStreamFromString(string s)
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
var writer = new StreamWriter(stream);
|
||||
writer.Write(s);
|
||||
writer.Flush();
|
||||
stream.Position = 0;
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
|
||||
public static class EncryptionRequestExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 自定义中间件
|
||||
/// 通过配置,对指定接口入参进行解密操作
|
||||
/// 注意:放到管道最外层
|
||||
/// </summary>
|
||||
public static IApplicationBuilder UseEncryptionRequest(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<EncryptionRequestMiddleware>();
|
||||
}
|
||||
}
|
||||
}
|
114
Blog.Core.Extensions/Middlewares/EncryptionResponseMiddleware.cs
Normal file
114
Blog.Core.Extensions/Middlewares/EncryptionResponseMiddleware.cs
Normal file
|
@ -0,0 +1,114 @@
|
|||
using Blog.Core.Common;
|
||||
using Blog.Core.Common.Extensions;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Blog.Core.Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 自定义中间件
|
||||
/// 通过配置,对指定接口返回数据进行加密返回
|
||||
/// 可过滤文件流
|
||||
/// </summary>
|
||||
public class EncryptionResponseMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
|
||||
public EncryptionResponseMiddleware(RequestDelegate next)
|
||||
{
|
||||
_next = next;
|
||||
}
|
||||
|
||||
public async Task InvokeAsync(HttpContext context)
|
||||
{
|
||||
// 配置开关,过滤接口
|
||||
if (AppSettings.app("Middleware", "EncryptionResponse", "Enabled").ObjToBool())
|
||||
{
|
||||
var isAllApis = AppSettings.app("Middleware", "EncryptionResponse", "AllApis").ObjToBool();
|
||||
var needEnApis = AppSettings.app<string>("Middleware", "EncryptionResponse", "LimitApis");
|
||||
var path = context.Request.Path.Value.ToLower();
|
||||
if (isAllApis || (path.Length > 5 && needEnApis.Any(d => d.ToLower().Contains(path))))
|
||||
{
|
||||
Console.WriteLine($"{isAllApis} -- {path}");
|
||||
var responseCxt = context.Response;
|
||||
var originalBodyStream = responseCxt.Body;
|
||||
|
||||
// 创建一个新的内存流用于存储加密后的数据
|
||||
using var encryptedBodyStream = new MemoryStream();
|
||||
// 用新的内存流替换 responseCxt.Body
|
||||
responseCxt.Body = encryptedBodyStream;
|
||||
|
||||
// 执行下一个中间件请求管道
|
||||
await _next(context);
|
||||
|
||||
//encryptedBodyStream.Seek(0, SeekOrigin.Begin);
|
||||
//encryptedBodyStream.Position = 0;
|
||||
|
||||
// 可以去掉某些流接口
|
||||
if (!context.Response.ContentType.ToLower().Contains("application/json"))
|
||||
{
|
||||
Console.WriteLine($"非json返回格式 {context.Response.ContentType}");
|
||||
//await encryptedBodyStream.CopyToAsync(originalBodyStream);
|
||||
context.Response.Body = originalBodyStream;
|
||||
return;
|
||||
}
|
||||
|
||||
// 读取加密后的数据
|
||||
//var encryptedBody = await new StreamReader(encryptedBodyStream).ReadToEndAsync();
|
||||
var encryptedBody = responseCxt.GetResponseBody();
|
||||
|
||||
if (encryptedBody.IsNotEmptyOrNull())
|
||||
{
|
||||
dynamic jsonObject = JsonConvert.DeserializeObject(encryptedBody);
|
||||
string statusCont = jsonObject.status;
|
||||
var status = statusCont.ObjToInt();
|
||||
string msg = jsonObject.msg;
|
||||
string successCont = jsonObject.success;
|
||||
var success = successCont.ObjToBool();
|
||||
dynamic responseCnt = success ? jsonObject.response : "";
|
||||
string s = "1";
|
||||
// 这里换成自己的任意加密方式
|
||||
var response = responseCnt.ToString() != "" ? Convert.ToBase64String(Encoding.UTF8.GetBytes(responseCnt.ToString())) : "";
|
||||
string resJson = JsonConvert.SerializeObject(new { response, msg, status, s, success });
|
||||
|
||||
context.Response.Clear();
|
||||
await using var streamlriter = new StreamWriter(originalBodyStream, leaveOpen: true);
|
||||
await streamlriter.WriteAsync(resJson);
|
||||
|
||||
//var encryptedData = Encoding.UTF8.GetBytes(resJson);
|
||||
//responseCxt.ContentLength = encryptedData.Length;
|
||||
//await originalBodyStream.WriteAsync(encryptedData, 0, encryptedData.Length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await _next(context);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await _next(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class EncryptionResponseExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 自定义中间件
|
||||
/// 通过配置,对指定接口返回数据进行加密返回
|
||||
/// 可过滤文件流
|
||||
/// 注意:放到管道最外层
|
||||
/// </summary>
|
||||
public static IApplicationBuilder UseEncryptionResponse(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<EncryptionResponseMiddleware>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -96,10 +96,10 @@ namespace Blog.Core.Extensions.Middlewares
|
|||
|
||||
// 去除 Html
|
||||
var reg = "<[^>]+>";
|
||||
var isHtml = Regex.IsMatch(responseBody, reg);
|
||||
|
||||
if (!string.IsNullOrEmpty(responseBody))
|
||||
{
|
||||
var isHtml = Regex.IsMatch(responseBody, reg);
|
||||
Parallel.For(0, 1, e =>
|
||||
{
|
||||
//LogLock.OutSql2Log("RequestResponseLog", new string[] { "Response Data:", ResponseBody });
|
||||
|
|
Loading…
Reference in New Issue
Block a user