diff --git a/Blog.Core.Api/Controllers/LoginController.cs b/Blog.Core.Api/Controllers/LoginController.cs
index 8313507d..4838c3c9 100644
--- a/Blog.Core.Api/Controllers/LoginController.cs
+++ b/Blog.Core.Api/Controllers/LoginController.cs
@@ -15,324 +15,332 @@
namespace Blog.Core.Controllers
{
- ///
- /// 登录管理【无权限】
- ///
- [Produces("application/json")]
- [Route("api/Login")]
- [AllowAnonymous]
- public class LoginController : BaseApiController
- {
- readonly ISysUserInfoServices _sysUserInfoServices;
- readonly IUserRoleServices _userRoleServices;
- readonly IRoleServices _roleServices;
- readonly PermissionRequirement _requirement;
- private readonly IRoleModulePermissionServices _roleModulePermissionServices;
- private readonly ILogger _logger;
-
- ///
- /// 构造函数注入
- ///
- ///
- ///
- ///
- ///
- ///
- public LoginController(ISysUserInfoServices sysUserInfoServices, IUserRoleServices userRoleServices,
- IRoleServices roleServices, PermissionRequirement requirement,
- IRoleModulePermissionServices roleModulePermissionServices, ILogger logger)
- {
- this._sysUserInfoServices = sysUserInfoServices;
- this._userRoleServices = userRoleServices;
- this._roleServices = roleServices;
- _requirement = requirement;
- _roleModulePermissionServices = roleModulePermissionServices;
- _logger = logger;
- }
-
-
- #region 获取token的第1种方法
-
- ///
- /// 获取JWT的方法1
- ///
- ///
- ///
- ///
- [HttpGet]
- [Route("Token")]
- public async Task> GetJwtStr(string name, string pass)
- {
- string jwtStr = string.Empty;
- bool suc = false;
- //这里就是用户登陆以后,通过数据库去调取数据,分配权限的操作
-
- var user = await _sysUserInfoServices.GetUserRoleNameStr(name, MD5Helper.MD5Encrypt32(pass));
- if (user != null)
- {
- TokenModelJwt tokenModel = new TokenModelJwt {Uid = 1, Role = user};
-
- jwtStr = JwtHelper.IssueJwt(tokenModel);
- suc = true;
- }
- else
- {
- jwtStr = "login fail!!!";
- }
-
- return new MessageModel()
- {
- success = suc,
- msg = suc ? "获取成功" : "获取失败",
- response = jwtStr
- };
- }
-
-
- ///
- /// 获取JWT的方法2:给Nuxt提供
- ///
- ///
- ///
- ///
- [HttpGet]
- [Route("GetTokenNuxt")]
- public MessageModel GetJwtStrForNuxt(string name, string pass)
- {
- string jwtStr = string.Empty;
- bool suc = false;
- //这里就是用户登陆以后,通过数据库去调取数据,分配权限的操作
- //这里直接写死了
- if (name == "admins" && pass == "admins")
- {
- TokenModelJwt tokenModel = new TokenModelJwt
- {
- Uid = 1,
- Role = "Admin"
- };
-
- jwtStr = JwtHelper.IssueJwt(tokenModel);
- suc = true;
- }
- else
- {
- jwtStr = "login fail!!!";
- }
-
- var result = new
- {
- data = new {success = suc, token = jwtStr}
- };
-
- return new MessageModel()
- {
- success = suc,
- msg = suc ? "获取成功" : "获取失败",
- response = jwtStr
- };
- }
-
- #endregion
-
-
- ///
- /// 获取JWT的方法3:整个系统主要方法
- ///
- ///
- ///
- ///
- [HttpGet]
- [Route("JWTToken3.0")]
- public async Task> GetJwtToken3(string name = "", string pass = "")
-
- {
- string jwtStr = string.Empty;
-
- if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pass))
- return Failed("用户名或密码不能为空");
-
- pass = MD5Helper.MD5Encrypt32(pass);
-
- var user = await _sysUserInfoServices.Query(d =>
- d.LoginName == name && d.LoginPWD == pass && d.IsDeleted == false);
- if (user.Count > 0)
- {
- var userRoles = await _sysUserInfoServices.GetUserRoleNameStr(name, pass);
- //如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色
- var claims = new List
- {
- new Claim(ClaimTypes.Name, name),
- new Claim(JwtRegisteredClaimNames.Jti, user.FirstOrDefault().Id.ToString()),
- new Claim("TenantId", user.FirstOrDefault().TenantId.ToString()),
- new Claim(JwtRegisteredClaimNames.Iat, DateTime.Now.ToString()),
- new Claim(ClaimTypes.Expiration,
- DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString())
- };
- claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
-
-
- // ids4和jwt切换
- // jwt
- if (!Permissions.IsUseIds4)
- {
- var data = await _roleModulePermissionServices.RoleModuleMaps();
- var list = (from item in data
- where item.IsDeleted == false
- orderby item.Id
- select new PermissionItem
- {
- Url = item.Module?.LinkUrl,
- Role = item.Role?.Name.ObjToString(),
- }).ToList();
-
- _requirement.Permissions = list;
- }
-
- var token = JwtToken.BuildJwtToken(claims.ToArray(), _requirement);
- return Success(token, "获取成功");
- }
- else
- {
- return Failed("认证失败");
- }
- }
-
- ///
- /// 请求刷新Token(以旧换新)
- ///
- ///
- ///
- [HttpGet]
- [Route("RefreshToken")]
- public async Task> RefreshToken(string token = "")
- {
- string jwtStr = string.Empty;
-
- if (string.IsNullOrEmpty(token))
- return Failed("token无效,请重新登录!");
- var tokenModel = JwtHelper.SerializeJwt(token);
- if (tokenModel != null && JwtHelper.customSafeVerify(token) && tokenModel.Uid > 0)
- {
- var user = await _sysUserInfoServices.QueryById(tokenModel.Uid);
- var value = User.Claims.SingleOrDefault(s => s.Type == JwtRegisteredClaimNames.Iat)?.Value;
- if (value != null && user.CriticalModifyTime > value.ObjToDate())
- {
- return Failed("很抱歉,授权已失效,请重新授权!");
- }
-
- if (user != null && !(value != null && user.CriticalModifyTime > value.ObjToDate()))
- {
- var userRoles = await _sysUserInfoServices.GetUserRoleNameStr(user.LoginName, user.LoginPWD);
- //如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色
- var claims = new List
- {
- new Claim(ClaimTypes.Name, user.LoginName),
- new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Uid.ObjToString()),
- new Claim(JwtRegisteredClaimNames.Iat, DateTime.Now.ToString()),
- new Claim(ClaimTypes.Expiration,
- DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString())
- };
- claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
-
- //用户标识
- var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);
- identity.AddClaims(claims);
-
- var refreshToken = JwtToken.BuildJwtToken(claims.ToArray(), _requirement);
- return Success(refreshToken, "获取成功");
- }
- }
-
- return Failed("认证失败!");
- }
-
- ///
- /// 获取JWT的方法4:给 JSONP 测试
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- [HttpGet]
- [Route("jsonp")]
- public void Getjsonp(string callBack, long id = 1, string sub = "Admin", int expiresSliding = 30,
- int expiresAbsoulute = 30)
- {
- TokenModelJwt tokenModel = new TokenModelJwt
- {
- Uid = id,
- Role = sub
- };
-
- string jwtStr = JwtHelper.IssueJwt(tokenModel);
-
- string response = string.Format("\"value\":\"{0}\"", jwtStr);
- string call = callBack + "({" + response + "})";
- Response.WriteAsync(call);
- }
-
-
- ///
- /// 测试 MD5 加密字符串
- ///
- ///
- ///
- [HttpGet]
- [Route("Md5Password")]
- public string Md5Password(string password = "")
- {
- return MD5Helper.MD5Encrypt32(password);
- }
-
- ///
- /// swagger登录
- ///
- ///
- ///
- [HttpPost]
- [Route("/api/Login/swgLogin")]
- public async Task SwgLogin([FromBody] SwaggerLoginRequest loginRequest)
- {
- if (loginRequest is null)
- {
- return new {result = false};
- }
-
- try
- {
- var result = await GetJwtToken3(loginRequest.name, loginRequest.pwd);
- if (result.success)
- {
- HttpContext.SuccessSwagger();
- HttpContext.SuccessSwaggerJwt(result.response.token);
- return new {result = true};
- }
- }
- catch (Exception ex)
- {
- _logger.LogWarning(ex, "Swagger登录异常");
- }
-
- return new {result = false};
- }
-
- ///
- /// weixin登录
- ///
- ///
- [HttpGet]
- [Route("wxLogin")]
- public dynamic WxLogin(string g = "", string token = "")
- {
- return new {g, token};
- }
- }
-
- public class SwaggerLoginRequest
- {
- public string name { get; set; }
- public string pwd { get; set; }
- }
+ ///
+ /// 登录管理【无权限】
+ ///
+ [Produces("application/json")]
+ [Route("api/Login")]
+ [AllowAnonymous]
+ public class LoginController : BaseApiController
+ {
+ readonly ISysUserInfoServices _sysUserInfoServices;
+ readonly IUserRoleServices _userRoleServices;
+ readonly IRoleServices _roleServices;
+ readonly PermissionRequirement _requirement;
+ private readonly IRoleModulePermissionServices _roleModulePermissionServices;
+ private readonly ILogger _logger;
+
+ ///
+ /// 构造函数注入
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public LoginController(ISysUserInfoServices sysUserInfoServices, IUserRoleServices userRoleServices,
+ IRoleServices roleServices, PermissionRequirement requirement,
+ IRoleModulePermissionServices roleModulePermissionServices, ILogger logger)
+ {
+ this._sysUserInfoServices = sysUserInfoServices;
+ this._userRoleServices = userRoleServices;
+ this._roleServices = roleServices;
+ _requirement = requirement;
+ _roleModulePermissionServices = roleModulePermissionServices;
+ _logger = logger;
+ }
+
+
+ #region 获取token的第1种方法
+
+ ///
+ /// 获取JWT的方法1
+ ///
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Route("Token")]
+ public async Task> GetJwtStr(string name, string pass)
+ {
+ string jwtStr = string.Empty;
+ bool suc = false;
+ //这里就是用户登陆以后,通过数据库去调取数据,分配权限的操作
+
+ var user = await _sysUserInfoServices.GetUserRoleNameStr(name, MD5Helper.MD5Encrypt32(pass));
+ if (user != null)
+ {
+ TokenModelJwt tokenModel = new TokenModelJwt { Uid = 1, Role = user };
+
+ jwtStr = JwtHelper.IssueJwt(tokenModel);
+ suc = true;
+ }
+ else
+ {
+ jwtStr = "login fail!!!";
+ }
+
+ return new MessageModel()
+ {
+ success = suc,
+ msg = suc ? "获取成功" : "获取失败",
+ response = jwtStr
+ };
+ }
+
+
+ ///
+ /// 获取JWT的方法2:给Nuxt提供
+ ///
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Route("GetTokenNuxt")]
+ public MessageModel GetJwtStrForNuxt(string name, string pass)
+ {
+ string jwtStr = string.Empty;
+ bool suc = false;
+ //这里就是用户登陆以后,通过数据库去调取数据,分配权限的操作
+ //这里直接写死了
+ if (name == "admins" && pass == "admins")
+ {
+ TokenModelJwt tokenModel = new TokenModelJwt
+ {
+ Uid = 1,
+ Role = "Admin"
+ };
+
+ jwtStr = JwtHelper.IssueJwt(tokenModel);
+ suc = true;
+ }
+ else
+ {
+ jwtStr = "login fail!!!";
+ }
+
+ var result = new
+ {
+ data = new { success = suc, token = jwtStr }
+ };
+
+ return new MessageModel()
+ {
+ success = suc,
+ msg = suc ? "获取成功" : "获取失败",
+ response = jwtStr
+ };
+ }
+
+ #endregion
+
+
+ ///
+ /// 获取JWT的方法3:整个系统主要方法
+ ///
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Route("JWTToken3.0")]
+ public async Task> GetJwtToken3(string name = "", string pass = "")
+
+ {
+ string jwtStr = string.Empty;
+
+ if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pass))
+ return Failed("用户名或密码不能为空");
+
+ pass = MD5Helper.MD5Encrypt32(pass);
+
+ var user = await _sysUserInfoServices.Query(d =>
+ d.LoginName == name && d.LoginPWD == pass && d.IsDeleted == false);
+ if (user.Count > 0)
+ {
+ var userRoles = await _sysUserInfoServices.GetUserRoleNameStr(name, pass);
+ //如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色
+ var claims = new List
+ {
+ new Claim(ClaimTypes.Name, name),
+ new Claim(JwtRegisteredClaimNames.Jti, user.FirstOrDefault().Id.ToString()),
+ new Claim("TenantId", user.FirstOrDefault().TenantId.ToString()),
+ new Claim(JwtRegisteredClaimNames.Iat, DateTime.Now.ToString()),
+ new Claim(ClaimTypes.Expiration,
+ DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString())
+ };
+ claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
+
+
+ // ids4和jwt切换
+ // jwt
+ if (!Permissions.IsUseIds4)
+ {
+ var data = await _roleModulePermissionServices.RoleModuleMaps();
+ var list = (from item in data
+ where item.IsDeleted == false
+ orderby item.Id
+ select new PermissionItem
+ {
+ Url = item.Module?.LinkUrl,
+ Role = item.Role?.Name.ObjToString(),
+ }).ToList();
+
+ _requirement.Permissions = list;
+ }
+
+ var token = JwtToken.BuildJwtToken(claims.ToArray(), _requirement);
+ return Success(token, "获取成功");
+ }
+ else
+ {
+ return Failed("认证失败");
+ }
+ }
+
+ [HttpGet]
+ [Route("GetJwtTokenSecret")]
+ public async Task> GetJwtTokenSecret(string name = "", string pass = "")
+ {
+ var rlt = await GetJwtToken3(name, pass);
+ return rlt;
+ }
+
+ ///
+ /// 请求刷新Token(以旧换新)
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Route("RefreshToken")]
+ public async Task> RefreshToken(string token = "")
+ {
+ string jwtStr = string.Empty;
+
+ if (string.IsNullOrEmpty(token))
+ return Failed("token无效,请重新登录!");
+ var tokenModel = JwtHelper.SerializeJwt(token);
+ if (tokenModel != null && JwtHelper.customSafeVerify(token) && tokenModel.Uid > 0)
+ {
+ var user = await _sysUserInfoServices.QueryById(tokenModel.Uid);
+ var value = User.Claims.SingleOrDefault(s => s.Type == JwtRegisteredClaimNames.Iat)?.Value;
+ if (value != null && user.CriticalModifyTime > value.ObjToDate())
+ {
+ return Failed("很抱歉,授权已失效,请重新授权!");
+ }
+
+ if (user != null && !(value != null && user.CriticalModifyTime > value.ObjToDate()))
+ {
+ var userRoles = await _sysUserInfoServices.GetUserRoleNameStr(user.LoginName, user.LoginPWD);
+ //如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色
+ var claims = new List
+ {
+ new Claim(ClaimTypes.Name, user.LoginName),
+ new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Uid.ObjToString()),
+ new Claim(JwtRegisteredClaimNames.Iat, DateTime.Now.ToString()),
+ new Claim(ClaimTypes.Expiration,
+ DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString())
+ };
+ claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
+
+ //用户标识
+ var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);
+ identity.AddClaims(claims);
+
+ var refreshToken = JwtToken.BuildJwtToken(claims.ToArray(), _requirement);
+ return Success(refreshToken, "获取成功");
+ }
+ }
+
+ return Failed("认证失败!");
+ }
+
+ ///
+ /// 获取JWT的方法4:给 JSONP 测试
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Route("jsonp")]
+ public void Getjsonp(string callBack, long id = 1, string sub = "Admin", int expiresSliding = 30,
+ int expiresAbsoulute = 30)
+ {
+ TokenModelJwt tokenModel = new TokenModelJwt
+ {
+ Uid = id,
+ Role = sub
+ };
+
+ string jwtStr = JwtHelper.IssueJwt(tokenModel);
+
+ string response = string.Format("\"value\":\"{0}\"", jwtStr);
+ string call = callBack + "({" + response + "})";
+ Response.WriteAsync(call);
+ }
+
+
+ ///
+ /// 测试 MD5 加密字符串
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Route("Md5Password")]
+ public string Md5Password(string password = "")
+ {
+ return MD5Helper.MD5Encrypt32(password);
+ }
+
+ ///
+ /// swagger登录
+ ///
+ ///
+ ///
+ [HttpPost]
+ [Route("/api/Login/swgLogin")]
+ public async Task SwgLogin([FromBody] SwaggerLoginRequest loginRequest)
+ {
+ if (loginRequest is null)
+ {
+ return new { result = false };
+ }
+
+ try
+ {
+ var result = await GetJwtToken3(loginRequest.name, loginRequest.pwd);
+ if (result.success)
+ {
+ HttpContext.SuccessSwagger();
+ HttpContext.SuccessSwaggerJwt(result.response.token);
+ return new { result = true };
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.LogWarning(ex, "Swagger登录异常");
+ }
+
+ return new { result = false };
+ }
+
+ ///
+ /// weixin登录
+ ///
+ ///
+ [HttpGet]
+ [Route("wxLogin")]
+ public dynamic WxLogin(string g = "", string token = "")
+ {
+ return new { g, token };
+ }
+ }
+
+ public class SwaggerLoginRequest
+ {
+ public string name { get; set; }
+ public string pwd { get; set; }
+ }
}
\ No newline at end of file
diff --git a/Blog.Core.Api/Program.cs b/Blog.Core.Api/Program.cs
index db22fc62..875b4f2e 100644
--- a/Blog.Core.Api/Program.cs
+++ b/Blog.Core.Api/Program.cs
@@ -144,6 +144,9 @@
//app.UseHsts();
}
+app.UseEncryptionRequest();
+app.UseEncryptionResponse();
+
app.UseExceptionHandlerMiddle();
app.UseIpLimitMiddle();
app.UseRequestResponseLogMiddle();
diff --git a/Blog.Core.Api/appsettings.json b/Blog.Core.Api/appsettings.json
index f91f6df8..ff2c178a 100644
--- a/Blog.Core.Api/appsettings.json
+++ b/Blog.Core.Api/appsettings.json
@@ -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": {
diff --git a/Blog.Core.Common/Extensions/HttpResponseExceptions.cs b/Blog.Core.Common/Extensions/HttpResponseExceptions.cs
index 67deee45..34c3baae 100644
--- a/Blog.Core.Common/Extensions/HttpResponseExceptions.cs
+++ b/Blog.Core.Common/Extensions/HttpResponseExceptions.cs
@@ -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;
+ }
+ }
}
\ No newline at end of file
diff --git a/Blog.Core.Extensions/Middlewares/EncryptionRequestMiddleware.cs b/Blog.Core.Extensions/Middlewares/EncryptionRequestMiddleware.cs
new file mode 100644
index 00000000..9cb78a30
--- /dev/null
+++ b/Blog.Core.Extensions/Middlewares/EncryptionRequestMiddleware.cs
@@ -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
+{
+ ///
+ /// 自定义中间件
+ /// 通过配置,对指定接口返回数据进行加密返回
+ /// 可过滤文件流
+ ///
+ 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("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
+ {
+ ///
+ /// 自定义中间件
+ /// 通过配置,对指定接口入参进行解密操作
+ /// 注意:放到管道最外层
+ ///
+ public static IApplicationBuilder UseEncryptionRequest(this IApplicationBuilder builder)
+ {
+ return builder.UseMiddleware();
+ }
+ }
+}
diff --git a/Blog.Core.Extensions/Middlewares/EncryptionResponseMiddleware.cs b/Blog.Core.Extensions/Middlewares/EncryptionResponseMiddleware.cs
new file mode 100644
index 00000000..188c6f8d
--- /dev/null
+++ b/Blog.Core.Extensions/Middlewares/EncryptionResponseMiddleware.cs
@@ -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
+{
+ ///
+ /// 自定义中间件
+ /// 通过配置,对指定接口返回数据进行加密返回
+ /// 可过滤文件流
+ ///
+ 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("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
+ {
+ ///
+ /// 自定义中间件
+ /// 通过配置,对指定接口返回数据进行加密返回
+ /// 可过滤文件流
+ /// 注意:放到管道最外层
+ ///
+ public static IApplicationBuilder UseEncryptionResponse(this IApplicationBuilder builder)
+ {
+ return builder.UseMiddleware();
+ }
+ }
+}
diff --git a/Blog.Core.Extensions/Middlewares/RequRespLogMiddleware.cs b/Blog.Core.Extensions/Middlewares/RequRespLogMiddleware.cs
index 26971a3a..510b87ef 100644
--- a/Blog.Core.Extensions/Middlewares/RequRespLogMiddleware.cs
+++ b/Blog.Core.Extensions/Middlewares/RequRespLogMiddleware.cs
@@ -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,
diff --git a/Blog.Core.Extensions/ServiceExtensions/SqlsugarSetup.cs b/Blog.Core.Extensions/ServiceExtensions/SqlsugarSetup.cs
index eb012394..99133fe1 100644
--- a/Blog.Core.Extensions/ServiceExtensions/SqlsugarSetup.cs
+++ b/Blog.Core.Extensions/ServiceExtensions/SqlsugarSetup.cs
@@ -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);
}