玩一玩基于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 ...
随机推荐
- shior笔记
Shiro 是一个强大而灵活的开源安全框架,能够非常清晰的处理认证.授权.管理会话以及密码加密.如下是它所具有的特点: 易于理解的 Java Security API: 简单的身份认证(登录),支持多 ...
- lua 二维数组创建
local arr= {} for i=1, 4 do arr[i] = {} end 使用时可以直接使用arr[i][j]
- 关于tomcat部署应用的三种方式
关于tomcat部署应用虽然不是一个经常的操作,因为一旦选择了一种部署方式,我们其他的应用就会不经大脑的使用这种既定模式, 如果不使用这种部署方式,但是对于其他的部署方式不是很清楚的话,很容易抓瞎,所 ...
- 前端之bootstrap模态框
简介:模态框(Modal)是覆盖在父窗体上的子窗体.通常,目的是显示来自一个单独的源的内容,可以在不离开父窗体的情况下有一些互动.子窗体可提供信息.交互等. Modal简介 Modal实现弹出表单 M ...
- Scala 快速入门
 Scalable 编程语言 纯正的的面向对象语言 函数式编程语言 无缝的java互操作 scala之父 Martin Odersky 1. 函数式编程 函数式编程(functional progr ...
- EasyUI导航栏。
html: <div data-options="region:'west',split:true" title="导航栏菜单" style=" ...
- MySQL“Another MySQL daemon already running with the same unix socket” 报错信息处理
Mysql "Another Mysql daemon already running with the same unix socket" 解决办法:rm var/lib/mys ...
- Win7下安装composer, 并使用其安装smarty
安装composer需要开启PHP openssl扩展. 1) 先查看PHP是否开启了openssl扩展 键盘win+r 输出cmd, 可以看到Dos窗口, 然后执行php -m (需要添加PHP环境 ...
- ### Cause: org.apache.ibatis.binding.BindingException: Parameter 'name' not found. Available parameters are [arg1, arg0, param1, param2]
org.apache.ibatis.exceptions.PersistenceException: ### Error updating database. Cause: org.apache.ib ...
- dubbo的InvocationChain
个人觉得dubbo比较好的设计是:一个是Cooma微容器设计.另一个就是InvocationChain了 Cooma微容器是自己实现了一套SPI,方便了用户做扩展: InvocationChain类似 ...