玩一玩基于Token的 自定义身份认证+权限管理
使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:
- 客户端使用用户名跟密码请求登录
- 服务端收到请求,去验证用户名与密码
- 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
- 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
- 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
- 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据
一,用户点击登录时 对用户名密码进行检查。 当状态为Success 进而通过用户名密码去生成一个身份验证的令牌
从而对令牌进行加密 生成Token 然后放入Cookie里
public ActionResult Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
} LoginManager loginManager = new LoginManager();
var result = loginManager.SignIn(model.Email, model.Password);
if (result == LoginState.Success)
{
var role = loginManager.GetUserRoleByEmailAsync(model.Email); //通过用户名(邮箱) 密码生成一个ticket令牌
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(, model.Email, DateTime.Now,
DateTime.Now.AddMinutes(), true, string.Format("{0}&{1}", model.Email, model.Password)); //加密
var Token = FormsAuthentication.Encrypt(ticket); System.Web.HttpContext.Current.Session["UserName"]=model.Email;
System.Web.HttpContext.Current.Session["Role"] = role; //将Token加入到cookie 并设置为5天过期
var cookie = new HttpCookie("Token", Token)
{
Expires = DateTime.Now.AddDays()
};
Response.Cookies.Add(cookie); if (returnUrl != null)
{
return Redirect(returnUrl);
}
return Redirect("/Home/Chat");
} return View();
}
二,继承并重写 AuthorizeAttribute 中的 OnAuthorization
这里 我建了个XML文件用来存放action的角色权限
用来对方法访问的控制。 这里会解析token 然后进行匹配
<?xml version="1.0" encoding="utf-8" ?>
<Roles>
<Controller name="Home">
<Action name="Index"></Action>
<Action name="Chat">Admin,VIP5,VIP4</Action>
</Controller>
<Controller name="Account">
<Action name="Index"></Action>
<Action name="GETint">Admin,VIP5,VIP4</Action>
</Controller>
</Roles>
public class MVCAuthorize : AuthorizeAttribute
{
public new string Roles { get; set; } //这个是从Action中传过来的角色
public override void OnAuthorization(AuthorizationContext actionContext)
{ var token = actionContext.HttpContext.Request.Params["Token"]; if (!string.IsNullOrEmpty(token))
{
string controllerName = actionContext.ActionDescriptor.ControllerDescriptor.ControllerName; //得到控制器名称
string actionName = actionContext.ActionDescriptor.ActionName;//得到Action名称
string roles = GetActionRoles(actionName, controllerName); // 在Xml文件中根据控制器 Action 找到对应的访问角色权限
if (!string.IsNullOrWhiteSpace(roles))
{
this.Roles = Roles + "," + roles;
var isAuthValidate = ValidateTicket(token, Roles);
if (isAuthValidate != AuthorizeState.ValidateSuucss)
{
base.HandleUnauthorizedRequest(actionContext);
} }
}
else{
base.HandleUnauthorizedRequest(actionContext);
}
}
//获取当前Action的访问角色
public static string GetActionRoles(string action, string controller)
{
XElement rootElement = XElement.Load(HttpContext.Current.Server.MapPath("/") + "/XML/RoleAction.xml");
XElement controllerElement = findElementByAttribute(rootElement, "Controller", controller);
if (controllerElement != null)
{
XElement actionElement = findElementByAttribute(controllerElement, "Action", action);
if (actionElement != null)
{
return actionElement.Value;
}
}
return "";
}
public static XElement findElementByAttribute(XElement xElement, string tagName, string attribute)
{
return xElement.Elements(tagName).FirstOrDefault(x => x.Attribute("name").Value.Equals(attribute, StringComparison.OrdinalIgnoreCase));
}
//校验用户名密码(对Session匹配,或数据库数据匹配)
private AuthorizeState ValidateTicket(string encryptToken,string role)
{
if (encryptToken == null)
{
return AuthorizeState.TokenErro;
}
//解密Ticket
var strTicket = FormsAuthentication.Decrypt(encryptToken).UserData;
//从Ticket里面获取用户名和密码
var index = strTicket.IndexOf("&");
string userName = strTicket.Substring(, index);
string password = strTicket.Substring(index + );
ArrayList arrayList = new ArrayList(role.Split(','));
var roleName = HttpContext.Current.Session["Role"].ToString();
var name = HttpContext.Current.Session["UserName"].ToString();
//取得session,不通过说明用户退出,或者session已经过期
if (arrayList.Contains(roleName) && name == userName) //获取对应控制器 对应方法的访问角色权限 如果包含说明符合访问 否则返回权限错误
{
return AuthorizeState.ValidateSuucss;
}
else
{
return AuthorizeState.UserValidateErro;
}
}
}
当我们去访问这个方法时。他会先进行身份验证。进入MVCAuthorize中。 这里你可以扩展开来。 比如我临时需要对这个方法在多开放些角色 ,可以直接在action 带上
[MVCAuthorize(Roles = "VIP9,ActiveUser")]
public ActionResult Chat()
{ var account = HttpContext.User.Identity.Name;
ModelDBContext db = new ModelDBContext();
//ViewBag.UserName =db.User.Where(x=>x.Email == account).FirstOrDefault().FullName;
return View();
}
当检测到用户未登陆 。 没有通过认证的同时 去访问的话。 会返回一个401 你没有当前页面权限访问

