MVC 统一验证Token demo
/// <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的更多相关文章
- Spring Cloud中Feign如何统一设置验证token
代码地址:https://github.com/hbbliyong/springcloud.git 原理是通过每个微服务请求之前都从认证服务获取认证之后的token,然后将token放入到请求头中带过 ...
- 本版本延续MVC中的统一验证机制~续的这篇文章,本篇主要是对验证基类的扩展和改善(转)
本版本延续MVC中的统一验证机制~续的这篇文章,本篇主要是对验证基类的扩展和改善 namespace Web.Mvc.Extensions { #region 验证基类 /// <summary ...
- .NET Core微服务之基于Ocelot+IdentityServer实现统一验证与授权
Tip: 此篇已加入.NET Core微服务基础系列文章索引 一.案例结构总览 这里,假设我们有两个客户端(一个Web网站,一个移动App),他们要使用系统,需要通过API网关(这里API网关始终作为 ...
- 使用Spring MVC统一异常处理实战
1 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合 ...
- 使用Spring MVC统一异常处理实战<转>
1 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合 ...
- MVC 数据验证
MVC 数据验证 前一篇说了MVC数据验证的例子,这次来详细说说各种各样的验证注解.System.ComponentModel.DataAnnotations 一.基础特性 一.Required 必填 ...
- MVC 数据验证[转]
前一篇说了MVC数据验证的例子,这次来详细说说各种各样的验证注解. 一.基础特性 一.Required 必填选项,当提交的表单缺少该值就引发验证错误. 二.StringLength 指定允许的长度 指 ...
- NET MVC权限验证
ASP.NET MVC权限验证 封装类 写该权限类主要目地 为了让权限配置更加的灵活,可以根据SQL.json.或者XML的方式来动态进行页面的访问控制,以及没有权限的相关跳转. 使用步骤 1.要建一 ...
- Prism for WPF 搭建一个简单的模块化开发框架(四)异步调用WCF服务、WCF消息头添加安全验证Token
原文:Prism for WPF 搭建一个简单的模块化开发框架(四)异步调用WCF服务.WCF消息头添加安全验证Token 为什么选择wcf? 因为好像wcf和wpf就是哥俩,,, 为什么选择异步 ...
随机推荐
- 教你怎么让vi和vim显示行数
首先我们来看看没有行号是多么难看. 2 再来看看有行号后的效果. 3 设置行号很简单. 我们要到命令模式下,输入set number :set number 按下回车 来看看效果 4 那么怎么关闭行号 ...
- WOE:信用评分卡模型中的变量离散化方法(生存分析)
WOE:信用评分卡模型中的变量离散化方法 2016-03-21 生存分析 在做回归模型时,因临床需要常常需要对连续性的变量离散化,诸如年龄,分为老.中.青三组,一般的做法是ROC或者X-tile等等. ...
- 读取Flex AIR应用程序设置
说明: 本人之前做过一年的Flex AIR移动跨平台开发,在之前学习过程中,一直是将笔记记在了Evernote上,有的笔记是自己写的,也有的笔记是在网上看到,顺手记下了的. 所以在这里声明下,如果在网 ...
- pip安装python包时报字符编码错
比如安装scikit-learn时报错: django ascii’ codec can’t encode character 原因是用户目录或用户名存在中文,ascii不能解码,解决办法是在Pyth ...
- JPA一对多循环引用的解决&&JackSon无限递归问题
说是解决,其实不是很完美的解决的,写出来只是想记录一下这个问题或者看一下有没有哪位仁兄会的,能否知道一二. 下面说说出现问题: 问题是这样的,当我查询一个一对多的实体的时候,工具直接就爆了,差不多我就 ...
- WPF 使用 SharpDx 异步渲染
本文告诉大家如何通过 SharpDx 进行异步渲染,但是因为在 WPF 是需要使用 D3DImage 画出来,所以渲染只是画出图片,最后的显示还是需要 WPF 在他自己的主线程渲染 本文是一个系列,希 ...
- 负margin的原理及应用
在很多布局中我们经常能够见到类似于margin:-10px;的用法,我们对正值的用法早已熟悉的不能再熟悉了,可是这负值到底有何用呢?听我给你吹. 负margin——普通文档流 普通文档流元素(不浮动, ...
- 【GYM102091】2018-2019 ACM-ICPC, Asia Nakhon Pathom Regional Contest
A-Evolution Game 题目大意:有$n$个不同的野兽,定义第$i$ 个野兽有 $i$ 个眼睛和 $h[i]$ 个角,你可以任意从中选择一个野兽进行进化,每次进化角数量必须增加,而且进化后要 ...
- Linux 内核总线属性
几乎 Linux 驱动模型中的每一层都提供一个添加属性的接口, 并且总线层不例外. bus_attribute 类型定义在 <linux/device.h> 如下: struct bus_ ...
- WNMP nginx+php5+mysql测试环境安装(Windows7)(二)
3. 安装Zend Optimizer Zend Optimizer对那些在被最终执行之前由Run-Time Complier产生的代码进行优化,提高PHP应用程序的执行速度.一般情况下,执行使用Ze ...