FormsAuthenticationTicket 

使用此类来为用户生成一个身份票据 持有该票据则说明该用户是通过了身份验证的用户 可以随时访问某些资源 我们先创建几个类

 //用户
 public class UserInfo
 {
     public string Name { get; set; }
     public int RoleID { get; set; }
     public string Password { get; set; }
 }

 //权限
 public class RoleRight
 {
     public int RoleID { get; set; }
     public string Route { get; set; }
 }

 //用户列表
 public class UserInfoList
 {
     public List<UserInfo> list = new List<UserInfo>
     {
             },
             },
     };
 }

 //权限列表
 public class RoleRightList
 {
     List<RoleRight> list = new List<RoleRight>
     {
         , Route="default/employee"},
         , Route="default/admin"}
     };
 }

用户列表存储了两个用户 它们的密码是加密后的字符 加密类在文章最后会提供 下面通过登录 测试该用户是否存在 如果存在则为其生成一个身份票据

 [HttpPost]
 public ActionResult Login(string name, string password)
 {
     //查询否有此用户
     ") == password);
     if (user != null)
     {
         //为其创建身份票据
         FormsAuthenticationTicket Ticket = , user.Name, DateTime.Now, DateTime.Now.AddDays(), true,user.RoleID.ToString());
         //加密票据
         string HashTicket = FormsAuthentication.Encrypt(Ticket);
         //将票据写入客户端
         HttpCookie UserCookie = new HttpCookie(FormsAuthentication.FormsCookieName, HashTicket);
         Response.Cookies.Add(UserCookie);
         //跳转到登录之前的页面
         var loginAgoUrl = FormsAuthentication.GetRedirectUrl(user.Name, true);
         return Redirect(loginAgoUrl);
     }
     ViewData["msg"] = "无此用户";
     return View();
 }

这样 登录用户就可以获得一个身份票据了 票据以cookie的形式存储在客户端 我们将票据的过期时间设为20天 即20天过后 票据失效 用户必须通过重新登录来访问站点的某些需要登录用户才能访问资源

获取已通过身份验证的用户的信息

我们知道通过HttpContext.User.Identity.Name可以获取到身份票据中的用户的名字 但无法获取到用户更多的信息 不可能每次都去查询数据库来获取该用户的信息 那么我们可以手动将用户类扩展一下 让其实现两个接口IPrincipal和IIdentity接口 因为HttpContext.User也实现这两个接口 HttpContext.User通过实现这两个接口能获取到用户的名字 如果用户类也实现这两个接口 则HttpContext.User就可以转换为用户类 用户类存储的信息则可以随时被访问到 转换后则可以在任何地方使用它来获取经过身份验证后的用户的所有信息了 我们将上面的UserInfo实现IPrincipal和IIdentity 如下

 //用户
 public class UserInfo : IPrincipal, IIdentity
 {
     //实现IIdentity接口 表示身份验证的类型为表单验证模式
     public string AuthenticationType { get { return "Froms"; } }

     //实现IIdentity接口 表示是否通过了身份验证
     public bool IsAuthenticated { get { return true; } }

     //实现IIdentity接口 用户名
     string IIdentity.Name { get { return this.UserName; } }

     //实现IPrincipal接口 用户唯一标识
     public IIdentity Identity { get { return this; } }

     //实现IPrincipal接口 如果当前用户是指定角色的成员,则为 true;否则为 false。
     public bool IsInRole(string role)
     {
         return false;
     }

     public string Name { get; set; }
     public int RoleID { get; set; }
     public string Password { get; set; }
 }

为了不用每次都去判断当前请求者是否是通过验证的用户 我们可以在Global.asax文件 为Application_PostAuthenticateRequest事件添加几行代码 如下

 public class MvcApplication : System.Web.HttpApplication
 {
     protected void Application_PostAuthenticateRequest(object sender, EventArgs e)
     {
         HttpApplication app = (HttpApplication)sender;
         if (app.Context.User.Identity.Name != "")  // 仅在用户已持有票据时将HttpContext.User替换为用户类UserInfo
         {
             var data = new UserInfoList().list.SingleOrDefault(n => n.Name == app.Context.User.Identity.Name);
             if (data != null)
             {
                 UserInfo user = data;
                 app.Context.User = user;
                 Thread.CurrentPrincipal = user;
             }
         }
     }

     protected void Application_Start()
     {
         //……
     }
 }

现在 可以在Action这样访问用户信息了

 public class DefaultController : Controller
 {
     private UserInfo user = System.Web.HttpContext.Current.User as UserInfo;

     public ActionResult Index()
     {
         if (user != null)
         {
             ViewData["Name"] = user.Name;
             ViewData["Password"] = user.Password;
         }
         return View();
     }
 }

注销身份票据

 FormsAuthentication.SignOut();

是否持有身份票据

 HttpContext.Current.User.Identity.IsAuthenticated

自定义过滤器验证用户角色是否有访问某资源的权限