然后就是通过验证后的样子

常常是看别人怎么实现。 还是自己多去实践 才能成长更快。 加油
工作之余。手撸代码。颇有漏洞。望君批正。
玩一玩基于Token的 自定义身份认证+权限管理的更多相关文章
- 基于token的后台身份验证(转载)
几种常用的认证机制 HTTP Basic Auth HTTP Basic Auth简单点说明就是每次请求API时都提供用户的username和password,简言之,Basic Auth是配合RES ...
- 在ASP.NET Web API 2中使用Owin基于Token令牌的身份验证
基于令牌的身份验证 基于令牌的身份验证主要区别于以前常用的常用的基于cookie的身份验证,基于cookie的身份验证在B/S架构中使用比较多,但是在Web Api中因其特殊性,基于cookie的身份 ...
- 在ASP.NET Core中实现一个Token base的身份认证
注:本文提到的代码示例下载地址> How to achieve a bearer token authentication and authorization in ASP.NET Core 在 ...
- [转]NET Core中实现一个Token base的身份认证
本文转自:http://www.cnblogs.com/Leo_wl/p/6077203.html 注:本文提到的代码示例下载地址> How to achieve a bearer token ...
- 基于Token的WEB后台认证机制
几种常用的认证机制 HTTP Basic Auth HTTP Basic Auth简单点说明就是每次请求API时都提供用户的username和password,简言之,Basic Auth是配合RES ...
- NET Core中实现一个Token base的身份认证
NET Core中实现一个Token base的身份认证 注:本文提到的代码示例下载地址> How to achieve a bearer token authentication and au ...
- .NetCore WebApi——基于JWT的简单身份认证与授权(Swagger)
上接:.NetCore WebApi——Swagger简单配置 任何项目都有权限这一关键部分.比如我们有许多接口.有的接口允许任何人访问,另有一些接口需要认证身份之后才可以访问:以保证重要数据不会泄露 ...
- 【转】基于Token的WEB后台认证机制
原谅地址:http://www.cnblogs.com/xiekeli/p/5607107.html 几种常用的认证机制 HTTP Basic Auth HTTP Basic Auth简单点说明就是每 ...
- springboot结合jwt实现基于restful接口的身份认证
基于restful接口的身份认证,可以采用jwt的方式实现,想了解jwt,可以查询相关资料,这里不做介绍~ 下面直接看如何实现 1.首先添加jwt的jar包,pom.xml中添加依赖包: <de ...
随机推荐
- if判断 -z -n 参数
_echo_error() { echo -ne "\033[31;1m $1\033[0m\n";}_echo_ok() { echo -ne "\033[32;1m ...
- java开发常用技术
基础部分 1. 线程和进程的区别 线程三个基本状态:就绪.执行.阻塞 线程五个基本操作:创建.就绪.运行.阻塞.终止 进程四种形式:主从式.会话式.消息或邮箱机制.共享存储区方式 进程是具有一定功能的 ...
- js 关于日期,字符串转化
<html><head><title>简单获取日期的JS</title><meta http-equiv="Content-Type&q ...
- Dynamics 365 for CRM: Sitemap站点图的可视化编辑功能
Dynamics 365 for CRM 提供了Sitemap站点图的可视化编辑功能 在之前的所有版本中,我们只能通过从系统中导出站点图的XML进行编辑后再导入(容易出错),或使用第三方的Sitema ...
- 【Spring源码深度解析学习系列】默认标签解析(三)
Spring的标签包括默认标签和自定义标签两种 默认标签的解析方法: ###DefaultBeanDefinitionDocumentReader.java### private void parse ...
- 【IntelliJ IDEA】使用idea解决新建jsp文件而找不到jsp文件模版的新建选项
使用idea解决新建jsp文件而找不到jsp文件模版的新建选项,这样每次创建一个新的jsp文件岂不是很耗时间? 解决办法: 就是要让idea知道你需要在这个目录下创建jsp文件 左上角,file中点击 ...
- Alpha冲刺Day3
Alpha冲刺Day3 一:站立式会议 今日安排: 我们把项目大体分为四个模块:数据管理员.企业人员.第三方机构.政府人员.数据管理员这一模块,数据管理员又可细分为两个模块:基础数据管理和风险信息管理 ...
- 学号:201621123032 《Java程序设计》第14周学习总结
1:本周学习总结 2:使用数据库技术改造你的系统 2.1:简述如何使用数据库技术改造你的系统.要建立什么表?截图你的表设计. 建立一个图书馆的表 建立读者用户个人的借书信息表---但是目前没有办法做到 ...
- android 框架LoonAndroid,码农偷懒专用
介绍 http://www.eoeandroid.com/thread-324764-1-1.html 架构培训视频: http://pan.baidu.com/s/1mgv8HTm 简介:下载 ht ...
- xcode7,ios9 部分兼容设置
神奇的苹果公司,再一次让程序员中枪. 一.xcode7 新建的项目,Foundation下默认所有http请求都被改为https请求. HTTP+SSL/TLS+TCP = HTTPS 也就是说,服务 ...