C# MVC 基於From的身份驗證

前言

昨天和一個技術比較好的前輩聊了聊,發現有的時候本身的學習方式有些問題,不知道有沒有和我同樣的越學習越感受到知識的匱乏不過能認識到這個問題的同窗們,也不要太心急路是一步一步走的飯是一口一口吃的認識到錯誤才能更高的改進錯誤,腳踏實地只要有上勁學習的心,終會有所成就。認識到本身薄弱的地方進行學習,要清楚學習的目的呀調理清晰:這個是什麼?爲何要這樣?能解決什麼問題?入正題吧。web

什麼是身份驗證

不少網站都有登陸對話框,讓事先已經註冊的用戶驗證,以便爲他們提供個性化的服務等。能夠把這個過程看做是兩件事情的發生:驗證和受權!登錄的做用是驗證請求登錄的用戶是否合法,而受權則是驗證合法的用戶在請求資源時,根據他們的權限決定是訪問仍是拒絕。瀏覽器

舉個例子:咱們已經在一個網站上登陸了,你剛把網頁關閉發現又要使用這個網站因而乎你又打開了瀏覽器而後輸入了網址,這個時候你發現還要讓你登陸才能進行操做。頻繁的這樣是失去用戶極大的體驗效果因此這個時候就用到了身份驗證。緩存

身份驗證是什麼?驗證和受權。爲何要使用?增強用戶體驗效果。能解決什麼問題?節省用戶時間避免重複性動做。安全

Form身份驗證思路

用戶要瀏覽須要權限的頁面,此時,安全機制先啓動,檢查當前用戶請求是否持有用戶票據的Cookie如此Cookie存在:解析Cookie中的票據信息,得到用戶角色,建立用戶標識或者對象。不然:認爲用戶無權瀏覽該頁面,跳轉至登入頁面,登入成功後重定向到所請求頁面。服務器

創建BaseController

創建BaseController繼承Controller,而後在其餘Controller中用BaseController做爲父類來繼承。咱們在Base中實現From設置Ticket和寫入Cooike信息等操做。cookie

        /// <summary>
        /// 保存用戶登錄信息
        /// </summary>
        public void WriteUserInfoToCookie(UserInfo userinfo)
        {
            var jss = new JavaScriptSerializer();
            var logonInfo = jss.Serialize(userinfo);

            //設置Ticket信息
            var ticket = new FormsAuthenticationTicket(1, userinfo.Name, DateTime.Now,
                                                       DateTime.Now.AddDays(1), false,
                                                       logonInfo);
            //加密驗證票據
            var strTicket = FormsAuthentication.Encrypt(ticket);
            //保存cookie
            SetCookie(FormsAuthentication.FormsCookieName, strTicket, ticket.Expiration, true);
        }

        /// <summary>
        /// 寫入Cooike
        /// </summary>
        /// <param name="cookiename"></param>
        /// <param name="value"></param>
        /// <param name="expires"></param>
        /// <param name="isSetExpires"></param>
        public static void SetCookie(string cookiename, string value, DateTime expires, bool isSetExpires)
        {
            var request = System.Web.HttpContext.Current.Request;
            var response = System.Web.HttpContext.Current.Response;
            var cookie = request.Cookies[cookiename] ?? new System.Web.HttpCookie(cookiename);
            cookie.Domain = FormsAuthentication.CookieDomain;
            if (value == null)
            {
                RemoveCookie(cookiename);
            }
            else
            {
                cookie.Value = value;

                //true表明客戶端只能讀,不能寫。只有服務端可寫,防止被篡改
                cookie.HttpOnly = true;

                if (isSetExpires)
                {
                    cookie.Expires = expires;
                }
            }
            response.Cookies.Add(cookie);
        }

        /// <summary>
        /// 移除指定名稱的cookie對象中的集合對
        /// </summary>
        /// <param name="cookieName">cookie名稱</param>
        public static void RemoveCookie(string cookieName)
        {
            var cookie = System.Web.HttpContext.Current.Request.Cookies[cookieName];
            var response = System.Web.HttpContext.Current.Response;
            if (cookie == null) return;
            cookie.Values.Clear();
            cookie.Domain = FormsAuthentication.CookieDomain;
            cookie.Expires = DateTime.Now.AddDays(-10000d);
            response.Cookies.Add(cookie);
        }

創建實體做爲用戶登陸信息和寫入Cookie

    public class UserInfo
    {
        public string Name { get; set; }

        public string PassWord { get; set; }

    }

配置WebConfig

  <system.web>
    <authentication mode="Forms">
      <forms name="test" protection="All" loginUrl="~/account/default" timeout="2880" />
    </authentication>
  </system.web>

Forms Authentication相關的配置

有些同窗會蒙圈爲啥會配置authentication,下面咱們看下他們的信息
在web.config文件中,<system.web>/<authentication>配置節用於對驗證進行配置。爲<authentication>節點提供mode="Forms"屬性能夠啓用Forms Authentication。一個典型的<authentication>配置節以下所示:less

