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就是哥俩,,, 为什么选择异步 ...
随机推荐
- origin/HEAD -> origin/master 这个分支是干嘛的啊
➜ sso git:(master) ✗ git branch -r origin/4.0 origin/HEAD -> origin/master origin/master origin/H ...
- Beta版是什么意思
外部测试版的意思. 软件会出现三种版本 1.alpha内部测试版本,极不稳定,一般也不会出现的公众视线,仅供内部测试人员测试用. 2.beta公共测试版,就是对外发布软件的测试版,收集公众的意见和建议 ...
- P1107 栈
题目描述 背景 栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表. 栈有两种最重要的操作,即 pop(从栈顶弹出一个元素)和 push(将一个元素进栈). 栈的重要性不言 ...
- 140种Python标准库、第三方库和外部工具
导读:Python数据工具箱涵盖从数据源到数据可视化的完整流程中涉及到的常用库.函数和外部工具.其中既有Python内置函数和标准库,又有第三方库和工具. 这些库可用于文件读写.网络抓取和解析.数据连 ...
- H3C 环路避免机制一:路由毒化
- 2018-8-10-dot-net-core-使用-IPC-进程通信
title author date CreateTime categories dot net core 使用 IPC 进程通信 lindexi 2018-08-10 19:16:52 +0800 2 ...
- linux alloc_pages 接口
为完整起见, 我们介绍另一个内存分配的接口, 尽管我们不会准备使用它直到 15 章. 现 在, 能够说 struct page 是一个描述一个内存页的内部内核结构. 如同我们将见到的, 在内核中有许多 ...
- js三大框架出现的意义
解决了原始html,css,js的UI与数据状态之间同步的难题,避免了大量的操作DOM代码. 使用了React,Angular和Vue,我们只需要定义一次 UI 界面,不再需要为每个操作编写特定的 U ...
- Hamcrest匹配器框架
其实在之前的文章中已经使用过 Hamcrest 匹配器框架,本篇文章将系统的介绍它的使用. 为什么要用Hamcrest匹配器框架 Hamcrest是一款软件测试框架, 可以通过现有的匹配器类检查代码中 ...
- LuoguP2765 魔术球问题
LuoguP2765 魔术球问题 首先,很难看出来这是一道网络流题.但是因为在网络流24题中,所以还是用网络流的思路 首先考虑完全平方数的限制. 如果\(i,j\)满足\(i < j\) 且 $ ...