[转]MVC4项目中验证用户登录一个特性就搞定

来源:互联网 发布:知乎 余建春卡迈克尔数 编辑:程序博客网 时间:2024/04/27 23:40
http://www.cnblogs.com/freeliver54/p/3792410.html
在开发过程中,需要用户登陆才能访问指定的页面这种功能,微软已经提供了这个特性。    // 摘要:    //     表示一个特性,该特性用于限制调用方对操作方法的访问。    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]    public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter但是,美中不足的是,需要微软自带的一些用户验证的东西,比如数据库,配置等等的。常常我们只需要用SESSION或者Cookies去保存用户登录状态的时候,这岂不是杀鸡用牛刀的感觉?那么,我们按照微软官方的这个特性,重写一个属于自己的验证特性类就行了。下面是我常用的自己写的一段代码,希望大家用得开心,如果有异议可以自己修改,代码无版权,哈哈,我们只为共享。下面也提供了一个可以直接引用的DLL,需要.NET 4.0 Framework的支持。下载地址:点击这里下载代码:using System.Web.Mvc;namespace System{    /// <summary>    /// 表示需要用户登录才可以使用的特性    /// <para>如果不需要处理用户登录,则请指定AllowAnonymousAttribute属性</para>    /// </summary>    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]    public class AuthorizationAttribute : FilterAttribute, IAuthorizationFilter    {        /// <summary>        /// 默认构造函数        /// </summary>        public AuthorizationAttribute()        {            String authUrl = System.Configuration.ConfigurationManager.AppSettings["AuthUrl"];            String saveKey = System.Configuration.ConfigurationManager.AppSettings["AuthSaveKey"];            String saveType = System.Configuration.ConfigurationManager.AppSettings["AuthSaveType"];            if (String.IsNullOrEmpty(authUrl))            {                this._AuthUrl = "/User/Login";            }            else            {                this._AuthUrl = authUrl;            }            if (String.IsNullOrEmpty(saveKey))            {                this._AuthSaveKey = "LoginedUser";            }            else            {                this._AuthSaveKey = saveKey;            }            if (String.IsNullOrEmpty(saveType))            {                this._AuthSaveType = "Session";            }            else            {                this._AuthSaveType = saveType;            }        }        /// <summary>        /// 构造函数重载        /// </summary>        /// <param name="loginUrl">表示没有登录跳转的登录地址</param>        public AuthorizationAttribute(String authUrl)            : this()        {            this._AuthUrl = authUrl;        }        /// <summary>        /// 构造函数重载        /// </summary>        /// <param name="loginUrl">表示没有登录跳转的登录地址</param>        /// <param name="saveKey">表示登录用来保存登陆信息的键名</param>        public AuthorizationAttribute(String authUrl, String saveKey)            : this(authUrl)        {            this._AuthSaveKey = saveKey;            this._AuthSaveType = "Session";        }        /// <summary>        /// 构造函数重载        /// </summary>        /// <param name="authUrl">表示没有登录跳转的登录地址</param>        /// <param name="saveKey">表示登录用来保存登陆信息的键名</param>        /// <param name="saveType">表示登录用来保存登陆信息的方式</param>        public AuthorizationAttribute(String authUrl, String saveKey, String saveType)            : this(authUrl, saveKey)        {            this._AuthSaveType = saveType;        }        private String _AuthUrl = String.Empty;        /// <summary>        /// 获取或者设置一个值,改值表示登录地址        /// <para>如果web.config中未定义AuthUrl的值,则默认为/User/Login</para>        /// </summary>        public String AuthUrl        {            get { return _AuthUrl.Trim(); }            set            {                if (String.IsNullOrEmpty(value))                {                    throw new ArgumentNullException("用于验证用户登录信息的登录地址不能为空!");                }                else                {                    _AuthUrl = value.Trim();                }            }        }        private String _AuthSaveKey = String.Empty;        /// <summary>        /// 获取或者设置一个值,改值表示登录用来保存登陆信息的键名        /// <para>如果web.config中未定义AuthSaveKey的值,则默认为LoginedUser</para>        /// </summary>        public String AuthSaveKey        {            get { return _AuthSaveKey.Trim(); }            set            {                if (String.IsNullOrEmpty(value))                {                    throw new ArgumentNullException("用于保存登陆信息的键名不能为空!");                }                else                {                    this._AuthSaveKey = value.Trim();                }            }        }        private String _AuthSaveType = String.Empty;        /// <summary>        /// 获取或者设置一个值,该值表示用来保存登陆信息的方式        /// <para>如果web.config中未定义AuthSaveType的值,则默认为Session保存</para>        /// </summary>        public String AuthSaveType        {            get { return _AuthSaveType.Trim().ToUpper(); }            set            {                if (String.IsNullOrEmpty(value))                {                    throw new ArgumentNullException("用于保存登陆信息的方式不能为空,只能为【Cookie】或者【Session】!");                }                else                {                    _AuthSaveType = value.Trim();                }            }        }        /// <summary>        /// 处理用户登录        /// </summary>        /// <param name="filterContext"></param>        public void OnAuthorization(AuthorizationContext filterContext)        {            if (filterContext.HttpContext == null)            {                throw new Exception("此特性只适合于Web应用程序使用!");            }            else            {                switch (AuthSaveType)                {                    case "SESSION":                        if (filterContext.HttpContext.Session == null)                        {                            throw new Exception("服务器Session不可用!");                        }                        else if (!filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) && !filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true))                        {                            if (filterContext.HttpContext.Session[_AuthSaveKey] == null)                            {                                filterContext.Result = new RedirectResult(_AuthUrl);                            }                        }                        break;                    case "COOKIE":                        if (!filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) && !filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true))                        {                            if (filterContext.HttpContext.Request.Cookies[_AuthSaveKey] == null)                            {                                filterContext.Result = new RedirectResult(_AuthUrl);                            }                        }                        break;                    default:                        throw new ArgumentNullException("用于保存登陆信息的方式不能为空,只能为【Cookie】或者【Session】!");                }            }        }    }}然后在Web.Config文件里面加入下面几句用于配置登陆验证的一些信息:  <appSettings>    <add key="AuthUrl" value="/User/Login" />    <add key="AuthSaveKey" value="LoginedUser" />    <add key="AuthSaveType" value="Session" />  </appSettings>使用实例://...省略引用namespace MrHuo.Framework.Blog{    [Authorization]//如果将此特性加在Controller上,那么访问这个Controller里面的方法都需要验证用户登录状态    public class UserController:Controller    {        [AllowAnonymous]//这里是一个特例,有这个特性,表示这个方法不需要验证用户登录状态        public ActionResult Index()        {            //...省略具体代码        }        //这里的方法需要验证登录状态,以下雷同        public ActionResult Create()        {            //...省略具体代码        }    }} 

