基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利。

流程上是这样的:

  • 用户使用用户名密码来请求服务器
  • 服务器进行验证用户的信息
  • 服务器通过验证发送给用户一个token
  • 客户端存储token,并在每次请求时附送上这个token值
  • 服务端验证token值,并返回数据

这个token必须要在每次请求时传递给服务端,它应该保存在请求头里。

OK,按照上述的流程,首先我们应当拿到登录的账户,密码等信息,验证通过后,生成TOKEN并发送给客户端,之后客户端的每个请求只需带上这个TOKEN,服务器端对这个TOKEN验证,验证通过后即可访问服务器资源,。

具体在C#中如何模仿这个流程呢?

  • 用户使用用户名密码来请求服务器
  • 服务器进行验证用户的信息

上述二个步骤其实是个登录过程,在此不作说明!

  • 服务器通过验证发送给用户一个token

发送给客户端一个Token,这个就需要我们生成Token了,那么怎样生成呢?理论模块可参考:Token的组成部分Token存放的信息

1、用C#生成Token:

首先引入JWT.dll

Token生成的具体代码如下:

--ToKen

2、将生成的Token发送给客户端后,随后,客户端的每次请求只需带上这个Token即可

一般都是将Token存放在Http请求的Headers中,也就是:context.Request.Headers,那么如何接收请求头中的Token呢?接收到Token后如何验证呢?

验证TOKEN时就需要构建 MVC Action 过滤器(AuthorizeAttribute)了,不过在构建 AuthorizeAttribute 之前,有必要对 AuthorizeAttribute 说明下,如下:

首先,AuthorizeAttribute 类位于System.Web.Http 命名空间下及System.Web.Mvc命名空间下,

一般情况下,如果你需要对C# MVC 控制器的访问作认证与授权,你需要用System.Web.Mvc命名空间下的 AuthorizeAttribute ,如果你需要对C# API 控制器的访问作认证与授权,你需要用System.Web.Http 命名空间下的 AuthorizeAttribute !

OK,知道了上述两种不同命名空间下的 AuthorizeAttribute ,下面以范例作为说明:

