使用基于 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. 设计模式 --> (5)适配器模式

    适配器模式 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹配而无法在一起工作的两个类能够在一起工作.比如说我的hp笔记本,美国产品,人家美国的电压是110V的,而我们中国的 ...

  2. android中shape属性大全

    出处:http://kofi1122.blog.51cto.com/2815761/521605

  3. (译文)React----React应用程序流式服务端渲染

    好处 React16推出了流式服务端渲染,它允许你并行地分发HTML片段.这样可以让渲染 出的首字节有意义的内容给用户速度更快. (例子1,上面部分是一次性转换,下面是流渲染,两种方式) 而且相对re ...

  4. 【详细】总结JavaWeb开发中SSH框架开发问题(用心总结,不容错过)

    在做JavaWeb的SSH框架开发的时候,遇到过很多的细节问题,这里大概记录下 我使用的IDE是Eclipse(老版本)三大框架:Spring4.Struts2.Hibernate5 1.web.xm ...

  5. 每日冲刺报告——Day1(Java-Team)

    第一天报告(11.2  周四) 团队:Java-Team 成员: 章辉宇(284) 吴政楠(286) 陈阳(PM:288) 韩华颂(142) 胡志权(143) github地址:https://git ...

  6. 高校征信系统项目Postmortem结果

    设想和目标 1 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们的软件需要解决的问题是当前高校学生征信系统建设薄弱的问题,我们试图建立一个征信系统,在完成之后推 ...

  7. 用greenlet实现Python中的并发

    from greenlet import greenlet def test1(): print 12 gr2.switch() print 34 def test2(): print 56 gr1. ...

  8. 201421123042 《Java程序设计》第9周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 2. 书面作业 本次作业题集集合 1. List中指定元素的删除(题集题目) 1.1 实验总结.并回答:列举至 ...

  9. bzoj千题计划243:bzoj2325: [ZJOI2011]道馆之战

    http://www.lydsy.com/JudgeOnline/problem.php?id=2325 设线段树节点区间为[l,r] 每个节点维护sum[0/1][0/1]  从l的A/B区域到r的 ...

  10. 从Nest到Nesk -- 模块化Node框架的实践

    文: 达孚(沪江Web前端架构师) 本文原创,转至沪江技术 首先上一下项目地址(:>): Nest:https://github.com/nestjs/nest Nesk:https://git ...