MVC - 身份验证
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 - 身份验证的更多相关文章
- Asp.Net MVC 身份验证-Forms
Asp.Net MVC 身份验证-Forms 在MVC中对于需要登录才可以访问的页面,只需要在对应的Controller或Action上添加特性[Authorize]就可以限制非登录用户访问该页面.那 ...
- MVC身份验证.MVC过滤器.MVC6关键字Task,Async.前端模拟表单验证,提交.自定义匿名集合.Edge导出到Excel.BootstrapTree树状菜单的全选和反选.bootstrap可搜索可多选可全选下拉框
1.MVC身份验证. 有两种方式.一个是传统的所有控制器继承自定义Control,然后再里面用MVC的过滤器拦截.所以每次网站的后台被访问时.就会先走入拦截器.进行前端和后端的验证 一个是利用(MVC ...
- Asp.net Mvc 身份验证、异常处理、权限验证(拦截器)实现代码
本问主要介绍asp.net的身份验证机制及asp.net MVC拦截器在项目中的运用.现在让我们来模拟一个简单的流程:用户登录>权限验证>异常处理 1.用户登录 验证用户是否登录成功步骤直 ...
- MVC身份验证及权限管理
MVC自带的ActionFilter 在Asp.Net WebForm的中要做到身份认证微软为我们提供了三种方式,其中最常用的就是我们的Form认证,需要配置相应的信息.例如下面的配置信息: < ...
- MVC身份验证及权限管理(转载)
from https://www.cnblogs.com/asks/p/4372783.html MVC自带的ActionFilter 在Asp.Net WebForm的中要做到身份认证微软为我们提供 ...
- (转) MVC身份验证及权限管理-2
转自:http://www.cnblogs.com/ldp615/archive/2010/10/27/asp-net-mvc-forms-authentication-roles-authoriza ...
- jwt的ASP.NET MVC 身份验证
Json Web Token(jwt) 一种不错的身份验证及授权方案,与 Session 相反,Jwt 将用户信息存放在 Token 的 payload 字段保存在客户端,通过 RSA 加密 ...
- MVC 身份验证和异常处理过滤器
:在Global中注册为全局过滤器,应用于所有的Controller的Action 参数类均继承自ControllerContext,主要包含属性请求上下文.路由数据.结果 using FilterE ...
- .Net MVC 身份验证
.Net身份验证主要是分为三种 Windows | Forms | Passport ,其中Froms在项目中用的最多. Windows 身份验证 Forms 验证 Passport 验证 1.Win ...
随机推荐
- 将手机micro USB口转换为USB type C连接器的低成本方案
我们知道USB IF提出的type C连接器的终极目标是统一各种USB 接口. 尽管USB 3.0在PC市场上发展的风生水起,但是由于USB 3.0对手机4G LTE的EMI和RFI干扰,导致市场上除 ...
- 如何用AndroidStudio导入github项目
最近一直在研究AndroidStudio,但是总会有这样那样的问题,特别是在github上看到一个很好地开源项目,想clone下来用用,就会出现很多蛋疼的问题,今天摸索着,结合一些大牛们的建议,轻轻松 ...
- Yorhom浅谈:作为一名初中生,自学编程的点点滴滴 - Yorhom's Game Box
Yorhom浅谈:作为一名初中生,自学编程的点点滴滴 我是一名不折不扣的初中生,白天要背着书包去上学,晚上要拿起笔写作业.天天如此,年年如此. 我的爱好很广泛,喜欢了解历史,读侦探小说,骑车,打篮球, ...
- WCF - Architecture
WCF - Architecture WCF has a layered architecture that offers ample support for developing various d ...
- USACO3.22Stringsobits
DP预处理出来 i位不超过j的个数 然后再进行从小到大找第一个比I大的 然后用I减掉上一个比I小的 剩余的按照之前的方法循环找 知道剩余为0 细节挺繁琐的 对照数据改了又改 最后一组数据还超 了int ...
- NOI2010超级钢琴
超级钢琴 [问题描述] 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度 ...
- 【转】使用XCODE 的SOURCE CONTROL 做版本控制 (1)
原文网址:http://it.zhaozhao.info/archives/60469 有一次笔者在开心项目准备尝试新的练习的时候,赫然注意到在选择档案存放位置的时候,下面有个Source Contr ...
- CodeForcesGym 100753B Bounty Hunter II 二分图最小路径覆盖
关键在建图 题解:http://www.cnblogs.com/crackpotisback/p/4856159.html 学习:http://www.cnblogs.com/jackiesteed/ ...
- ms sql server缓存清除与内存释放
Sql Server系统内 存管理在没有配置内存最大值,很多时候我们会发现运行Sql Server的系统内存往往居高不下.这是由于他对于内存使用的策略是有多少闲置的内存就占用多少,直到内存使用虑达到系 ...
- opencv源代码
源代码都在modules文件夹下.搜索一个函数比如dft,在win7下 找到了