只需要重写过滤器特性Authorize的OnAuthorization方法 该方法在截获用户请求后会被自动调用 即Url匹配路由成功 并转向对应的控制器之前会调用OnAuthorization方法 你可以在该方法中测试该用户的角色是否有访问该地址的权限

 public class MyFilters : AuthorizeAttribute
 {
     public override void OnAuthorization(AuthorizationContext filterContext)
     {
         UserInfo user = System.Web.HttpContext.Current.User == null ? null : System.Web.HttpContext.Current.User as UserInfo;
         var httpContext = filterContext.HttpContext;
         //未登录用户
         if (user == null) { filterContext.HttpContext.Response.Redirect("/Error.html"); return; }
         //获取登录用户的角色ID
         int roleID = user.RoleID;
         //获取请求的Url中的controller名字 如果要获取action的名字 则可以Values["action"]
         string Url = "/" + RouteTable.Routes.GetRouteData(httpContext).Values["controller"].ToString();
         //获取权限对应的功能
         var Data = new UserInfoList().list.Where(m => m.RoleID == roleID);
         var UrlList = from m in Data
                         join n in new RoleRightList().list
                         on m.RoleID equals n.RoleID
                         select n.Route;
         //所请求的Url未通过验证
         if (UrlList.Where(m => m.Contains(Url)).FirstOrDefault() == null)
         {
             httpContext.Response.Redirect("/Error.html");
             return;
         }
         //否则转向默认的过滤器 默认过滤器无逻辑测试则会将请求转到对应的action
         base.OnAuthorization(filterContext);
     }
 }

要使用这个过滤器只需要在Action或Controller上应用自定义的特性[MyFilters]

 [MyFilters]
 public class AdminController : Controller
 {

 }

这样 当每次请求进入控制器就会自动调用MyFilters过滤器 或者在Action方法上使用该特性也可以

票据加密算法

 using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
 using System.Security.Cryptography;
 using System.Text;
 using System.Web;

 namespace EncryptionHelper
 {
     public class Encryption
     {
         //默认密钥向量
         private static byte[] Keys = { 0xEF, 0xAB, 0x56, 0x78, 0x90, 0x34, 0xCD, 0x12 };

         #region DES加密字符
         /// <summary>
         /// DES加密字符
         /// </summary>
         /// <param name="encryptString">待加密的字符串</param>
         /// <param name="encryptKey">加密密钥,要求为8位</param>
         /// <returns>加密成功返回加密后的字符串,失败返回源串</returns>
         public static string EncryptDES(string encryptString, string encryptKey)
         {
             try
             {
                 , ));
                 byte[] rgbIV = Keys;
                 byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
                 DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
                 MemoryStream mStream = new MemoryStream();
                 CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                 cStream.Write(inputByteArray, , inputByteArray.Length);
                 cStream.FlushFinalBlock();
                 return Convert.ToBase64String(mStream.ToArray());
             }
             catch
             {
                 return encryptString;
             }
         }
         #endregion

         #region DES解密字符串
         /// <summary>
         /// DES解密字符串
         /// </summary>
         /// <param name="decryptString">待解密的字符串</param>
         /// <param name="decryptKey">解密密钥,要求为8位,和加密密钥相同</param>
         /// <returns>解密成功返回解密后的字符串,失败返源串</returns>
         public static string DecryptDES(string decryptString, string decryptKey)
         {
             try
             {
                 , ));
                 byte[] rgbIV = Keys;
                 byte[] inputByteArray = Convert.FromBase64String(decryptString);
                 DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
                 MemoryStream mStream = new MemoryStream();
                 CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                 cStream.Write(inputByteArray, , inputByteArray.Length);
                 cStream.FlushFinalBlock();
                 return Encoding.UTF8.GetString(mStream.ToArray());
             }
             catch
             {
                 return decryptString;
             }
         }
         #endregion

         #region SH1加密
         /// <summary>
         /// SH1加密
         /// </summary>
         /// <param name="Source_String">待加密的字符串</param>
         /// <returns>加密成功返回加密后的字符串,失败返回源串</returns>
         public string SHA1_Encrypt(string Source_String)
         {
             byte[] StrRes = Encoding.Default.GetBytes(Source_String);
             HashAlgorithm iSHA = new SHA1CryptoServiceProvider();
             StrRes = iSHA.ComputeHash(StrRes);
             StringBuilder EnText = new StringBuilder();
             foreach (byte iByte in StrRes)
             {
                 EnText.AppendFormat("{0:x2}", iByte);
             }
             return EnText.ToString();
         }
         #endregion
     }
 }

MVC - 学习总目录

