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

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过期而报红页面了!
2014-06-17 11:35 |  freeliver54   

#2楼[楼主]   

MVC中利用Filter验证用户登录状态  http://blog.csdn.net/xyzqiang/article/details/7327119 第一步,建立Filter类 [csharp] view plaincopy 01.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 plaincopy 01.public class HomeController : Controller  02. {  03. //  04. // GET: /Home/  05.  06. [CheckinLogin]  07. public ActionResult Index()  08. {  09. return View();  10. }  11.  12. }
2014-06-17 11:36 |  freeliver54   

#3楼[楼主]   

http://www.cnblogs.com/ylbtech/archive/2012/08/23/2652394.html ASP.net MVC 中Security.FormsAuthentication验证用户的状态(匿名|已登录)
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.生成cookie HttpCookie UserCookie = new HttpCookie(FormsAuthentication.FormsCookieName, HashTicket) ; 4.身份验证票Cookie输出到客户端 Response.Cookies.Add(UserCookie) 5.重定向 Response.Redirect (Context.Request["ReturnUrl"]) ;  FormsAuthenticationTicket ticket = new FormsAuthenticationTicket( 1, // Ticket version userCode, // Username to be associated with this ticket DateTime.Now, // Date/time issued DateTime.Now.AddMinutes(30), // Date/time to expire true, // "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 wire string hash = FormsAuthentication.Encrypt(ticket); HttpCookie cookie = new HttpCookie( FormsAuthentication.FormsCookieName, // Name of auth cookie hash); // Hashed ticket // Add the cookie to the list for outbound response Response.Cookies.Add(cookie); Response.Redirect(this.Request.QueryString["ReturnUrl"]);
2014-06-27 17:31 |  freeliver54   
复制代码
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值