webApi签名验证
还是一如既往先上结构图如下:

上一讲说明了redis,也谢谢心态的建议。这里经过改进后的redis的地址

当然这里是加密了的,具体实现如下图:

这里提供的解密。
先把加密解密的帮助类放上来。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks; namespace KuRuMi.Mio.DoMain.Infrastructure.Common
{
/// <summary>
/// 对称加密帮助类
/// </summary>
public class CryptographyExtension
{
// 对称加密算法提供器
private ICryptoTransform encryptor; // 加密器对象
private ICryptoTransform decryptor; // 解密器对象
private const int BufferSize = ;
private static string dataKey = "XXXXXXXX"; public CryptographyExtension(string algorithmName, string key)
{
SymmetricAlgorithm provider = SymmetricAlgorithm.Create(algorithmName);
provider.Key = Encoding.UTF8.GetBytes(key);
provider.IV = new byte[] { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; encryptor = provider.CreateEncryptor();
decryptor = provider.CreateDecryptor();
} public CryptographyExtension(string key) : this("TripleDES", key) { } /// <summary>
/// 加密算法
/// </summary>
/// <param name="clearText"></param>
/// <returns></returns>
public string Encrypt(string clearText)
{
// 创建明文流
byte[] clearBuffer = Encoding.UTF8.GetBytes(clearText);
MemoryStream clearStream = new MemoryStream(clearBuffer); // 创建空的密文流
MemoryStream encryptedStream = new MemoryStream(); CryptoStream cryptoStream =
new CryptoStream(encryptedStream, encryptor, CryptoStreamMode.Write); // 将明文流写入到buffer中
// 将buffer中的数据写入到cryptoStream中
int bytesRead = ;
byte[] buffer = new byte[BufferSize];
do
{
bytesRead = clearStream.Read(buffer, , BufferSize);
cryptoStream.Write(buffer, , bytesRead);
} while (bytesRead > ); cryptoStream.FlushFinalBlock(); // 获取加密后的文本
buffer = encryptedStream.ToArray();
string encryptedText = Convert.ToBase64String(buffer);
return encryptedText;
} /// <summary>
/// 解密算法
/// </summary>
/// <param name="encryptedText"></param>
/// <returns></returns>
public string Decrypt(string encryptedText)
{
byte[] encryptedBuffer = Convert.FromBase64String(encryptedText);
Stream encryptedStream = new MemoryStream(encryptedBuffer); MemoryStream clearStream = new MemoryStream();
CryptoStream cryptoStream =
new CryptoStream(encryptedStream, decryptor, CryptoStreamMode.Read); int bytesRead = ;
byte[] buffer = new byte[BufferSize]; do
{
bytesRead = cryptoStream.Read(buffer, , BufferSize);
clearStream.Write(buffer, , bytesRead);
} while (bytesRead > ); buffer = clearStream.GetBuffer();
string clearText =
Encoding.UTF8.GetString(buffer, , (int)clearStream.Length); return clearText;
} /// <summary>
/// 加密
/// </summary>
/// <param name="clearText"></param>
/// <param name="key"></param>
/// <returns></returns>
public static string Encrypts(string clearText)
{
CryptographyExtension helper = new CryptographyExtension(dataKey);
return helper.Encrypt(clearText);
} /// <summary>
/// 解密
/// </summary>
/// <param name="encryptedText"></param>
/// <param name="key"></param>
/// <returns></returns>
public static string Decrypts(string encryptedText)
{
CryptographyExtension helper = new CryptographyExtension(dataKey);
return helper.Decrypt(encryptedText);
}
}
}
完成这一些后,下面来看看签名验证。本来是写好了token+签名的验证,因为token目前还有些问题后来删掉了,改用签名验证。

这个方法是放在client端返回加密后的key。因为博主的项目全是post请求,这里就没有补充get请求。
public static T Post<T>(string url, string data, string appid)
{
byte[] bytes = Encoding.UTF8.GetBytes(data);
HttpWebRequest request = WebRequest.CreateHttp(url) as HttpWebRequest;
//加入到头信息中
request.Headers.Add("appid", appid);//当前的用户的请求id
request.Headers.Add("sign", GetSignature());//签名验证 //写数据
request.Method = "POST";
request.ContentLength = bytes.Length;
request.ContentType = "application/json";
Stream reqstream = request.GetRequestStream();
reqstream.Write(bytes, , bytes.Length); //读数据
request.Timeout = ;
request.Headers.Set("Pragma", "no-cache");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream streamReceive = response.GetResponseStream();
StreamReader streamReader = new StreamReader(streamReceive, Encoding.UTF8);
string strResult = streamReader.ReadToEnd(); //关闭流
reqstream.Close();
streamReader.Close();
streamReceive.Close();
request.Abort();
response.Close(); return JsonConvert.DeserializeObject<T>(strResult);
}
然后是调用:

页面上的写法就是在ajax里面加入请求头
$(function () {
$("#regist").click(function () {
var data = { userName: $("#text_r").val(), email: $("#email_r").val(), passWord: $("#password_r").val() };
debugger;
$.ajax({
//"Content-Type":"application/ json" //这里如果将此放入到headers里面会出现传入DTO参数的时候为空
headers: { appid: "2xl7w0Doqog=", sign: "MwOMp5bATVf1N2qNmAxW1GL1mduieOjsLHe45frBuISIpRE9OWncZ569sZraRQnwmWuQHNmJZJjCT/FaWsSiZw=="},
type: 'post',
datatype: 'json',
data: data,
url: 'http://localhost:13292/Api/App/DataForAjax',
success: function (data) {
$('small').html(data);
$('small').delay(3000).hide(0);
}
});
});
//"Content-Type":"application/ json" //这里如果将此放入到headers里面会出现传入DTO参数的时候为空
这里就是加上了
Content-Type":"application/ json造成的
去掉了之后

下面是filter代码
using KuRuMi.Mio.AppService.Common;
using KuRuMi.Mio.AppService.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Http.Controllers;
using System.Web.Http.Filters; namespace KuRuMi.Mio.AppService.Filter
{
public class SignSecretFilter : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
ResultMsg resultMsg = null;
string appId = string.Empty;
string sign = string.Empty;
if (actionContext.Request.Headers.Contains("appid"))
{
appId = HttpUtility.UrlDecode(actionContext.Request.Headers.GetValues("appid").FirstOrDefault());
}
if (actionContext.Request.Headers.Contains("sign"))
{
sign = HttpUtility.UrlDecode(actionContext.Request.Headers.GetValues("sign").FirstOrDefault());
} //判断请求头是否包含以下参数
if (string.IsNullOrEmpty(appId) || string.IsNullOrEmpty(sign))
{
resultMsg = new ResultMsg();
resultMsg.StatusCode = (int)StatusCodeEnum.ParameterError;
resultMsg.Info = StatusCodeEnum.ParameterError.GetEnumText();
resultMsg.Data = "";
actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(resultMsg));
base.OnActionExecuting(actionContext);
return;
}
//验证签名算法
bool result = SignExtension.Validate(appId, sign);
if (!result)
{
resultMsg = new ResultMsg();
resultMsg.StatusCode = (int)StatusCodeEnum.HttpRequestError;
resultMsg.Info = StatusCodeEnum.HttpRequestError.GetEnumText();
resultMsg.Data = "";
actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(resultMsg));
base.OnActionExecuting(actionContext);
return;
}
}
}
}
服务器端验证签名的方法:
using KuRuMi.Mio.DoMain.Infrastructure.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web; namespace KuRuMi.Mio.AppService.Common
{
/// <summary>
/// 判断签名算法
/// </summary>
public class SignExtension
{
private static readonly string keys = "Kurumi";
/// <summary>
/// 判断签名算法
/// </summary>
/// <param name="appId"></param>
/// <param name="url"></param>
/// <param name="sign">签名</param>
/// <returns></returns>
public static bool Validate(string appId, string sign)
{
byte[] bytes = Encoding.UTF8.GetBytes(ConfigManagerExtension.SecretKey);
string signs = string.Empty;
if (appId != "")
signs = CryptographyExtension.Decrypts(appId) + keys;
else
signs = appId + keys;
byte[] val = Encoding.UTF8.GetBytes(string.Concat(signs.OrderBy(c => c)));//排序
string key = null;
using (HMACSHA512 SecretKey = new HMACSHA512(bytes))
{
var SecretKeyBytes = SecretKey.ComputeHash(val);
key = Convert.ToBase64String(SecretKeyBytes);
}
return (sign.Equals(key, StringComparison.Ordinal));
}
}
}
webApi签名验证的更多相关文章
- WebApi安全性 使用TOKEN+签名验证
首先问大家一个问题,你在写开放的API接口时是如何保证数据的安全性的?先来看看有哪些安全性问题在开放的api接口中,我们通过http Post或者Get方式请求服务器的时候,会面临着许多的安全性问题, ...
- WebAPI 安全性 使用TOKEN+签名验证(上)
首先问大家一个问题,你在写开放的API接口时是如何保证数据的安全性的?先来看看有哪些安全性问题在开放的api接口中,我们通过http Post或者Get方式请求服务器的时候,会面临着许多的安全性问题, ...
- WebAPI 用户认证防篡改实现HMAC(二)签名验证 AbsBaseAuthenticationAttribute--转
public class ActionFilter : ActionFilterAttribute { public override void OnActionExecu ...
- WebApi安全性 使用TOKEN+签名验证 (秘钥是GUID的,私有的,不是雙方的,并不在网络连接上传输)
转http://www.cnblogs.com/MR-YY/archive/2016/10/18/5972380.html WebApi安全性 使用TOKEN+签名验证 首先问大家一个问题,你在写 ...
- WebAPI 安全性 使用TOKEN+签名验证(下)
//根据请求类型拼接参数 NameValueCollection form = HttpContext.Current.Request.QueryString; string data = strin ...
- WebApi基于Token和签名的验证
最近一段时间在学习WebApi,涉及到验证部分的一些知识觉得自己并不是太懂,所以来博客园看了几篇博文,发现一篇讲的特别好的,读了几遍茅塞顿开(都闪开,我要装逼了),刚开始读有些地方不理解,所以想了很久 ...
- WebApi传参总动员(填坑)
本以为系列文章已经Over,突然记起来前面留了个大坑还没填,真是自己给自己挖坑. 这个坑就是: (body 只能被读取一次)Only one thing can read the body MVC和W ...
- TOKEN+签名验证
TOKEN+签名验证 首先问大家一个问题,你在写开放的API接口时是如何保证数据的安全性的?先来看看有哪些安全性问题在开放的api接口中,我们通过http Post或者Get方式请求服务器的时候,会面 ...
- 简析ASP.NET WebApi的跨域签名
之前的文章写了关于WebApi的跨域问题,当中的方法只是解决了简单请求的跨域问题而非简单请求的跨域问题则没有解决. 要弄清楚 CORS规范将哪些类型的跨域资源请求划分为简单请求的范畴,需要额外了解几个 ...
随机推荐
- NODEJS环境搭建 第一篇 安装和部署NODEJS
一.下载安装文件 根据自己当前系统环境,下载相对应的安装文件 https://nodejs.org/en/download/ 二.双击安装 都傻瓜式的安装步骤,一步一步安装就好了. 三.检查安装结果 ...
- AngularJS创建新指令 - 函数功能
首先先介绍下AngularJS指令下的几种函数 Link函数和Scope 指令生成出的模板其实没有太多意义,除非它在特定的scope下编译.默认情况下,指令并不会创建新的子scope.更多的,它使用父 ...
- Andriod中自定义Dialog样式的Activity点击空白处隐藏软件盘(Dialog不消失)
一.需求触发场景: 项目中需要出发带有EditText的Dialog显示,要求在编辑完EditText时,点击Dilog的空白处隐藏软键盘.但是Dialog不会消失.示例如下: 二.实现方法: 发布需 ...
- eharts入门篇一
1.导入文件样式 从官网下载界面选择你需要的版本下载,根据开发者功能和体积上的需求,我们提供了不同打包的下载,如果你在体积上没有要求,可以直接下载完整版本. 2,引入 ECharts 文件 < ...
- 移动端H5开发 (滑动事件)
最近一直在做手机App H5的开发,在开发过程中,经常会遇到很多滑动事件,写个demo,分享自己的一些写法.(如写的不好,轻喷!) 直接贴代码 html css代码 <!DOCTYPE html ...
- 【算法系列学习】[kuangbin带你飞]专题十二 基础DP1 E - Super Jumping! Jumping! Jumping!
https://vjudge.net/contest/68966#problem/E http://blog.csdn.net/to_be_better/article/details/5056334 ...
- apache配置多个虚拟目录站点
错误的做法 网上查了几个资料,做法如下:比如想配置两个www.web1.com www.web2.com站点 打开httpd.conf ,然后添加: <VirtualHost *:80> ...
- Java中Properties类
1 简介: JDK提供的java.util.Properties类继承自Hashtable类并且实现了Map接口,用map来存储key-value数据,所以存入的数据是无序的.其中键和值都是字符串类型 ...
- redis数据库入门
Redis入门(1) 之安装.配置.安全登录 REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统. Redi ...
- 从点击到呈现 — 详解一次HTTP请求
一般来说,很多的参考资料上面都会说,http 是一个基于请求/响应的工作模式,然后画出一张浏览器和服务器的 b/s 结构图,再画上两个箭头,表示请求和响应,应该说这么解释是易懂的,一般也是够清楚的,但 ...