<authentication mode="Forms">
     <forms
         name=".ASPXAUTH"
         loginUrl="login.aspx"
         defaultUrl="default.aspx"
         protection="All"
         timeout="30"
         path="/"
         requireSSL="false"
         slidingExpiration="false"
         enableCrossAppRedirects="false"
         cookieless="UseDeviceProfile"
         domain=""
     />
</authentication>

以上代碼使用的均是默認設置,換言之,若是你的哪項配置屬性與上述代碼一致,則能夠省略該屬性。例如<forms name="MyAppAuth" />。下面依次介紹一下各類屬性:dom

  • name——Cookie的名字。Forms Authentication可能會在驗證後將用戶憑證放在Cookie中,name屬性決定了該Cookie的名字。經過FormsAuthentication.FormsCookieName屬性能夠獲得該配置值(稍後介紹FromsAuthentication類)。
  • loginUrl——登陸頁的URL。經過FormsAuthentication.LoginUrl屬性能夠獲得該配置值。當調用FormsAuthentication.RedirectToLoginPage()方法時,客戶端請求將被重定向到該屬性所指定的頁面。loginUrl的默認值爲「login.aspx」,這代表即使不提供該屬性值,ASP.NET也會嘗試到站點根目錄下尋找名爲login.aspx的頁面。
  • defaultUrl——默認頁的URL。經過FormsAuthentication.DefaultUrl屬性獲得該配置值。
  • protection——Cookie的保護模式,可取值包括All(同時進行加密和數據驗證)、Encryption(僅加密)、Validation(僅進行數據驗證)和None。爲了安全,該屬性一般從不設置爲None。
  • timeout——Cookie的過時時間。
  • path——Cookie的路徑。能夠經過FormsAuthentication.FormsCookiePath屬性獲得該配置值。
  • requireSSL——在進行Forms Authentication時,與服務器交互是否要求使用SSL。能夠經過FormsAuthentication.RequireSSL屬性獲得該配置值。
  • slidingExpiration——是否啓用「彈性過時時間」,若是該屬性設置爲false,從首次驗證以後過timeout時間後Cookie即過時;若是該屬性爲true,則從上次請求該開始過timeout時間才過時,這意味着,在首次驗證後,若是保證每timeout時間內至少發送一個請求,則Cookie將永遠不會過時。經過FormsAuthentication.SlidingExpiration屬性能夠獲得該配置值。
  • enableCrossAppRedirects——是否能夠將以進行了身份驗證的用戶重定向到其餘應用程序中。經過FormsAuthentication.EnableCrossAppRedirects屬性能夠獲得該配置值。爲了安全考慮,一般老是將該屬性設置爲false。
  • cookieless——定義是否使用Cookie以及Cookie的行爲。Forms Authentication能夠採用兩種方式在會話中保存用戶憑據信息,一種是使用Cookie,即將用戶憑據記錄到Cookie中,每次發送請求時瀏覽器都會將該Cookie提供給服務器。另外一種方式是使用URI,即將用戶憑據看成URL中額外的查詢字符串傳遞給服務器。該屬性有四種取值——UseCookies(不管什麼時候都使用Cookie)、UseUri(從不使用Cookie,僅使用URI)、AutoDetect(檢測設備和瀏覽器,只有當設備支持Cookie而且在瀏覽器中啓用了Cookie時才使用Cookie)和UseDeviceProfile(只檢測設備,只要設備支持Cookie無論瀏覽器是否支持,都是用Cookie)。經過FormsAuthentication.CookieMode屬性能夠獲得該配置值。經過FormsAuthentication.CookiesSupported屬性能夠獲得對於當前請求是否使用Cookie傳遞用戶憑證。
  • domain——Cookie的域。經過FormsAuthentication.CookieDomain屬性能夠獲得該配置值。

驗證Ing

咱們建立個Controller,我創建的是HomeController來進行測試ide

    public class HomeController : BaseCntroller
    {
        public ActionResult Index()
        {
            if (User.Identity.IsAuthenticated)
            {
                var strUser = ((FormsIdentity)User.Identity).Ticket.UserData;
                var _loginInfo = new UserInfo();
                if (strUser.Contains("{") && strUser.Contains("}"))
                {
                    var jss = new JavaScriptSerializer();
                    _loginInfo = jss.Deserialize<UserInfo>(strUser);
                }
                else
                {
                    //或者能夠從緩存裏面取出
                }
                return Json(new { result = true });
            }
            else
            {
                UserInfo user = new UserInfo();
                user.Name = "焦海濤";
                user.PassWord = "123456";
                WriteUserInfoToCookie(user);
            }
            return View();
        }
    }

剛進來咱們能夠看到User的identity是flase說明咱們沒有登陸過。那麼確定是else來進行寫入咱們的信息。學習

設置tick信息而後進行寫入cooike

 

 瀏覽器中能夠看到咱們使用的Cooike,這就是咱們剛剛添加的。

相關文章
相關標籤/搜索