😎优化代码
This commit is contained in:
parent
d1021dde55
commit
7f4aee2465
@ -7,13 +7,12 @@
|
|||||||
namespace Admin.NET.Core;
|
namespace Admin.NET.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 自定义Json转换字段名
|
/// 自定义JSON属性特性,仅在三方接口序列化时生效
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[AttributeUsage(AttributeTargets.Property)]
|
[AttributeUsage(AttributeTargets.Property)]
|
||||||
public class CustomJsonPropertyAttribute(string name) : Attribute
|
public class CustomJsonPropertyAttribute(string name) : Attribute
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 序列化名称
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; } = name;
|
public string Name { get; } = name;
|
||||||
|
|
||||||
|
public string DateFormat { get; set; } = "yyyy-MM-dd HH:mm:ss";
|
||||||
}
|
}
|
||||||
@ -27,7 +27,7 @@ public partial class SysLogHttp : EntityTenantId
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 接口描述
|
/// 接口描述
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SugarColumn(ColumnDescription = "接口描述", Length = 32)]
|
[SugarColumn(ColumnDescription = "接口描述", Length = 64)]
|
||||||
[MaxLength(32)]
|
[MaxLength(32)]
|
||||||
public string? HttpApiDesc { get; set; }
|
public string? HttpApiDesc { get; set; }
|
||||||
|
|
||||||
@ -47,7 +47,8 @@ public partial class SysLogHttp : EntityTenantId
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 模块名称
|
/// 模块名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SugarColumn(ColumnDescription = "模块名称")]
|
[SugarColumn(ColumnDescription = "模块名称", Length = 64)]
|
||||||
|
[MaxLength(32)]
|
||||||
public string? ActionName { get; set; }
|
public string? ActionName { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -68,6 +69,12 @@ public partial class SysLogHttp : EntityTenantId
|
|||||||
[SugarColumn(ColumnDescription = "请求体", ColumnDataType = StaticConfig.CodeFirst_BigString)]
|
[SugarColumn(ColumnDescription = "请求体", ColumnDataType = StaticConfig.CodeFirst_BigString)]
|
||||||
public string? RequestBody { get; set; }
|
public string? RequestBody { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 请求体明文
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "请求体明文", ColumnDataType = StaticConfig.CodeFirst_BigString)]
|
||||||
|
public string? RequestBodyPlaintext { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 响应状态码
|
/// 响应状态码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -86,6 +93,12 @@ public partial class SysLogHttp : EntityTenantId
|
|||||||
[SugarColumn(ColumnDescription = "响应体", ColumnDataType = StaticConfig.CodeFirst_BigString)]
|
[SugarColumn(ColumnDescription = "响应体", ColumnDataType = StaticConfig.CodeFirst_BigString)]
|
||||||
public string? ResponseBody { get; set; }
|
public string? ResponseBody { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 响应体明文
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "响应体明文", ColumnDataType = StaticConfig.CodeFirst_BigString)]
|
||||||
|
public string? ResponseBodyPlaintext { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 异常信息
|
/// 异常信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -9,8 +9,7 @@ namespace Admin.NET.Core;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Http远程服务扩展
|
/// Http远程服务扩展
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class HttpRemotesExtension
|
public static class HttpRemotesExtension {
|
||||||
{
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 添加Http远程服务
|
/// 添加Http远程服务
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -18,7 +17,7 @@ public static class HttpRemotesExtension
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static IServiceCollection AddHttpRemoteClientService(this IServiceCollection services)
|
public static IServiceCollection AddHttpRemoteClientService(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
var options = App.GetConfig<object>("HttpRemotes") ?? throw new Exception("未正确配置HttpRemotes.json");
|
var options = App.GetOptions<HttpRemotesOptions>() ?? throw new Exception("未正确配置HttpRemotes.json");
|
||||||
foreach (var prop in options.GetType().GetProperties())
|
foreach (var prop in options.GetType().GetProperties())
|
||||||
{
|
{
|
||||||
if (prop.GetValue(options) is not HttpRemoteItem opt) continue;
|
if (prop.GetValue(options) is not HttpRemoteItem opt) continue;
|
||||||
@ -28,11 +27,10 @@ public static class HttpRemotesExtension
|
|||||||
client.Timeout = TimeSpan.FromSeconds(opt.Timeout);
|
client.Timeout = TimeSpan.FromSeconds(opt.Timeout);
|
||||||
foreach (var kv in opt.Headers) client.DefaultRequestHeaders.Add(kv.Key, kv.Value);
|
foreach (var kv in opt.Headers) client.DefaultRequestHeaders.Add(kv.Key, kv.Value);
|
||||||
})
|
})
|
||||||
.AddHttpMessageHandler<HttpLoggingHandler>()
|
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler {
|
||||||
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
|
|
||||||
{
|
|
||||||
UseCookies = opt.UseCookies
|
UseCookies = opt.UseCookies
|
||||||
});
|
})
|
||||||
|
.AddHttpMessageHandler<HttpLoggingHandler>();
|
||||||
}
|
}
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
@ -41,52 +39,11 @@ public static class HttpRemotesExtension
|
|||||||
/// 携带接口描述相关属性
|
/// 携带接口描述相关属性
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="builder"></param>
|
/// <param name="builder"></param>
|
||||||
/// <param name="httpName"></param>
|
|
||||||
/// <param name="attr"></param>
|
/// <param name="attr"></param>
|
||||||
|
/// <param name="reqPlaintext"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static HttpRequestBuilder SetRemoteApiAttr(this HttpRequestBuilder builder, string httpName, HttpRemoteApiAttribute attr)
|
public static HttpRequestBuilder SetRemoteApiAttr(this HttpRequestBuilder builder, HttpRemoteApiAttribute attr, string reqPlaintext = null)
|
||||||
{
|
{
|
||||||
return HttpLoggingHandler.SetRemoteApiAttr(builder, httpName, attr);
|
return HttpLoggingHandler.SetRemoteApiAttr(builder, attr, reqPlaintext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 远程请求配置项
|
|
||||||
/// </summary>
|
|
||||||
public sealed class HttpRemoteItem
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 是否启用日志
|
|
||||||
/// </summary>
|
|
||||||
public bool EnabledLog { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否启用代理
|
|
||||||
/// </summary>
|
|
||||||
public bool EnabledProxy { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 服务名称
|
|
||||||
/// </summary>
|
|
||||||
public string HttpName { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 服务地址
|
|
||||||
/// </summary>
|
|
||||||
public string BaseAddress { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 请求超时时间
|
|
||||||
/// </summary>
|
|
||||||
public int Timeout { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否自动处理Cookie
|
|
||||||
/// </summary>
|
|
||||||
public bool UseCookies { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 请求头
|
|
||||||
/// </summary>
|
|
||||||
public Dictionary<string, string> Headers { get; set; }
|
|
||||||
}
|
|
||||||
@ -8,11 +8,14 @@ using System.Net.Http.Headers;
|
|||||||
|
|
||||||
namespace Admin.NET.Core;
|
namespace Admin.NET.Core;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// http日志处理
|
/// http日志处理
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class HttpLoggingHandler : DelegatingHandler, ITransient
|
public class HttpLoggingHandler : DelegatingHandler, ITransient
|
||||||
{
|
{
|
||||||
|
private static readonly string RespPlaintextKey = CommonConst.HttpRemoteHeaderKeyPrefix + "RESP_PLAINTEXT__";
|
||||||
|
private static readonly string ReqPlaintextKey = CommonConst.HttpRemoteHeaderKeyPrefix + "REQ_PLAINTEXT__";
|
||||||
private static readonly string IgnoreLogKey = CommonConst.HttpRemoteHeaderKeyPrefix + "IGNORE_LOG__";
|
private static readonly string IgnoreLogKey = CommonConst.HttpRemoteHeaderKeyPrefix + "IGNORE_LOG__";
|
||||||
private static readonly string ApiDescKey = CommonConst.HttpRemoteHeaderKeyPrefix + "API_DESC__";
|
private static readonly string ApiDescKey = CommonConst.HttpRemoteHeaderKeyPrefix + "API_DESC__";
|
||||||
private static readonly string HttpNameKey = CommonConst.HttpRemoteHeaderKeyPrefix + "NAME__";
|
private static readonly string HttpNameKey = CommonConst.HttpRemoteHeaderKeyPrefix + "NAME__";
|
||||||
@ -27,10 +30,10 @@ public class HttpLoggingHandler : DelegatingHandler, ITransient
|
|||||||
_eventPublisher = eventPublisher;
|
_eventPublisher = eventPublisher;
|
||||||
_sysConfigService = sysConfigService;
|
_sysConfigService = sysConfigService;
|
||||||
|
|
||||||
var options = App.GetConfig<object>("HttpRemotes") ?? throw new Exception("未正确配置HttpRemotes.json");
|
var options = App.GetOptions<HttpRemotesOptions>() ?? throw new Exception("[HttpRemote] 未正确配置HttpRemotes.json");
|
||||||
_enabledLogMap = options.GetType().GetProperties()
|
_enabledLogMap = options.GetType().GetProperties()
|
||||||
.Where(u => u.PropertyType == typeof(HttpRemoteItem))
|
.Where(u => u.PropertyType == typeof(HttpRemoteItem))
|
||||||
.ToDictionary(u => u.GetValue(options) is HttpRemoteItem opt ? opt.HttpName : "",
|
.ToDictionary(u => u.GetValue(options) is HttpRemoteItem opt ? opt.HttpName : throw new Exception("[HttpRemote] 未正确配置HttpName"),
|
||||||
u => u.GetValue(options) is HttpRemoteItem { EnabledLog: true });
|
u => u.GetValue(options) is HttpRemoteItem { EnabledLog: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +45,7 @@ public class HttpLoggingHandler : DelegatingHandler, ITransient
|
|||||||
if (!enabledLog) return await base.SendAsync(request, cancellationToken);
|
if (!enabledLog) return await base.SendAsync(request, cancellationToken);
|
||||||
|
|
||||||
// 判断当前配置日志开关
|
// 判断当前配置日志开关
|
||||||
(string apiDesc, bool ignoreLog) = GetRemoteApiAttrAndRemove(request.Headers);
|
(string apiDesc, bool ignoreLog, string reqPlaintext) = GetRemoteApiAttrAndRemove(request.Headers);
|
||||||
_ = request.Options.TryGetValue<string>(HttpNameKey, out var httpName);
|
_ = request.Options.TryGetValue<string>(HttpNameKey, out var httpName);
|
||||||
if (!string.IsNullOrWhiteSpace(httpName)) enabledLog = _enabledLogMap.GetOrDefault(httpName);
|
if (!string.IsNullOrWhiteSpace(httpName)) enabledLog = _enabledLogMap.GetOrDefault(httpName);
|
||||||
if (!enabledLog || ignoreLog) return await base.SendAsync(request, cancellationToken);
|
if (!enabledLog || ignoreLog) return await base.SendAsync(request, cancellationToken);
|
||||||
@ -57,6 +60,7 @@ public class HttpLoggingHandler : DelegatingHandler, ITransient
|
|||||||
ActionName = urlList.Length >= 2 ? $"{urlList[^2]}/{urlList[^1]}" : urlList.Length >= 1 ? urlList[^1] : null,
|
ActionName = urlList.Length >= 2 ? $"{urlList[^2]}/{urlList[^1]}" : urlList.Length >= 1 ? urlList[^1] : null,
|
||||||
RequestUrl = request.RequestUri?.ToString(),
|
RequestUrl = request.RequestUri?.ToString(),
|
||||||
RequestHeaders = request.Headers.ToDictionary(u => u.Key, u => u.Value.Join(";")).ToJson(),
|
RequestHeaders = request.Headers.ToDictionary(u => u.Key, u => u.Value.Join(";")).ToJson(),
|
||||||
|
RequestBodyPlaintext = reqPlaintext,
|
||||||
TenantId = _userManager.Value?.TenantId,
|
TenantId = _userManager.Value?.TenantId,
|
||||||
CreateUserId = _userManager.Value?.UserId,
|
CreateUserId = _userManager.Value?.UserId,
|
||||||
CreateUserName = _userManager.Value?.RealName,
|
CreateUserName = _userManager.Value?.RealName,
|
||||||
@ -96,15 +100,16 @@ public class HttpLoggingHandler : DelegatingHandler, ITransient
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="headers"></param>
|
/// <param name="headers"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private static (string apiDesc, bool ignoreLog) GetRemoteApiAttrAndRemove(HttpRequestHeaders headers)
|
private static (string apiDesc, bool ignoreLog, string reqPlaintext) GetRemoteApiAttrAndRemove(HttpRequestHeaders headers)
|
||||||
{
|
{
|
||||||
var result = new
|
var result = new
|
||||||
{
|
{
|
||||||
|
ReqPlaintext = headers?.FirstOrDefault(u => u.Key == ReqPlaintextKey).Value?.FirstOrDefault()?.ToString(),
|
||||||
ApiDesc = headers?.FirstOrDefault(u => u.Key == ApiDescKey).Value?.FirstOrDefault()?.ToString(),
|
ApiDesc = headers?.FirstOrDefault(u => u.Key == ApiDescKey).Value?.FirstOrDefault()?.ToString(),
|
||||||
IgnoreLog = headers?.FirstOrDefault(u => u.Key == IgnoreLogKey).Value?.ToBoolean() ?? false,
|
IgnoreLog = headers?.FirstOrDefault(u => u.Key == IgnoreLogKey).Value?.ToBoolean() ?? false,
|
||||||
};
|
};
|
||||||
RemoveRemoteApiAttr(headers);
|
RemoveRemoteApiAttr(headers);
|
||||||
return (result.ApiDesc, result.IgnoreLog);
|
return (result.ApiDesc, result.IgnoreLog, result.ReqPlaintext);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -126,14 +131,14 @@ public class HttpLoggingHandler : DelegatingHandler, ITransient
|
|||||||
/// 设置接口描述相关属性
|
/// 设置接口描述相关属性
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="builder"></param>
|
/// <param name="builder"></param>
|
||||||
/// <param name="httpName"></param>
|
|
||||||
/// <param name="attr"></param>
|
/// <param name="attr"></param>
|
||||||
|
/// <param name="reqPlaintext">请求文明</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static HttpRequestBuilder SetRemoteApiAttr(HttpRequestBuilder builder, string httpName, HttpRemoteApiAttribute attr)
|
public static HttpRequestBuilder SetRemoteApiAttr(HttpRequestBuilder builder, HttpRemoteApiAttribute attr, string reqPlaintext = null)
|
||||||
{
|
{
|
||||||
builder.WithHeader(IgnoreLogKey, attr.IgnoreLog, replace: true);
|
builder.WithHeader(ReqPlaintextKey, reqPlaintext, replace:true);
|
||||||
builder.WithHeader(ApiDescKey, attr.Desc, replace: true);
|
builder.WithHeader(IgnoreLogKey, attr.IgnoreLog, replace:true);
|
||||||
builder.SetHttpClientName(httpName);
|
builder.WithHeader(ApiDescKey, attr.Desc, replace:true);
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -56,6 +56,11 @@ public class PageLogHttpOutput
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string RequestBody { get; set; }
|
public string RequestBody { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 请求体(明文)
|
||||||
|
/// </summary>
|
||||||
|
public string RequestBodyPlaintext { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 响应状态码
|
/// 响应状态码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -71,6 +76,11 @@ public class PageLogHttpOutput
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string ResponseBody { get; set; }
|
public string ResponseBody { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 响应体(明文)
|
||||||
|
/// </summary>
|
||||||
|
public string ResponseBodyPlaintext { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 异常信息
|
/// 异常信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -100,6 +110,7 @@ public class PageLogHttpOutput
|
|||||||
/// 创建用户
|
/// 创建用户
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string CreateUserName { get; set; }
|
public string CreateUserName { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
//
|
//
|
||||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.WebUtilities;
|
||||||
using Org.BouncyCastle.Crypto.Parameters;
|
using Org.BouncyCastle.Crypto.Parameters;
|
||||||
using Org.BouncyCastle.Utilities.Encoders;
|
using Org.BouncyCastle.Utilities.Encoders;
|
||||||
|
|
||||||
@ -35,6 +36,31 @@ public class CryptogramHelper
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据字符串生成SM4密钥
|
||||||
|
/// </summary>
|
||||||
|
public static string GetSm4Key(string identity)
|
||||||
|
{
|
||||||
|
ArgumentException.ThrowIfNullOrWhiteSpace(identity, nameof(identity));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] decoded = WebEncoders.Base64UrlDecode(identity);
|
||||||
|
|
||||||
|
if (decoded.Length < 16)
|
||||||
|
throw new ArgumentException($"Base64 解码后数据长度不足 16 字节,实际长度: {decoded.Length}", nameof(identity));
|
||||||
|
|
||||||
|
byte[] keyCode = new byte[16];
|
||||||
|
Buffer.BlockCopy(decoded, 0, keyCode, 0, 16);
|
||||||
|
|
||||||
|
return Hex.ToHexString(keyCode);
|
||||||
|
}
|
||||||
|
catch (FormatException ex)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("无效的 Base64Url 编码格式", nameof(identity), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 加密
|
/// 加密
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user