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规范将哪些类型的跨域资源请求划分为简单请求的范畴,需要额外了解几个 ...
随机推荐
- virtual box ubuntu 与Windows共享文件夹
由于懒得去截图了,直接抛链接.参考链接:http://www.cnblogs.com/lidabo/p/5317024.html 简介概括:首先安装增强功能,接着在virtual box的seting ...
- iOS 关于定位你该注意的那些事
其实现在对于一个APP来说,定位用户的位置是件很容易的事情,有三种解决方案供您选择: (1)原生 (2)高德地图 (3)百度地图 1.解决方案的选择 其实单说iOS开发来说应用哪种方案都无所谓 ...
- fir.im Weekly - 如何在 iOS 上构建 TensorFlow 应用
本期 fir.im Weekly 收集了最近新鲜出炉的 iOS /Android 技术分享,包括 iOS 系统开发 TensorFlow 教程.iOS 新架构.iOS Notifications 推送 ...
- C#小知识点记录(QQ交流群的一个小问题)Linq提取数据
请教 这里 LINQ想 找到 最后的 4条 记录 然后放在 这里这个 List Linq查找怎么写呀? 解答:写了一个小例子作为解答. namespace C_Sharp { class Progra ...
- QT链接数据库
在介绍QT与数据的链接问题上,我在这里就不介绍关于QT环境与mysql.sqlite3环境的安装步骤了,以下的所有的操作都是建立在你已经安装了所有环境的基础上的.好的,那我们就具体来看一看QT环境中怎 ...
- JS实现图片不间断滚动
方法一: <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title ...
- git提交如何忽略某些文件
在使用git对项目进行版本管理的时候,我们总有一些不需要提交到版本库里的文件和文件夹,这个时候我们就需要让git自动忽略掉一下文件. 使用.gitignore忽略文件 为了让git忽略指定的文件和文件 ...
- Lambda表达式随笔
1.Lambda表达式是一个匿名函数,其本质其实还是一个函数,因此任何一个Lambda表达式都可以以其它的方式通过普通的函数实现或者代替. 2.Lambda表达式云算符:=>,该运算符读为&qu ...
- [Git]06 如何提交空目录
git和 svn不同,仅仅跟踪文件的变动,不跟踪目录.所以,一个空目录,如果里面没有文件,即便 git add 这个目录,另外在别处 check out 的时候,是没有这个空目录的. 只跟踪文件 ...
- linux 下启动程序的时候会显示坏的解释器,或者没有那个文件
又一次开发的时候在windowns上编写完的程序放到linux下运行的时候,比如:./start.sh的时候显示:"坏的解释器,没有那个文件"错误, 原因是windowns下写的s ...