VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > temp > C#教程 >
  • C# 通用 HTTP 签名组件的另类实现

1、初衷

开发中经常需要做一些接口的签名生成和校验工作,最开始的时候都是每个接口去按照约定单独实现,久而久之就变的非常难维护,因此就琢磨怎么能够写了一个比较通用的签名生成工具。

2、思路

采用链式调用的方式,使得签名的步骤可以动态拼凑组合。

3、直接看效果


 
//设置数据源
 
var signSource = new Dictionary<string, string>()
 
{
 
{ "param1", "1" },
 
{ "param3", "3+" },
 
{ "param2", "2" }
 
};
 
var signer = new HttpSigner();
 
signer.SetSignData(signSource);
 
 
 
//设置数据源并配置规则
 
signer.SetSignData(signSource, setting =>
 
{
 
//按参数名排序
 
//result --> param1 param2 param3
 
setting.IsOrderByWithKey = false;
 
 
 
//是否对签名数据的参数值进行UrlEncode
 
setting.IsDoUrlEncodeForSourceValue = false;
 
 
 
//签名主体是否包含参数名
 
setting.IsSignTextContainKey = true;
 
//签名主体中参数和参数值的连接符(需要启用IsSignTextContainKey)
 
setting.SignTextKeyValueSeparator = "=";
 
//签名主体中不同参数项的连接符
 
setting.SignTextItemSeparator = "&";
 
//以上都开启后 --> param1=1&param2=2&param3=3
 
 
 
//编码
 
setting.DefaultEncoding = Encoding.UTF8;
 
});
 
 
 
//签名主体设置前缀
 
signer.SetSignData(signSource).SetSignTextPrefix("TestPrefix");
 
 
 
//签名主体设置后缀
 
signer.SetSignData(signSource).SetSignTextSuffix("TestSuffix");
 
 
 
//签名主体进行Base64
 
signer.SetSignData(signSource).SetSignTextBase64();
 
 
 
//签名主体进行MD5,(方法参数为签名结果是否转小写)
 
signer.SetSignData(signSource).SetSignTextMD5(bool isToLower = true);
 
 
 
//签名主体进行SHA1,(方法参数为签名结果是否转小写)
 
signer.SetSignData(signSource).SetSignTextSHA1(bool isToLower = true);
 
 
 
//获取签名结果
 
string signString = signer.SetSignData(signSource).GetSignResult();
 
 
 
//组合调用
 
string signString = signer.SetSignData(signSource).SetSignTextBase64().SetSignTextMD5().SetSignTextSHA1();

4、代码实现

HttpSignItem类

用于保存签名的参数集合。


 
namespace JiuLing.CommonLibs.Security.HttpSign
 
{
 
internal class HttpSignItem
 
{
 
public string Key { get; set; }
 
public string Value { get; set; }
 
 
 
public HttpSignItem(string key, string value)
 
{
 
Key = key;
 
Value = value;
 
}
 
}
 
}

HttpSignSetting类

用于签名的基本配置。


 
using System.Text;
 
 
 
namespace JiuLing.CommonLibs.Security.HttpSign
 
{
 
/// <summary>
 
/// 签名配置
 
/// </summary>
 
public class HttpSignSetting
 
{
 
/// <summary>
 
/// 是否按参数名进行排序
 
/// </summary>
 
public bool IsOrderByWithKey { get; set; } = false;
 
 
 
/// <summary>
 
/// 是否对签名数据的参数值进行UrlEncode
 
/// </summary>
 
public bool IsDoUrlEncodeForSourceValue { get; set; } = false;
 
 
 
/// <summary>
 
/// 签名主体是否包含参数名
 
/// </summary>
 
public bool IsSignTextContainKey { get; set; } = true;
 
 
 
/// <summary>
 
/// 签名主体中参数和参数值的连接符(需要启用IsSignTextContainKey)
 
/// </summary>
 
public string SignTextKeyValueSeparator { get; set; } = "=";
 
 
 
/// <summary>
 
/// 签名主体中不同参数项的连接符
 
/// </summary>
 
public string SignTextItemSeparator { get; set; } = "&";
 
 
 
/// <summary>
 
/// 编码
 
/// </summary>
 
public Encoding DefaultEncoding { get; set; } = Encoding.UTF8;
 
}
 
}

HttpSigner类

签名组件的具体实现。


 
using System;
 
using System.Collections.Generic;
 
using System.Linq;
 
 
 
namespace JiuLing.CommonLibs.Security.HttpSign
 
