/// <summary>
/// 获取token
/// </summary>
/// <param name="staffId"></param>
/// <returns></returns>
public JsonResult GetToken(string staffId)
{
ResultMsg resultMsg = null; //判断参数是否合法
if (string.IsNullOrEmpty(staffId))
{
resultMsg = new ResultMsg();
resultMsg.StatusCode = (int)StatusCodeEnum.ParameterError;
resultMsg.Info = "staffId不合法";
resultMsg.Data = new Token();
return Json(resultMsg, JsonRequestBehavior.AllowGet);
} //插入缓存
Token token = (Token)HttpRuntime.Cache.Get(staffId);
if (HttpRuntime.Cache.Get(staffId.ToString()) == null)
{
token = new Token();
token.StaffId = staffId;
token.SignToken = Guid.NewGuid();
token.ExpireTime = DateTime.Now.AddDays();
HttpRuntime.Cache.Insert(token.StaffId.ToString(), token, null, token.ExpireTime, TimeSpan.Zero);
} //返回token信息
resultMsg = new ResultMsg();
resultMsg.StatusCode = (int)StatusCodeEnum.Success;
resultMsg.Info = "";
resultMsg.Data = token;
return Json(resultMsg, JsonRequestBehavior.AllowGet); }
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Mvc;
using WebApplication_Token.Models; namespace WebApplication_Token.Controllers
{
public class VerificationTokenController : Controller
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
ResultMsg resultMsg = null;
var request = Request;
var method = request.HttpMethod;
string staffid = string.Empty, timestamp = string.Empty, nonce = string.Empty, signature = string.Empty; if (!string.IsNullOrEmpty(request.Headers["staffid"]))
{
staffid = HttpUtility.UrlDecode(request.Headers.GetValues("staffid").FirstOrDefault());
}
if (!string.IsNullOrEmpty(request.Headers["timestamp"]))
{
timestamp = HttpUtility.UrlDecode(request.Headers.GetValues("timestamp").FirstOrDefault());
}
if (!string.IsNullOrEmpty(request.Headers["nonce"]))
{
nonce = HttpUtility.UrlDecode(request.Headers.GetValues("nonce").FirstOrDefault());
}
if (!string.IsNullOrEmpty(request.Headers["signature"]))
{
signature = HttpUtility.UrlDecode(request.Headers.GetValues("signature").FirstOrDefault());
} //GetToken方法不需要进行签名验证
if (filterContext.ActionDescriptor.ActionName == "GetToken")
{
base.OnActionExecuting(filterContext);
return;
} //判断请求头是否包含以下参数
if (string.IsNullOrEmpty(staffid) || string.IsNullOrEmpty(timestamp) || string.IsNullOrEmpty(nonce) || string.IsNullOrEmpty(signature))
{
resultMsg = new ResultMsg();
resultMsg.StatusCode = (int)HttpStatusCode.PartialContent;
resultMsg.Info = "请求头缺少参数";
resultMsg.Data = new Token();
filterContext.Result = Json(resultMsg, JsonRequestBehavior.AllowGet);//返回json数据
base.OnActionExecuting(filterContext);
return;
} //判断token是否有效
Token token = (Token)HttpRuntime.Cache.Get(staffid); string signtoken = string.Empty;
if (token == null)
{
resultMsg = new ResultMsg();
resultMsg.StatusCode = (int)StatusCodeEnum.ParameterError;
resultMsg.Info = "token为null";
resultMsg.Data = new Token();
filterContext.Result = Json(resultMsg, JsonRequestBehavior.AllowGet);//返回json数据
base.OnActionExecuting(filterContext);
return;
}
else
{
signtoken = token.SignToken.ToString();
} bool timespanvalidate = token.ExpireTime > Convert.ToDateTime(timestamp);
if (!timespanvalidate)
{
resultMsg = new ResultMsg();
resultMsg.StatusCode = (int)HttpStatusCode.PartialContent;
resultMsg.Info = "token已过期";
resultMsg.Data = new Token();
filterContext.Result = Json(resultMsg, JsonRequestBehavior.AllowGet);//返回json数据
base.OnActionExecuting(filterContext);
return;
} //根据请求类型拼接参数
NameValueCollection coll = Request.Form;
string[] requestItem = coll.AllKeys;
Dictionary<string, string> sArray = new Dictionary<string, string>();
int j = ;
for (j = ; j < requestItem.Length; j++)
{
sArray.Add(requestItem[j], Request.Form[requestItem[j]]);
}
var queryStr = GetQueryString(sArray);
var _signature = GetSingnature(timestamp, queryStr.Item1, staffid, signtoken, queryStr.Item2); if(signature!= _signature)
{
resultMsg = new ResultMsg();
resultMsg.StatusCode = (int)HttpStatusCode.PartialContent;
resultMsg.Info = "token不合法";
resultMsg.Data = new Token();
filterContext.Result = Json(resultMsg, JsonRequestBehavior.AllowGet);//返回json数据
base.OnActionExecuting(filterContext);
return;
} } /// <summary>
/// 获取签名字符串
/// </summary>
/// <param name="parames"></param>
/// <returns></returns>
public Tuple<string, string> GetQueryString(Dictionary<string, string> parames)
{
// 第一步:把字典按Key的字母顺序排序
IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parames);
IEnumerator<KeyValuePair<string, string>> dem = sortedParams.GetEnumerator(); // 第二步:把所有参数名和参数值串在一起
StringBuilder query = new StringBuilder("");//签名字符串
StringBuilder queryStr = new StringBuilder("");//url参数
if (parames == null || parames.Count == )
{
return new Tuple<string, string>("", "");
} while (dem.MoveNext())
{
string key = dem.Current.Key;
string value = dem.Current.Value;
if (!string.IsNullOrEmpty(key))
{
query.Append(key).Append(value);
queryStr.Append("&").Append(key).Append("=").Append(value);
}
} return new Tuple<string, string>(query.ToString(), queryStr.ToString().Substring(, queryStr.Length - ));
} /// <summary>
/// 根据参数计算签名
/// </summary>
/// <param name="timeStamp">发起请求时的时间戳(单位:毫秒)</param>
/// <param name="nonce">随机数</param>
/// <param name="staffId">当前请求用户StaffId</param>
/// <param name="signToken">signToken</param>
/// <param name="data">参数url</param>
/// <returns></returns>
public string GetSingnature(string timeStamp, string nonce, string staffId,string signToken, string data)
{
var hash = System.Security.Cryptography.MD5.Create();
//拼接签名
var signStr = timeStamp + nonce + staffId + signToken + data;
//将字符串中字符按升序排序
var sortStr = string.Concat(signStr.OrderBy(c => c));
var bytes = Encoding.UTF8.GetBytes(sortStr);
//使用MD5加密
var md5Val = hash.ComputeHash(bytes);
//把二进制转大写十六进制
StringBuilder result = new StringBuilder();
foreach (var c in md5Val)
{
result.Append(c.ToString("X2"));
}
return result.ToString().ToUpper(); }
}
}

