还是一如既往先上结构图如下:

上一讲说明了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签名验证的更多相关文章

  1. WebApi安全性 使用TOKEN+签名验证

    首先问大家一个问题,你在写开放的API接口时是如何保证数据的安全性的?先来看看有哪些安全性问题在开放的api接口中,我们通过http Post或者Get方式请求服务器的时候,会面临着许多的安全性问题, ...

  2. WebAPI 安全性 使用TOKEN+签名验证(上)

    首先问大家一个问题,你在写开放的API接口时是如何保证数据的安全性的?先来看看有哪些安全性问题在开放的api接口中,我们通过http Post或者Get方式请求服务器的时候,会面临着许多的安全性问题, ...

  3. WebAPI 用户认证防篡改实现HMAC(二)签名验证 AbsBaseAuthenticationAttribute--转

    public class ActionFilter : ActionFilterAttribute      {          public override void OnActionExecu ...

  4. WebApi安全性 使用TOKEN+签名验证 (秘钥是GUID的,私有的,不是雙方的,并不在网络连接上传输)

    转http://www.cnblogs.com/MR-YY/archive/2016/10/18/5972380.html WebApi安全性 使用TOKEN+签名验证   首先问大家一个问题,你在写 ...

  5. WebAPI 安全性 使用TOKEN+签名验证(下)

    //根据请求类型拼接参数 NameValueCollection form = HttpContext.Current.Request.QueryString; string data = strin ...

  6. WebApi基于Token和签名的验证

    最近一段时间在学习WebApi,涉及到验证部分的一些知识觉得自己并不是太懂,所以来博客园看了几篇博文,发现一篇讲的特别好的,读了几遍茅塞顿开(都闪开,我要装逼了),刚开始读有些地方不理解,所以想了很久 ...

  7. WebApi传参总动员(填坑)

    本以为系列文章已经Over,突然记起来前面留了个大坑还没填,真是自己给自己挖坑. 这个坑就是: (body 只能被读取一次)Only one thing can read the body MVC和W ...

  8. TOKEN+签名验证

    TOKEN+签名验证 首先问大家一个问题,你在写开放的API接口时是如何保证数据的安全性的?先来看看有哪些安全性问题在开放的api接口中,我们通过http Post或者Get方式请求服务器的时候,会面 ...

  9. 简析ASP.NET WebApi的跨域签名

    之前的文章写了关于WebApi的跨域问题,当中的方法只是解决了简单请求的跨域问题而非简单请求的跨域问题则没有解决. 要弄清楚 CORS规范将哪些类型的跨域资源请求划分为简单请求的范畴,需要额外了解几个 ...

随机推荐

  1. 鸟哥linux私房菜学习笔记,U盘安装centos5.3不能正常引导的问题

    前言: 一直都想学习linux,毕竟是做测试的标配.听过鸟哥的linux私房菜大名,作为新手我淘来了第三版,到手看到书的厚度,心都凉了半截,本着不能浪费的原则,还是学吧! 过程:        开始看 ...

  2. HTML表单基本格式与代码

    咱们先来看下今天咱们需要学习的内容,理解起来很简单,像我这种英语不好的只是需要背几个单词 在HTML中创建表单需要用到的最基本的代码和格式 <form method="post/get ...

  3. TCP三次握手四次挥手过程及各过程中客户端和服务器端的状态。

    #三次握手 客户端向服务器端发送SYN包,客户端进入SYN_SEND状态 服务器端收到客户端发送的包返回ACK+SYN包,服务器端进入SYN_RECV状态 客户端收到服务器端返回的包再发回ACK包,客 ...

  4. Python之路- 反射&定制自己的数据类型

    一.isinstance和issubclass isinstance(obj,cls)检查是否obj是否是类 cls 的对象 issubclass(sub, super)检查sub类是否是 super ...

  5. 用vuejs仿网易云音乐(实现听歌以及搜索功能)

    前言 前端时间学了vue,一开始看了vue1.0,后来实在觉得技术总得实践,就直接上手vue2.0.然后花了将近一周时间做了一个网易云音乐的小项目.一开始觉得项目比较小,没必要用vuex所以就没有使用 ...

  6. linux 基础(1)

    第一章 Linux 基础知识(一) 一.硬件介绍: 由一条总线把CPU.内存和I/O设备串联起来并与其他设备进行通信.CPU负责运算,内存用于储存临时变量,硬盘用于储存数据.1.1处理器CPU 从内存 ...

  7. Oracle学习历程--创建用户,分配表空间

    记录下学习Oracle12c的过程中的点点滴滴. Oracle12c新特性:http://www.cnblogs.com/kerrycode/p/3386917.html --创建临时表空间CREAT ...

  8. Linux学习之竿头直上

    今天第二讲昨天我们讲解了10基础命令,今早上我继续为大家讲解10个linux常见命令 今天主要讲解与网络相关的命令和软件安装的命名 NetworkManager 与rpm 在windows中我们查看网 ...

  9. String转int数字格式异常问题

     写在前面的话 差不多一年前就计划写博客,可因为种种原因一直没有写,反而我身边的一些同学在我建议他们写博客不久之后就写了,比如张博同学,基本每次总结一个知识点就写一篇,这样不但方便自己以后查看翻阅,也 ...

  10. [ABP实战开源项目]--YoYoCms目录

    ABP是"ASP.NET Boilerplate Project (ASP.NET样板项目)"的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WE ...