{
 
/// <summary>
 
/// 网络请求签名工具
 
/// </summary>
 
public class HttpSigner
 
{
 
/// <summary>
 
/// 签名配置
 
/// </summary>
 
private readonly HttpSignSetting _setting = new HttpSignSetting();
 
/// <summary>
 
/// 最终的签名串
 
/// </summary>
 
private string _signString;
 
 
 
/// <summary>
 
/// 设置签名数据
 
/// </summary>
 
/// <param name="signSource">待签名的键值对</param>
 
/// <param name="setting">配置签名规则</param>
 
/// <returns></returns>
 
/// <exception cref="ArgumentException"></exception>
 
public HttpSigner SetSignData(Dictionary<string, string> signSource, Action<HttpSignSetting> setting = null)
 
{
 
setting?.Invoke(_setting);
 
if (_setting == null)
 
{
 
throw new ArgumentNullException("无效的签名配置", "setting");
 
}
 
 
 
if (signSource == null || signSource.Count == 0)
 
{
 
throw new ArgumentException("待签名数据异常", nameof(signSource));
 
}
 
 
 
var signSourceList = new List<HttpSignItem>(signSource.Count);
 
foreach (var item in signSource)
 
{
 
var itemValue = item.Value;
 
if (_setting.IsDoUrlEncodeForSourceValue)
 
{
 
itemValue = System.Web.HttpUtility.UrlEncode(itemValue, _setting.DefaultEncoding);
 
}
 
signSourceList.Add(new HttpSignItem(item.Key, itemValue));
 
}
 
 
 
if (_setting.IsOrderByWithKey)
 
{
 
signSourceList = signSourceList.OrderBy(x => x.Key).ToList();
 
}
 
 
 
if (_setting.IsSignTextContainKey)
 
{
 
_signString = string.Join(_setting.SignTextItemSeparator, signSourceList.Select(x => $"{x.Key}{_setting.SignTextKeyValueSeparator}{x.Value}"));
 
}
 
else
 
{
 
_signString = string.Join(_setting.SignTextItemSeparator, signSourceList.Select(x => x.Value));
 
}
 
 
 
return this;
 
}
 
 
 
/// <summary>
 
/// 签名主体设置前缀
 
/// </summary>
 
/// <param name="input">前缀值</param>
 
/// <returns></returns>
 
public HttpSigner SetSignTextPrefix(string input)
 
{
 
_signString = $"{input}{_signString}";
 
return this;
 
}
 
 
 
/// <summary>
 
/// 签名主体设置后缀
 
/// </summary>
 
/// <param name="input">后缀值</param>
 
/// <returns></returns>
 
public HttpSigner SetSignTextSuffix(string input)
 
{
 
_signString = $"{_signString}{input}";
 
return this;
 
}
 
 
 
/// <summary>
 
/// 签名主体设置后缀
 
/// </summary>
 
/// <returns></returns>
 
public HttpSigner SetUrlEncode()
 
{
 
_signString = System.Web.HttpUtility.UrlEncode(_signString, _setting.DefaultEncoding);
 
return this;
 
}
 
 
 
/// <summary>
 
/// 签名主体进行Base64
 
/// </summary>
 
/// <returns></returns>
 
public HttpSigner SetSignTextBase64()
 
{
 
_signString = Base64Utils.GetStringValue(_signString);
 
return this;
 
}
 
 
 
/// <summary>
 
/// 签名主体进行MD5
 
/// </summary>
 
/// <param name="isToLower">签名结果是否转小写</param>
 
/// <returns></returns>
 
public HttpSigner SetSignTextMD5(bool isToLower = true)
 
{
 
if (isToLower)
 
{
 
_signString = MD5Utils.GetStringValueToLower(_signString);
 
}
 
else
 
{
 
_signString = MD5Utils.GetStringValueToUpper(_signString);
 
}
 
return this;
 
}
 
 
 
/// <summary>
 
/// 签名主体进行SHA1
 
/// </summary>
 
/// <param name="isToLower">签名结果是否转小写</param>
 
/// <returns></returns>
 
public HttpSigner SetSignTextSHA1(bool isToLower = true)
 
{
 
if (isToLower)
 
{
 
_signString = SHA1Utils.GetStringValueToLower(_signString);
 
}
 
else
 
{
 
_signString = SHA1Utils.GetStringValueToUpper(_signString);
 
}
 
return this;
 
}
 
 
 
/// <summary>
 
/// 获取签名结果
 
/// </summary>
 
/// <returns></returns>
 
public string GetSignResult()
 
{
 
return _signString;
 
}
 
}
 
}

5、附上仓库地址

以上代码包含在我的通用类库中,可以直接Nuget搜索JiuLing.CommonLibs   (https://www.nuget.org/packages/JiuLing.CommonLibs/)安装。

GitHub类库地址

https://github.com/JiuLing-zhang/JiuLing.CommonLibs


文章代码地址

https://github.com/JiuLing-zhang/JiuLing.CommonLibs/tree/main/src/Security/HttpSign

出处:https://www.cnblogs.com/JiuLing-zhang/p/16732526.html

 


相关教程