MVC - 身份验证的更多相关文章

  1. Asp.Net MVC 身份验证-Forms

    Asp.Net MVC 身份验证-Forms 在MVC中对于需要登录才可以访问的页面,只需要在对应的Controller或Action上添加特性[Authorize]就可以限制非登录用户访问该页面.那 ...

  2. MVC身份验证.MVC过滤器.MVC6关键字Task,Async.前端模拟表单验证,提交.自定义匿名集合.Edge导出到Excel.BootstrapTree树状菜单的全选和反选.bootstrap可搜索可多选可全选下拉框

    1.MVC身份验证. 有两种方式.一个是传统的所有控制器继承自定义Control,然后再里面用MVC的过滤器拦截.所以每次网站的后台被访问时.就会先走入拦截器.进行前端和后端的验证 一个是利用(MVC ...

  3. Asp.net Mvc 身份验证、异常处理、权限验证(拦截器)实现代码

    本问主要介绍asp.net的身份验证机制及asp.net MVC拦截器在项目中的运用.现在让我们来模拟一个简单的流程:用户登录>权限验证>异常处理 1.用户登录 验证用户是否登录成功步骤直 ...

  4. MVC身份验证及权限管理

    MVC自带的ActionFilter 在Asp.Net WebForm的中要做到身份认证微软为我们提供了三种方式,其中最常用的就是我们的Form认证,需要配置相应的信息.例如下面的配置信息: < ...

  5. MVC身份验证及权限管理(转载)

    from https://www.cnblogs.com/asks/p/4372783.html MVC自带的ActionFilter 在Asp.Net WebForm的中要做到身份认证微软为我们提供 ...

  6. (转) MVC身份验证及权限管理-2

    转自:http://www.cnblogs.com/ldp615/archive/2010/10/27/asp-net-mvc-forms-authentication-roles-authoriza ...

  7. jwt的ASP.NET MVC 身份验证

    Json Web Token(jwt)      一种不错的身份验证及授权方案,与 Session 相反,Jwt 将用户信息存放在 Token 的 payload 字段保存在客户端,通过 RSA 加密 ...

  8. MVC 身份验证和异常处理过滤器

    :在Global中注册为全局过滤器,应用于所有的Controller的Action 参数类均继承自ControllerContext,主要包含属性请求上下文.路由数据.结果 using FilterE ...

  9. .Net MVC 身份验证

    .Net身份验证主要是分为三种 Windows | Forms | Passport ,其中Froms在项目中用的最多. Windows 身份验证 Forms 验证 Passport 验证 1.Win ...

随机推荐

  1. 【大话QT之十】实现FTP断点续传(需要设置ftp服务器为“PASV”被动接收方式)

    应用需求: 网盘开发工作逐步进入各部分的整合阶段,当用户在客户端修改或新增加一个文件时,该文件要同步上传到服务器端对应的用户目录下,因此针对数据传输(即:上传.下载)这一块现在既定了三种传输方式,即: ...

  2. BGP详解

    相信各位站长在托管服务器或者选择虚拟主机的时候,提供商都会说他们的机房是双线机房,保证你的站点访问速度,那么这里所谓的双线机房到底是何意思,它又为何能提升站点的访问速度呢? 一遍小型机房的所谓双线路其 ...

  3. BZOJ_3039_玉蟾宫_(动态规划+悬线法)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=3039 n*m的矩阵由R和F组成,求全是F的子矩阵的大小的三倍. 分析 悬线法: 浅谈用极大化思 ...

  4. PHP imdb类多个跨站脚本漏洞

    漏洞版本: PHP imdb Classes 2-2.1.5 漏洞描述: BUGTRAQ ID: 64542 PHP是一种HTML内嵌式的语言. PHP imdb类2-2.1.5及其他版本在实现上存在 ...

  5. c程序设计语言_习题1-16_自己编写getline()函数,接收整行字符串,并完整输出

    Revise the main routine of the longest-line program so it will correctly print the length of arbitra ...

  6. hdu 4294 数学分析+搜索

    又要开始一段搜索的路程了. 最近看了这题,在网上看到一个结论,任何一个数倍数都能被不超过两个数字组成,假如一个数n个A%x=b,那么必然有m个A%=b那么此时n个A减去m个B就能够被x整除,那么此时就 ...

  7. 谈谈分布式事务之三: System.Transactions事务详解[下篇]

    在前面一篇给出的Transaction的定义中,信息的读者应该看到了一个叫做DepedentClone的方法.该方法对用于创建基于现有Transaction对 象的“依赖事务(DependentTra ...

  8. acm位运算应用 搜索

    acm位运算应用 搜索 搜索    此处不讲题目,只讲位运算是怎样在这些题中实现和应用的.由于搜索题往往是基于对状态的操作,位运算往往特别有效,优化之后的效果可以有目共睹.    例1.POJ 132 ...

  9. ms sql server缓存清除与内存释放

    Sql Server系统内 存管理在没有配置内存最大值,很多时候我们会发现运行Sql Server的系统内存往往居高不下.这是由于他对于内存使用的策略是有多少闲置的内存就占用多少,直到内存使用虑达到系 ...

  10. Unity3d 巫师3Ciri的渲染

    --wolf96 16/10/6