Skip to content

Commit

Permalink
Merge branch 'master' into net7.0
Browse files Browse the repository at this point in the history
  • Loading branch information
anjoy8 committed Nov 14, 2023
2 parents 6655c65 + d0fe732 commit f786881
Show file tree
Hide file tree
Showing 8 changed files with 610 additions and 349 deletions.
648 changes: 328 additions & 320 deletions Blog.Core.Api/Controllers/LoginController.cs

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Blog.Core.Api/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@
//app.UseHsts();
}

app.UseEncryptionRequest();
app.UseEncryptionResponse();

app.UseExceptionHandlerMiddle();
app.UseIpLimitMiddle();
app.UseRequestResponseLogMiddle();
Expand Down
14 changes: 14 additions & 0 deletions Blog.Core.Api/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
48 changes: 24 additions & 24 deletions Blog.Core.Common/Extensions/HttpResponseExceptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,29 @@ namespace Blog.Core.Common.Extensions;

public static class HttpResponseExceptions
{
public static string GetResponseBody(this HttpResponse response)
{
if (response is null)
{
return default;
}
public static string GetResponseBody(this HttpResponse response)
{
if (response is null)
{
return string.Empty;
}

if (response.Body is FluentHttpResponseStream responseBody)
{
response.Body.Position = 0;
//不关闭底层流
using StreamReader stream = new StreamReader(responseBody, leaveOpen: true);
string body = stream.ReadToEnd();
response.Body.Position = 0;
return body;
}
else
{
//原始HttpResponseStream 无法读取
//实际上只是个包装类,内部使用了HttpResponsePipeWriter write
throw new ApplicationException("The response body is not a FluentHttpResponseStream");
}
return default;
}
//原始HttpResponseStream 无法读取
//实际上只是个包装类,内部使用了HttpResponsePipeWriter write
switch (response.Body)
{
case FluentHttpResponseStream:
case MemoryStream:
{
response.Body.Position = 0;
using var stream = new StreamReader(response.Body, leaveOpen: true);
var body = stream.ReadToEnd();
response.Body.Position = 0;
return body;
}
default:
// throw new ApplicationException("The response body is not a FluentHttpResponseStream");
return string.Empty;
}
}
}
116 changes: 116 additions & 0 deletions Blog.Core.Extensions/Middlewares/EncryptionRequestMiddleware.cs
Original file line number Diff line number Diff line change
@@ -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>();
}
}
}
118 changes: 118 additions & 0 deletions Blog.Core.Extensions/Middlewares/EncryptionResponseMiddleware.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
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();
responseCxt.ContentType = "application/json";

//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);

responseCxt.Body = originalBodyStream;
}
}
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>();
}
}
}
4 changes: 2 additions & 2 deletions Blog.Core.Extensions/Middlewares/RequRespLogMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,11 @@ private void ResponseDataLog(HttpResponse response)

// 去除 Html
var reg = "<[^>]+>";
var isHtml = Regex.IsMatch(responseBody, reg);

if (!string.IsNullOrEmpty(responseBody))
{
Parallel.For(0, 1, e =>
var isHtml = Regex.IsMatch(responseBody, reg);
Parallel.For(0, 1, e =>
{
//LogLock.OutSql2Log("RequestResponseLog", new string[] { "Response Data:", ResponseBody });
LogLock.OutLogAOP("RequestResponseLog", response.HttpContext.TraceIdentifier,
Expand Down
8 changes: 5 additions & 3 deletions Blog.Core.Extensions/ServiceExtensions/SqlsugarSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,12 @@ public static void AddSqlsugarSetup(this IServiceCollection services)
{
BaseDBConfig.MainConfig = config;
}

//复用连接
if (m.ConnId.ToLower().StartsWith(MainDb.CurrentDbConnId.ToLower()))
else if (m.ConnId.ToLower().StartsWith(MainDb.CurrentDbConnId.ToLower()))
{
//复用连接
BaseDBConfig.ReuseConfigs.Add(config);
}


BaseDBConfig.ValidConfig.Add(config);
}
Expand Down

0 comments on commit f786881

Please sign in to comment.