IT俱乐部 ASP.NET 通用 HTTP 签名组件的另类实现方式

通用 HTTP 签名组件的另类实现方式

1、初衷

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

2、思路

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

3、直接看效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//设置数据源
  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();</string>

4、代码实现

HttpSignItem类

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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类

用于签名的基本配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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类

签名组件的具体实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
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 name="setting">配置签名规则
        /// <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">前缀值
        /// <returns></returns>
        public HttpSigner SetSignTextPrefix(string input)
        {
            _signString = $"{input}{_signString}";
            return this;
        }
  
        /// <summary>
        /// 签名主体设置后缀
        /// </summary>
        /// <param name="input">后缀值
        /// <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">签名结果是否转小写
        /// <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">签名结果是否转小写
        /// <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;
        }
    }
}
</httpsignitem></httpsignsetting></string>

5、附上仓库地址

以上代码包含在我的通用类库中,可以直接Nuget搜索JiuLing.CommonLibs安装。
GitHub类库地址
文章代码地址

到此这篇关于通用 HTTP 签名组件的另类实现的文章就介绍到这了,更多相关HTTP 签名组件内容请搜索IT俱乐部以前的文章或继续浏览下面的相关文章希望大家以后多多支持IT俱乐部!

本文收集自网络,不代表IT俱乐部立场,转载请注明出处。https://www.2it.club/code/asp-net/1241.html
上一篇
下一篇
联系我们

联系我们

在线咨询: QQ交谈

邮箱: 1120393934@qq.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部