.NET mvc实现登陆

1.检测未登陆跳转登陆页面

重写AuthorizeAttribute类

这里主要用到两个方法:web

  • HandleUnauthorizedRequest :处理未能受权的 HTTP 请求。
  • AuthorizeCore:经过上下文检查用户是否受权

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
namespace NewsPublish.Common
{
    public class MvcAuthorizeAttribute : AuthorizeAttribute
    {

        //
        // 摘要:
        // 处理未能受权的 HTTP 请求。
        //
        // 参数:
        // filterContext:
        // 封装有关使用 System.Web.Mvc.AuthorizeAttribute 的信息。filterContext 对象包括控制器、HTTP 上下文、请求上下文、操做结果和路由数据。
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            var routeValue = new RouteValueDictionary {
                { "Controller", "Home"},
                { "Action", "Login"}
            };
            filterContext.Result = new RedirectToRouteResult(routeValue);
        }


        // 摘要:
        // 重写时,提供一个入口点用于进行自定义受权检查。
        //
        // 参数:
        // httpContext:
        // HTTP 上下文,它封装有关单个 HTTP 请求的全部 HTTP 特定的信息。
        //
        // 返回结果:
        // 若是用户已通过受权,则为 true;不然为 false。
        //
        // 异常:
        // T:System.ArgumentNullException:
        // httpContext 参数为 null。
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            //调用基类的次方法检查若是用户已通过受权,则为 true;不然为 false。
            if (base.AuthorizeCore(httpContext))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }     
}

2.处理登陆请求

(1)建立登陆基类

public class LoginBase
    {
        public int ID { get; set; }
        public string UserName { get; set; }
        public string UserCode { get; set; }
        public string AuthToken { get; set; }
    }

(2)登陆判断函数

[HttpPost]
        public JsonResult doLogin()
        {
            bool bSuccess = false;
            string strMes = string.Empty;
            var username = Request.Form["username"].ToString();
            var Password = Request.Form["Password"].ToString();
            var Db = DBhelper.QueryDB();
            //用户名密码检查
            if (String.IsNullOrEmpty(username) || String.IsNullOrEmpty(Password))
            {
                bSuccess = false;
                strMes = "登录失败,用户名或者密码为空";
                return Json(new { success = bSuccess, message = strMes });
            }

            //用户名密码验证
            string strSql = string.Format(@"select * from db_users where username='{0}' and password='{1}'", username, EncryptHelper.MD5(Password));
            var result = Db.Sql(strSql).QuerySingle<NewsPublish.Areas.Admin.Models.db_users>();

            //验证密码
            if (result == null || String.IsNullOrEmpty(result.username))
            {
                bSuccess = false;
                strMes = "登录失败,用户名或者密码错误";
                return Json(new { success = bSuccess, message = strMes });
            }

            //调用框架中的登录机制
            var loginer = new LoginerBase() { username = result.username,  ID=result.id };

            var effectiveHours = ConfigHelper.GetConfigInt("LoginEffectiveHours", 8);
            if (Request.Form["remember"] == null)
            {
                effectiveHours = 0;
            }
            FormsAuth.SignIn(loginer, 60 * effectiveHours);

            //登录后处理
            //strSql = string.Format(@"update db_users set LoginCount=LoginCount+1,LastLoginDate='{0}' where ID='{1}'", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), result.id);
            //Db.Sql(strSql).Execute();

            bSuccess = true;
            strMes = "登陆成功,页面跳转中……";
            return Json(new { success = bSuccess, message = strMes });
        }

(3)登陆受权函数

public static void SignIn(LoginerBase loginer, int expireMin)
        {
            var loginName = loginer.username;
            loginer.AuthToken = GetToken(loginName);
            var data = JsonConvert.SerializeObject(loginer);

            //建立一个FormsAuthenticationTicket,它包含登陆名以及额外的用户数据。
            var ticket = new FormsAuthenticationTicket(2,
                loginName, DateTime.Now, DateTime.Now.AddDays(1), true, data);

            //加密Ticket,变成一个加密的字符串。
            var cookieValue = FormsAuthentication.Encrypt(ticket);

            //根据加密结果建立登陆Cookie
            var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, cookieValue)
            {
                HttpOnly = true,
                Secure = FormsAuthentication.RequireSSL,
                Domain = FormsAuthentication.CookieDomain,
                Path = FormsAuthentication.FormsCookiePath
            };
            if (expireMin > 0)
                cookie.Expires = DateTime.Now.AddMinutes(expireMin);

            var context = HttpContext.Current;
            if (context == null)
                throw new InvalidOperationException();

            //写登陆Cookie
            context.Response.Cookies.Remove(cookie.Name);
            context.Response.Cookies.Add(cookie);
        }

将cookies写入context中上下文,就能够判断是否受权成功了cookie

(4)在配置文件中添加配置

<authentication mode="Forms">
      <forms loginUrl="~/Admin/Login" cookieless="UseCookies" />
    </authentication>

(5)设置须要验证登陆的controller

  • 能够直接在controller方法上面加上 [Authorize] 表示只验证次方法
  • 在FilterConfig中添加配置 filters.Add(new MvcAuthorizeAttribute());表示给项目中全部须要验证的方法加上验证。
  • 在特定方法前加[AllowAnonymous]能够跳过验证

3.退出登陆(清除受权)

public static void SingOut()
        {
            FormsAuthentication.SignOut();
        }

这种方法如今只适合mvc4或如下版本,mvc5中亲测不可用,方法还在研究中。。。。。