使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:

  1. 客户端使用用户名跟密码请求登录
  2. 服务端收到请求,去验证用户名与密码
  3. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
  4. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
  5. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
  6. 服务端收到请求,然后去验证客户端请求里面带着的 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的 自定义身份认证+权限管理的更多相关文章

  1. 基于token的后台身份验证(转载)

    几种常用的认证机制 HTTP Basic Auth HTTP Basic Auth简单点说明就是每次请求API时都提供用户的username和password,简言之,Basic Auth是配合RES ...

  2. 在ASP.NET Web API 2中使用Owin基于Token令牌的身份验证

    基于令牌的身份验证 基于令牌的身份验证主要区别于以前常用的常用的基于cookie的身份验证,基于cookie的身份验证在B/S架构中使用比较多,但是在Web Api中因其特殊性,基于cookie的身份 ...

  3. 在ASP.NET Core中实现一个Token base的身份认证

    注:本文提到的代码示例下载地址> How to achieve a bearer token authentication and authorization in ASP.NET Core 在 ...

  4. [转]NET Core中实现一个Token base的身份认证

    本文转自:http://www.cnblogs.com/Leo_wl/p/6077203.html 注:本文提到的代码示例下载地址> How to achieve a bearer token ...

  5. 基于Token的WEB后台认证机制

    几种常用的认证机制 HTTP Basic Auth HTTP Basic Auth简单点说明就是每次请求API时都提供用户的username和password,简言之,Basic Auth是配合RES ...

  6. NET Core中实现一个Token base的身份认证

    NET Core中实现一个Token base的身份认证 注:本文提到的代码示例下载地址> How to achieve a bearer token authentication and au ...

  7. .NetCore WebApi——基于JWT的简单身份认证与授权(Swagger)

    上接:.NetCore WebApi——Swagger简单配置 任何项目都有权限这一关键部分.比如我们有许多接口.有的接口允许任何人访问,另有一些接口需要认证身份之后才可以访问:以保证重要数据不会泄露 ...

  8. 【转】基于Token的WEB后台认证机制

    原谅地址:http://www.cnblogs.com/xiekeli/p/5607107.html 几种常用的认证机制 HTTP Basic Auth HTTP Basic Auth简单点说明就是每 ...

  9. springboot结合jwt实现基于restful接口的身份认证

    基于restful接口的身份认证,可以采用jwt的方式实现,想了解jwt,可以查询相关资料,这里不做介绍~ 下面直接看如何实现 1.首先添加jwt的jar包,pom.xml中添加依赖包: <de ...

随机推荐

  1. ArrayList 源码分析

    ArrayList 源码分析 1. 结构   首先我们需要对 ArrayList 有一个大致的了解就从结构来看看吧. 1. 继承   该类继承自 AbstractList 这个比较好说 2. 实现 这 ...

  2. 【Flask】 flask-socketio实现WebSocket

    [flask-socektio] 之前不知道在哪个场合下提到过如何从web后台向前台推送消息.听闻了反向ajax技术这种模式之后,大呼神奇,试了一下之后发现也确实可以用.不过,反向ajax的代价也很明 ...

  3. kvm之六:配置kvm虚拟机通过VNC访问

    1.网络安装的snale2没有添加VNC访问方式,配置如下 [root@kvm ~ ::]#virsh edit snale2 插入如下配置: <graphics type=' autoport ...

  4. openjudge(三)

    已知三角形的三边分别是a.b.c, 先算出周长的一半s=1/2(a+b+c) 则该三角形面积S=根号[s(s-a)(s-b)(s-c)] 这个公式叫海伦--秦九昭公式 证明: 设三角形的三边a.b.c ...

  5. node.js与比特币(typescript实现)

    BTC中的utxo模型 BTC中引入了许多创新的概念与技术,区块链.PoW共识.RSA加密.萌芽阶段的智能合约等名词是经常被圈内人所提及,诚然这些创新的实现使得BTC变成了一种有可靠性和安全性保证的封 ...

  6. web服务器学习3---httpd 2.4.29日志处理

    .rotarelogs分割工具 如果有虚拟主机在虚拟主机配置文件中配置,否则在主配置文件中修改. 1.1修改配置文件 vi /usr/local/httpd/conf/conf.d/vhosts.co ...

  7. Beta开始前准备

    Beta准备 1. 讨论组长是否重选的议题和结论. 经过讨论,我们认为,经过一段时间的磨合,现任组长是不需要更换的. 2. 下一阶段需要改进完善的功能. 增加关于征信的功能,贴近选题主题 美化界面,尽 ...

  8. listview 与 button 焦点 在item添加下列属性

    android:descendantFocusability="blocksDescendants" http://zhaojianping.blog.51cto.com/7251 ...

  9. HAOI 2012 高速公路

    https://www.luogu.org/problem/show?pid=2221 题目描述 Y901高速公路是一条重要的交通纽带,政府部门建设初期的投入以及使用期间的养护费用都不低,因此政府在这 ...

  10. 美团点餐—listview内部按钮点击事件

    PS:长时间不写博客了,今天来写一下美团的这个点餐界面,今天先写一个加号减号的接口调用,下一篇是整体,有点菜,评价,商家,还有左边的listview和右边的展示项.进入这篇正题,像listview,G ...