评论

#1楼[楼主]   

MVC session过期如何处理跳转 http://www.cnblogs.com/jenney-qiu/archive/2013/07/25/3213928.html以前我们总是会写一个基类也叫父类来判断session是否已过期然后跳转到指定的错误页面或者登陆界面,然后让所有的页面都继承这个基类,但是当我们应用到MVC项目中时,发现该方法并不会起作用。这时我们可以这么做:1.建一个类,如下using System;using System.Web.Mvc;using System.Web.Routing;namespace CheckInManagerSystem.Controllers{public class CheckLogin : ActionFilterAttribute{public override void OnActionExecuting(ActionExecutingContext filterContext){if (filterContext.HttpContext.Session != null){if (filterContext.HttpContext.Session.IsNewSession){var sessionCookie = filterContext.HttpContext.Request.Headers["Cookie"];if ((sessionCookie != null) && (sessionCookie.IndexOf("ASP.NET_SessionId", StringComparison.OrdinalIgnoreCase) >= 0)){filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { Controller = "Account", Action = "LogOff" }));//这里是跳转到Account下的LogOff,自己定义}}}}}} 2.在每个用到session的Action前增加这个[CheckLogin()],如[CheckLogin()]public ActionResult Details(int userid){  ViewDataLoad();return View(_context.GetUserById(userid));}   这样就OK啦!不会再因为session过期而报红页面了!
支持(0)反对(0)
2014-06-17 11:35 | freeliver54  

#2楼[楼主]   

MVC中利用Filter验证用户登录状态 http://blog.csdn.net/xyzqiang/article/details/7327119第一步,建立Filter类[csharp] view plaincopy01.public class CheckinLoginAttribute:ActionFilterAttribute 02. { 03. public override void OnActionExecuting(ActionExecutingContext filterContext) 04. { 05. if (filterContext.HttpContext.Session["user"] == null) 06. { 07. filterContext.HttpContext.Response.Redirect("/User/Login"); 08. } 09. } 10. } 第二步,在需要验证的Action上加上Filter[csharp] view plaincopy01.public class HomeController : Controller 02. { 03. // 04. // GET: /Home/ 05. 06. [CheckinLogin] 07. public ActionResult Index() 08. { 09. return View(); 10. } 11. 12. }
支持(0)反对(0)
2014-06-17 11:36 | freeliver54  

#3楼[楼主]   

http://www.cnblogs.com/ylbtech/archive/2012/08/23/2652394.htmlASP.net MVC 中Security.FormsAuthentication验证用户的状态(匿名|已登录)
支持(0)反对(0)
2014-06-17 14:05 | freeliver54  

#4楼[楼主]   

直接用Response.Redirect("default.aspx")的话当然验证失败,因为你根本没有建立身份验证票。FormsAuthentication.RedirectFromLoginPage方法,会自动完成很多功能的。如完成生成身份验证票,写回客户端,浏览器重定向等一系列的动作。当然完成这些功能并不是只有FormsAuthentication.RedirectFromLoginPage方法才能办到,相反如果需要带角色信息的验证则只能采用其他办法。我门可采用手动添加身份验证票1.FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket (1,"coffee",DateTime.Now, DateTime.Now.AddMinutes(20), false,UserRoles,"/") ;2.加密序列化string HashTicket = FormsAuthentication.Encrypt (Ticket) ;3.生成cookieHttpCookie UserCookie = new HttpCookie(FormsAuthentication.FormsCookieName, HashTicket) ;4.身份验证票Cookie输出到客户端Response.Cookies.Add(UserCookie)5.重定向Response.Redirect (Context.Request["ReturnUrl"]) ; FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, // Ticket versionuserCode, // Username to be associated with this ticketDateTime.Now, // Date/time issuedDateTime.Now.AddMinutes(30), // Date/time to expiretrue, // "true" for a persistent user cookie (could be a checkbox on form)UserPrincipal.CreateUserData(staffId), // User-data (the roles from the user record)FormsAuthentication.FormsCookiePath);// Hash the cookie for transport over the wirestring hash = FormsAuthentication.Encrypt(ticket);HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, // Name of auth cookiehash); // Hashed ticket// Add the cookie to the list for outbound responseResponse.Cookies.Add(cookie);Response.Redirect(this.Request.QueryString["ReturnUrl"]);
支持(0)反对(0)
2014-06-27 17:31 | freeliver54  
复制代码
0 0