MVC 统一验证Token demo的更多相关文章

  1. Spring Cloud中Feign如何统一设置验证token

    代码地址:https://github.com/hbbliyong/springcloud.git 原理是通过每个微服务请求之前都从认证服务获取认证之后的token,然后将token放入到请求头中带过 ...

  2. 本版本延续MVC中的统一验证机制~续的这篇文章,本篇主要是对验证基类的扩展和改善(转)

    本版本延续MVC中的统一验证机制~续的这篇文章,本篇主要是对验证基类的扩展和改善 namespace Web.Mvc.Extensions { #region 验证基类 /// <summary ...

  3. .NET Core微服务之基于Ocelot+IdentityServer实现统一验证与授权

    Tip: 此篇已加入.NET Core微服务基础系列文章索引 一.案例结构总览 这里,假设我们有两个客户端(一个Web网站,一个移动App),他们要使用系统,需要通过API网关(这里API网关始终作为 ...

  4. 使用Spring MVC统一异常处理实战

    1 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合 ...

  5. 使用Spring MVC统一异常处理实战<转>

    1 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合 ...

  6. MVC 数据验证

    MVC 数据验证 前一篇说了MVC数据验证的例子,这次来详细说说各种各样的验证注解.System.ComponentModel.DataAnnotations 一.基础特性 一.Required 必填 ...

  7. MVC 数据验证[转]

    前一篇说了MVC数据验证的例子,这次来详细说说各种各样的验证注解. 一.基础特性 一.Required 必填选项,当提交的表单缺少该值就引发验证错误. 二.StringLength 指定允许的长度 指 ...

  8. NET MVC权限验证

    ASP.NET MVC权限验证 封装类 写该权限类主要目地 为了让权限配置更加的灵活,可以根据SQL.json.或者XML的方式来动态进行页面的访问控制,以及没有权限的相关跳转. 使用步骤 1.要建一 ...

  9. Prism for WPF 搭建一个简单的模块化开发框架(四)异步调用WCF服务、WCF消息头添加安全验证Token

    原文:Prism for WPF 搭建一个简单的模块化开发框架(四)异步调用WCF服务.WCF消息头添加安全验证Token 为什么选择wcf?   因为好像wcf和wpf就是哥俩,,, 为什么选择异步 ...

随机推荐

  1. 全面理解Python中的类型提示(Type Hints)

    众所周知,Python 是动态类型语言,运行时不需要指定变量类型.这一点是不会改变的,但是2015年9月创始人 Guido van Rossum 在 Python 3.5 引入了一个类型系统,允许开发 ...

  2. Python--day62--ORM的使用

    4.Django里ORM的使用 1,手动创建数据库 2,在settings.py里面,配置数据库的连接信息 3,在项目/__init__.py告诉Django用pymysql模块代替MySQLdb(不 ...

  3. H3C HDLC状态检测

  4. 再一次利用with as 优化SQL

    上海的一个哥们问我有个SQL跑了4个小时都没跑完,实在受不了了,找我优化一下.我确实挺佩服他的,要是我遇到跑了几分钟的,就受不了了. SQL语句和执行计划如下: --sql id:1qbbw3th4x ...

  5. python基础四之列表

    列表详解 列表的增删改查! 增加 li = ['zxc', 'is', 'a'] # append 在列表结尾整体添加 修改列表,但是没有返回值 li.append('boy') print(li) ...

  6. 2018-7-31-C#-判断两条直线距离

    title author date CreateTime categories C# 判断两条直线距离 lindexi 2018-07-31 14:38:13 +0800 2018-05-08 10: ...

  7. P1057 迷宫路径

    题目描述 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, ...

  8. PHP判断类型

    is_bool();//判断是否为布尔型   is_float(); //判断是否为浮点型   is_int(); //判断是否为整型   is_numeric(); //判断是否为数值型   is_ ...

  9. 裁剪nutch 8步骤

    裁剪nutch 8步骤

  10. Java中大量if...else语句的消除替代方案

    在我们平时的开发过程中,经常可能会出现大量If else的场景,代码显的很臃肿,非常不优雅.那我们又没有办法处理呢? 针对大量的if嵌套让代码的复杂性增高而且难以维护.本文将介绍多种解决方案. 案例 ...