2.1、自定义MVC ACTION 登录授权验证,(由于本篇博客主讲 Token 的验证与实现,因此,关于MVC 登录验证只做代码说明:

2.1.1、新建一个MVC控制器,命名为BaseController,代码如下:


2.2.2、新建一个MVC控制器,命名为HomeController,代码如下:

2.2.3、新建一个登录实体类,命名为:LoginsModel,代码如下:

2.2.4、修改你的Global.asax文件,修改代码如下:

2.2.5、公共访问类CommonCS部分代码如下:

2.2.6、公共Token生成类代码如下:

2.2.7、新建一个登录页面,Login.cshtml代码如下:

@{
Layout = null;
} <!DOCTYPE html> <html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no"> <title>账户登录</title>
<link href="~/Content/css/materialize.min.css" rel="stylesheet" />
<style type="text/css">
html,
body {
height: 100%;
}
html {
display: table;
margin: auto;
}
body {
display: table-cell;
vertical-align: middle;
color:#47c1a8; } .margin {
margin: 0 !important;
} .card-panel{ min-width:350px;}
</style>
<!--[if IE]>
<script src="http://apps.bdimg.com/libs/html5shiv/3.7/html5shiv.min.js"></script>
<![endif]-->
</head>
<body class="red"> <div id="login-page" class="row">
<div class="col s12 z-depth-6 card-panel">
<form class="login-form">
<div class="row">
<div class="input-field col s12 center">
<img src="/content/images/100.png" alt="" class="responsive-img valign profile-image-login">
<p class="center login-form-text">账户登录</p>
</div>
</div>
<div class="row margin">
<div class="input-field col s12">
<i class="mdi-social-person-outline prefix"></i>
<input class="validate" id="UserName" name="UserName" type="tel" value="@ViewBag.HX_userName">
<label for="tel" data-error="wrong" data-success="right" class="center-align">手机号码:</label>
</div>
</div>
<div class="row margin">
<div class="input-field col s12">
<i class="mdi-action-lock-outline prefix"></i>
<input id="UserPwd" name="UserPwd" type="password" value="@ViewBag.HX_userPwd">
<label for="password">密码:</label>
</div>
</div>
<div class="row">
<div class="input-field col s12 m12 l12 login-text">
<input type="checkbox" id="remember-me" name="remember-me" />
<label for="remember-me">记住我</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<a href="JavaScript:void(0)" class="btn waves-effect waves-light col s12" onclick="Login()">登 录</a>
</div>
</div>
<div class="row">
<div class="input-field col s6 m6 l6">
<p class="margin medium-small"></p>
</div>
<div class="input-field col s6 m6 l6">
<p class="margin right-align medium-small"><a href="/home/forgotpassword">忘记密码?</a></p>
</div>
</div>
</form>
</div>
</div> <script src="~/Scripts/js/jquery-2.1.0.js"></script>
<script src="~/Scripts/js/materialize.min.js"></script>
<script type="text/javascript">
function Login() {
var UserName = $("#UserName").val();
var UserPwd = $("#UserPwd").val();
var remember = document.getElementById("remember-me").checked; $(document).ready(function (data) {
$.ajax({
url: "/Home/UserLogin",
type: "post",
contentType: "application/json",
dataType: "text",
data: JSON.stringify({ UserName: UserName, UserPwd: UserPwd, remember: remember }),
success: function (result, status) {
if (result == "HomeCare.Administrator") {
//登录成功 跳转
location.href = "/Manger/Index";//管理员登录
}
else {
alert(result);
}
},
error: function (error) {
alert(error);
}
});
});
}
</script>
<!--materialize js--> </body>
</html>

2.2.8、新建一个登录验证属性,继承自:System.Web.Mvc.AuthorizeAttribute,代码如下:(千呼万唤始出来啊......~_~)

2.2.9、新建一个MVC 控制器 ,命名为:MangerController,代码如下:

上述代码就不做演示了,大致过程是这样的:

Manger/Index的访问权限如下:

登录用户:

上述截图已经很清晰了,不再作重复说明。

OK,上述代码便是整个MVC 控制器 登录验证/授权认证的全部代码。下面我们请出本文终极BOSS,如果接收并解析验证接收的TOKEN。

3、下面介绍webAPI Controller 的认证授权

3.1、首先,我们自定义一个继承自System.Web.Http 命名空间下的AuthorizeAttribute 属性来解析并验证TOKEN

代码如下:

3.2、新增一个存储解析Token结果的类,命名为SysHelper.cs,代码如下:

3.3、公共Token生成方法修改如下:

3.4、定义一个MVC API Controller 代码如下:

OK,有了上述代码我们就可以模拟TOKEN验证了,模拟步骤如下:/

3.5、模拟TOKEN验证:

3.5.1、生成TOKEN,代码如下:

生成的TOKEN为:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiLnrb7lj5HogIXkv6Hmga8iLCJpYXQiOjE1MDk2OTEyODQsImV4cCI6MTUwOTY5ODQ4NCwiYXVkIjoiaHR0cDovL2V4YW1wbGUuY29tIiwic3ViIjoiSG9tZUNhcmUuVklQIiwianRpIjoiMjAxNzExMDMwMjQxMTkiLCJVc2VySWQiOjEsIlVzZXJOYW1lIjoiamFjay5jaGVuIiwiVXNlclB3ZCI6ImphY2sxMjM0NTYiLCJVc2VyUm9sZSI6IkhvbWVDYXJlLkFkbWluaXN0cmF0b3IifQ.IryLo19SSghi34LD1PNIOmzgzavQrnmGBD42pdojXtg

3.5.2、将获取的TOKEN(有效期两个小时)返回至客户端,客户端将获取的TOKEN放在 请求头 Headers 中,模拟请求如下(PostMan):

OK,将上述TOKEN随便去掉一个字母,请求结果如下:

过期的TOKEN,请求如下:

项目源码位置http://download.csdn.net/download/wolongbb/10102574

内容 参照 @陈卧龙的博客

c# asp.net 中使用token验证的更多相关文章

  1. 也谈Asp.net 中的身份验证

    钱李峰 的这篇博文<Asp.net中的认证与授权>已对Asp.net 中的身份验证进行了不错实践.而我这篇博文,是从初学者的角度补充了一些基础的概念,以便能有个清晰的认识. 一.配置安全身 ...

  2. ASP.NET中 RegularExpressValidator(正则验证)的使用

    原文:ASP.NET中 RegularExpressValidator(正则验证)的使用 ylbtech-ASP.NET-Control-Validator: RegularExpressValida ...

  3. 利用.net的内部机制在asp.net中实现身份验证

    知识点: 在ASP.NET中,任何页面都是继承于System.Web.UI.Page,他提供了Response,Request,Session,Application的操作.在使用Visual Stu ...

  4. Asp.net中基于Forms验证的角色验证授权

    Asp.net的身份验证有有三种,分别是"Windows | Forms | Passport",其中又以Forms验证用的最多,也最灵活. Forms 验证方式对基于用户的验证授 ...

  5. webapi中使用token验证(JWT验证)

    本文介绍如何在webapi中使用JWT验证 准备 安装JWT安装包 System.IdentityModel.Tokens.Jwt 你的前端api登录请求的方法,参考 axios.get(" ...

  6. Django中csrf token验证原理

    我多年没维护的博客园,有一篇初学Django时的笔记,记录了关于django-csrftoekn使用笔记,当时几乎是照抄官网的使用示例,后来工作全是用的flask.博客园也没有维护.直到我的博客收到了 ...

  7. ASP.NET WebApi实现Token验证

    记录笔记,在博客园中有很多实现Token的方法,这是我看过他们学到的,然后找到适合自己的解决方案,自己无聊总结一下学习经验写下的 WebApi后端接口实现Token验证 Token是在客户端频繁向服务 ...

  8. [转]ASP.NET中的forms验证

    本文转自:http://www.cnblogs.com/fengzheng126/archive/2012/04/06/2435513.html ASP.NET的安全认证:Windows验证 (默认) ...

  9. ASP.NET 中的 authentication(验证)与authorization(授权)

    这两个东西很绕口,也绕脑袋. 一般来说,了解authentication(验证)的用法即可,用于自定义的用户验证. authorization(授权)主要通过计算机信息来控制. “*”:所有用户: “ ...

随机推荐

  1. 【CCPC-Wannafly Winter Camp Day4 (Div1) C】最小边覆盖(简单题)

    点此看题面 大致题意: 给你一个边集的子集,问你这可不可能是这张图的最小边覆盖. 大致思路 考虑到,如果一条边连接的两个点度数都大于等于\(2\),则这条边完全可以删去. 因此,我们只要判断是否存在这 ...

  2. 【HDU4676】Sum Of Gcd(莫队+欧拉函数)

    点此看题面 大致题意: 多组询问,求\(\sum_{i=L}^R\sum_{j=i+1}^Rgcd(i,j)\). 推式子 这道题我们可以考虑,每个因数\(d\)被统计答案的次数,肯定与其出现次数有关 ...

  3. Search in Rotated Sorted Array——LeetCode

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e. ...

  4. parameter server

    http://zeromq.org ZeroMQ \zero-em-queue\, \ØMQ\: Ø  Connect your code in any language, on any platfo ...

  5. Mybatis查询报错:There is no getter for property named '*' in 'class java.lang.String

    问题: 执行查询时报错:There is no getter for property named '*' in 'class java.lang.String 原因: 传过去的参数为识别.本例为 p ...

  6. Linq to Entity 时间差作为筛选条件产生的问题

    前言 在使用 Linq to Entity 的時候,會把之前 Linq to SQL 的想法就帶進去,寫好之後編譯也都不會出錯,但是實際上在跑的時候就會出現錯誤訊息了,這點真的要注意了.這次我遇到問題 ...

  7. mysql基础,索引

  8. tomcat7下载地址

    tomcat7下载地址:https://tomcat.apache.org/download-70.cgi

  9. mac上配置java jdk环境

    访问Oracle官网 http://www.oracle.com,浏览到首页的底部菜单 ,然后按下图提示操作: 2.点击“JDK DOWNLOAD”按钮: 3.选择“Accept Lisence Ag ...

  10. Linux问题分析或解决_ssh无法连接

    1. ldd - 检查依赖库是否存在问题 问题:ssh连接不上,之前一直没有问题,最近别人安装了其他桌面(系统Ubuntu) 解决: 查看进程,发现没有启动 ps -ef | grep ssh 重新安 ...