<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      ASP.NET MVC 4 (十三) 基于表單的身份驗(yàn)證

      在前面的章節(jié)中我們知道可以在MVC應(yīng)用程序中使用[Authorize]特性來限制用戶對(duì)某些網(wǎng)址(控制器/控制器方法)的訪問,但這都是在對(duì)用戶認(rèn)證之后,而用戶的認(rèn)證則依然是使用ASP.NET平臺(tái)的認(rèn)證機(jī)制。

      ASP.NET提供Windows和Forms兩種身份驗(yàn)證,前者主要用于Intranet上域環(huán)境內(nèi),后者則更多的應(yīng)用于Internet,這里我們只討論后者。先從最簡單的例子開始,我們?cè)趙eb.config中配置Forms認(rèn)證方式:

      ... 
      <authentication mode="Forms"> 
        <forms loginUrl="~/Account/Login" timeout="2880"> 
          <credentials passwordFormat="Clear"> 
            <user name="admin" password="secret" /> 
          </credentials> 
        </forms> 
      </authentication> 
      ... 

      這里設(shè)置認(rèn)證方式為Forms,用戶登錄的地址為~/Account/Login,我們用最簡單的方式創(chuàng)建用戶信息,在credentials節(jié)中直接設(shè)置用戶名稱/密碼。在創(chuàng)建頁面之前我們先創(chuàng)建收集用戶名和密碼Model類:

      using System.ComponentModel.DataAnnotations;
      
      namespace SportsStore.WebUI.Models {
      
          public class LoginViewModel {
              [Required]
              public string UserName { get; set; }
      
              [Required]
              [DataType(DataType.Password)]
              public string Password { get; set; }
          }
      }

      創(chuàng)建一個(gè)視圖來收集用戶名和信息:

      @model SportsStore.WebUI.Models.LoginViewModel
      
      @{
          ViewBag.Title = "Admin: Log In";
          Layout = "~/Views/Shared/_AdminLayout.cshtml";
      }
      
      <h1>Log In</h1>
      
      <p>Please log in to access the administrative area:</p>
      @using(Html.BeginForm()) {
          @Html.ValidationSummary(true)
          @Html.EditorForModel()
          <p><input type="submit" value="Log in" /></p>
      }

      最后還需要在Account控制器的Login action中處理用戶提交的用戶名和密碼完成用戶認(rèn)證:

      [HttpPost]
              public ActionResult Login(LoginViewModel model)
              {
      
                  if (ModelState.IsValid)
                  {
                      bool result = FormsAuthentication.Authenticate(model.UserName, model.Password);
                      if (result)
                      {
                          FormsAuthentication.SetAuthCookie(model.UserName, false);
                          return Redirect(Url.Action("Index", "Admin"));
                      }
                      else
                      {
                          ModelState.AddModelError("", "Incorrect username or password");
                          return View();
                      }
                  }
                  else
                  {
                      return View();
                  }
              }

      調(diào)用FormsAuthentication.Authenticate()對(duì)用戶名和密碼驗(yàn)證,如何驗(yàn)證成功,調(diào)用FormsAuthentication.SetAuthCookie()設(shè)置用戶驗(yàn)證的cookie并在響應(yīng)中返回,在cookie過期之前用戶再次訪問時(shí)不再要求登錄。

      以上就是最簡單的Forms身份驗(yàn)證過程,但實(shí)際的Internet應(yīng)用用戶的信息一般存儲(chǔ)在數(shù)據(jù)庫中,通過Membership provider利用數(shù)據(jù)庫中的信息對(duì)用戶驗(yàn)證,MVC4中微軟為我們提供SQL membership provider、Universal membership provider和Simple membership provider,下面來看看如何具體如何使用它們。

      SQL membership provider

      在.NET 2.0中SQL membership provider就已經(jīng)存在了,在visual studio 2012中使用empty模板創(chuàng)建一個(gè)MVC4的工程,web.config你不會(huì)看到任何membership provider相關(guān)的信息,默認(rèn)使用的是Windows認(rèn)證。在VS的Project菜單下打開Asp.net configurtion工具(在打開配置工具前記得編譯下工程,否則會(huì)提示“選定的數(shù)據(jù)存儲(chǔ)區(qū)出現(xiàn)問題”),在“安全”標(biāo)簽頁面點(diǎn)擊“選擇身份驗(yàn)證類型”,配置工具詢問“用戶如何訪問您的站點(diǎn)?”,選擇“通過Internet”,點(diǎn)擊“完成”后配置工具將自動(dòng)在web.config中添加“<authentication mode="Forms" />”。配置工具仍然沒有在web.config添加任何membership provider的信息,但是我們轉(zhuǎn)到配置工具的“提供程序頁面”,可以看到看到默認(rèn)選中的是AspNetSqlMembershipProvider,同時(shí)配置工具會(huì)在工程的app_data目錄下創(chuàng)建一個(gè)名為ASPNETDB.MDF的數(shù)據(jù)庫,這是一個(gè)sql express的數(shù)據(jù)庫,visual studio 2012中不能直接打開(VS用的是localdb),可以在SQL管理工具中附加到SQL EXPRESS的服務(wù)實(shí)例來查看。打開數(shù)據(jù)庫可以看到數(shù)據(jù)庫中添加了很多“aspnet_”為前綴的表和存儲(chǔ)過程,這些都是SqlMembershipProvider需要的。

      如果我們要使用自建的數(shù)據(jù)庫來保存用戶信息改如何操作呢?我們?cè)赟olution exploer中點(diǎn)擊App_Start目錄,右鍵菜單中選擇添加->添加項(xiàng)目->SQL數(shù)據(jù)庫創(chuàng)建一個(gè)localdb的數(shù)據(jù)庫,添加相應(yīng)的Connection字符串到web.config:

      <connectionStrings>
          <add name="DefaultConnection" connectionString="Data Source=(localdb)\v11.0;AttachDbFileName=|DataDirectory|\mvc4empty.mdf;Initial Catalog=mvc4empty;Integrated Security=True"
            providerName="System.Data.SqlClient"/>
        </connectionStrings>

      我們還需要在web.config手工添加SqlMembershipProvider,讓它使用上面的數(shù)據(jù)庫連接:

      <membership defaultProvider="mySqlMembershipProvider">
            <providers>
              <clear />
              <add connectionStringName="DefaultConnection" enablePasswordRetrieval="false"
                enablePasswordReset="true" requiresQuestionAndAnswer="false"
                applicationName="/" requiresUniqueEmail="false" passwordFormat="Hashed"
                passwordStrengthRegularExpression="" name="mySqlMembershipProvider"
                type="System.Web.Security.SqlMembershipProvider" />
            </providers>
          </membership>

      再次打開asp.net配置工具轉(zhuǎn)到安全界面會(huì)提示錯(cuò)誤“Could not find stored procedure 'dbo.aspnet_CheckSchemaVersion'”,配置工具試圖調(diào)用相關(guān)的存儲(chǔ)過程,但是數(shù)據(jù)庫是我們手工創(chuàng)建的,不包含這些過程和數(shù)據(jù)表。我們可以使用aspnet_regsql.exe工具在我們的數(shù)據(jù)庫中創(chuàng)建相關(guān)表和數(shù)據(jù),C:\Windows\Microsoft.NET\Framework64\v4.0.30319和C:\Windows\Microsoft.NET\Framework64\v2.0.50727都有這個(gè)工具,沒有細(xì)究兩個(gè)版本的不同,這里使用.NET 4.0的版本。在aspnet_regsql工具選擇服務(wù)器為“(localdb)\v11.0”,數(shù)據(jù)庫列表中如果找不到新建的數(shù)據(jù)庫,可以事先在sql manage studio中連接到服務(wù)引擎“(localdb)\v11.0”后附加該數(shù)據(jù)庫(aspnet_reqsql也支持使用連接字符串作為參數(shù),參見http://msdn.microsoft.com/en-us/library/ms229862(v=vs.100).aspx)。完成上述操作后,asp.net配置工具就可以在我們的數(shù)據(jù)庫中創(chuàng)建管理用戶了。

      準(zhǔn)備好Forms認(rèn)證的配置,我們繼續(xù)完善上面的例子,從控制器開始:

      using System;
      using System.Web.Mvc;
      using System.Web.Security;
      using SportsStore.WebUI.Models;
      
      namespace SportsStore.WebUI.Controllers
      {
      
          public class AccountController : Controller
          {
              public ViewResult Login(string returnUrl = null)
              {
                  ViewBag.ReturnUrl = returnUrl;
                  return View();
              }
      
              [HttpPost]
              public ActionResult Login(LoginViewModel model, string returnUrl)
              {
                  if (!ModelState.IsValid) return View();
                  var result = Membership.ValidateUser(model.UserName, model.Password);
                  if (result)
                  {
                      FormsAuthentication.SetAuthCookie(model.UserName, false);
                      return Redirect(returnUrl ?? Url.Action("Index", "Home"));
                  }
                  ModelState.AddModelError("", "Incorrect username or password");
                  return View();
              }
      
              public ActionResult Logout(string returnUrl)
              {
                  FormsAuthentication.SignOut();
                  return Redirect(returnUrl ?? Url.Action("Index", "Home"));
              }
              
              public ViewResult Register()
              {
                  return View();
              }
      
              [HttpPost]
              public ViewResult Register(LoginViewModel model)
              {
                  if (!ModelState.IsValid) return View(model);
                  try
                  {
                      Membership.CreateUser(model.UserName, model.Password);
                      ViewBag.Registered = true;
                  }
                  catch (Exception exception)
                  {
                      ModelState.AddModelError("",exception.Message);
                  }
                  return View(model);
              }
          }
      }

      在用戶登錄時(shí)不再使用FormsAuthentication.Authenticate()認(rèn)證用戶,它僅讀取web.config中credentials節(jié)的內(nèi)容,我們需要改用Membership.ValidateUser()對(duì)用戶密碼校驗(yàn)。調(diào)用FormsAuthentication.SignOut()登出用戶,它清除認(rèn)證相關(guān)的cookie。Register() action用于創(chuàng)建用戶,它調(diào)用Membership.CreateUser()創(chuàng)建一個(gè)用戶保存到數(shù)據(jù)庫中,對(duì)應(yīng)的Register視圖:

      @model SportsStore.WebUI.Models.LoginViewModel
      
      @{
          ViewBag.Title = "User: Register";
          Layout = "~/Views/Shared/_AdminLayout.cshtml";
      }
      
      <h1>User register</h1>
      @if (ViewBag.Registered != null && ViewBag.Registered)
      {
          <p>User "@Model.UserName" has been created sucessfully!</p>
      }
      else
      {
          <p>Please input user name and password to register:</p>
          using (Html.BeginForm())
          {
          @Html.ValidationSummary(true)
          @Html.EditorForModel()
          <p>
              <input type="submit" value="Register" /></p>
          }
      }

      作為示例這里簡單的收集用戶名和密碼,成功注冊(cè)后給出提示,Html.ValidationSummary()顯示發(fā)生的錯(cuò)誤發(fā)生,比如用戶名已經(jīng)存在。我們可以在布局文件中創(chuàng)建一些鏈接關(guān)聯(lián)到用戶注冊(cè)、登出:

      ...
      <div>
                  @if (User.Identity.IsAuthenticated)
                  {
                      <p>Current user:@User.Identity.Name</p>
                      @Html.RouteLink("Logout",new {Controller="Account",Action="Logout",returnUrl=Request.Url.PathAndQuery})
                  }
                  else
                  {
                      <span>@Html.RouteLink("Login",new {Controller="Account",Action="Login",returnUrl=Request.Url.PathAndQuery})</span>
                      <span>@Html.ActionLink("Register","Register","Account")</span>
                  }
              </div>
              <div>
                  @if (User.IsInRole("Admin"))
                  {
                      @Html.ActionLink("Administrate", "Index", "Admin")
                  }
              </div>
      ...

       

      Universal provider

      SQL membership provider要求使用完整安裝的SQL server,使用到很多表和存儲(chǔ)過程,對(duì)SQL server azure、SQL server compact都不支持,于是Universal provider出現(xiàn)了,最早于 2011年發(fā)布。我們可以在VS2012中使用Basic模板創(chuàng)建MVC4工程,工程被配置為默認(rèn)使用Universal provider。我們也可以在nuget包管理器搜索“universal”,找到“Microsoft ASP.NET universal provider”安裝,安裝工具修改web.config配置DefaultMembershipProvider作為默認(rèn)的provider;配置EntityFramework,universal provider使用EntityFramework完成數(shù)據(jù)庫的讀寫;創(chuàng)建一個(gè)SQL express的數(shù)據(jù)庫和連接字符串供universal provider使用。下面是web.config的部分內(nèi)容:

      ...
      <configSections>
          <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
          <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
        </configSections>
      ...
      <profile defaultProvider="DefaultProfileProvider">
            <providers>
              <add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
            </providers>
          </profile>
          <membership defaultProvider="DefaultMembershipProvider">
            <providers>
              <add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" passwordFormat="Hashed" passwordStrengthRegularExpression="" />
            </providers>
          </membership>
          <roleManager defaultProvider="DefaultRoleProvider">
            <providers>
              <add name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
            </providers>
          </roleManager>
          <!--
                  If you are deploying to a cloud environment that has multiple web server instances,
                  you should change session state mode from "InProc" to "Custom". In addition,
                  change the connection string named "DefaultConnection" to connect to an instance
                  of SQL Server (including SQL Azure and SQL  Compact) instead of to SQL Server Express.
            -->
          <sessionState mode="InProc" customProvider="DefaultSessionProvider">
            <providers>
              <add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" />
            </providers>
          </sessionState>
      ....
      
      <entityFramework>
          <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
          <providers>
            <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
          </providers>
        </entityFramework>
      
      ...

      打開asp.net配置工具,可以看到成員資格提供程序有AspNetSqlMembershipProvider和DefaultMembershipProvider供選擇,前者就是sql membership provider,我們我們這時(shí)選擇它,配置工具會(huì)把membership改為:

      <membership>

      defaultProvider特性被刪除,不帶任何的特性,這需要特別注意。

      查看Universal provider生成的數(shù)據(jù)庫,它只包含Users、Roles、Profiles、Memberships、UsersInRoles、Applications幾個(gè)表,而且沒有任何的存儲(chǔ)過程,確實(shí)很多程度上簡化了數(shù)據(jù)庫模型,不再使用存儲(chǔ)過程操作數(shù)據(jù),因此支持的SQL服務(wù)類型也更多。nuget包安裝工具為我們自動(dòng)創(chuàng)建了一個(gè)數(shù)據(jù)庫,如果我們要使用原有的數(shù)據(jù)庫該怎么辦呢?我們只需要改動(dòng)相應(yīng)的連接字符串,編譯后啟動(dòng)asp.net配置工具,它會(huì)在我們?cè)械臄?shù)據(jù)庫中創(chuàng)建上面的幾個(gè)表。

      SQL membership provider一節(jié)示例的的控制器/視圖我們不需要任何改動(dòng)都可以在切換成universal provider后正常運(yùn)行,對(duì)Membership方法的調(diào)用在MVC內(nèi)部轉(zhuǎn)由System.Web.Providers.DefaultProfileProvider,對(duì)我們寫程序講沒有任何不同。這樣講似乎universal provider沒有帶來太多的好處,實(shí)際上隨著數(shù)據(jù)庫結(jié)構(gòu)的簡化,對(duì)我們擴(kuò)展profile等有很大的便利,這里就不再深入討論。

      Simple provider

      simple provider在VS 2010 SP1中隨Webmatrix發(fā)布,和universal provider一樣使用entrity framework操作用戶信息數(shù)據(jù)庫,但是數(shù)據(jù)庫的結(jié)構(gòu)更為簡單也可以更為靈活的配置。在VS2012中我們使用Internet模板創(chuàng)建MVC4的工程,工程被配置為使用simple provider。web.config中只有<authentication mode="Forms">,不再包含membership provider的信息,membership的處理直接在控制器中使用WebMatrix.WebData.WebSecurity處理。Internet模板創(chuàng)建了具備完整用戶功能的代碼,這里不一一列出。

      Internet模板創(chuàng)建一個(gè)名為InitializeSimpleMembershipAttribute的過濾器,它在每次應(yīng)用程序啟動(dòng)時(shí)調(diào)用一次:

      WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);

      這個(gè)方法使初始化用戶信息的數(shù)據(jù)庫連接,DefaultConnection為數(shù)據(jù)庫的連接字符串,Userpofile為表名稱,UserId和UserName分別為用戶ID和用戶名稱在表中的字段名稱,也就是說我們只需要一個(gè)最簡單的有用戶ID和名稱兩個(gè)字段的表就可以了,這個(gè)表可以在任何數(shù)據(jù)庫中,這是可以動(dòng)態(tài)設(shè)置的,所以asp.net的配置工具不能用于配置simple provider。

      Internet模板創(chuàng)建Account控制器,包含眾多action方法用于提供用戶注冊(cè)、登錄、登出、修改密碼,基本上都是調(diào)用WebSecurity的相關(guān)方法來實(shí)現(xiàn)的,比如登錄調(diào)用的是WebSecurity.Login()。在Internet模板的基礎(chǔ)上,我們可以很方便的自定義profile、roles等,這里也不再深入,已經(jīng)有一篇很好的文章講解simple provider如何工作,可以參見http://weblogs.asp.net/jgalloway/archive/2012/08/29/simplemembership-membership-providers-universal-providers-and-the-new-asp-net-4-5-web-forms-and-asp-net-mvc-4-templates.aspx

       

      MVC5已隨VS2013在2013十月發(fā)布,相對(duì)于MVC4有了很多的變化,包括這里所講的安全認(rèn)證。就以本文結(jié)束MVC4,開始MVC5之旅。

      posted @ 2016-09-02 22:32  閆寶平  閱讀(932)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 精品中文人妻在线不卡| www国产成人免费观看视频| 丰满人妻被黑人猛烈进入| 玩弄漂亮少妇高潮白浆| 欧美成人片一区二区三区| 成人网站av亚洲国产| 国产欲女高潮正在播放| 国内少妇人妻偷人精品| 小嫩批日出水无码视频免费| 中文字幕日韩国产精品| av无码一区二区大桥久未| 97久久超碰精品视觉盛宴| 94人妻少妇偷人精品| 邮箱| 日本一区二区三本视频在线观看| 在线看免费无码av天堂| 在线a级毛片无码免费真人| 亚洲欧洲久久激情久av| 99在线精品视频观看免费| 亚洲熟女乱综合一区二区| 国产精品久久久久久久网| 精品久久一线二线三线区| 国产精品久久一区二区三区| 国产精品69人妻我爱绿帽子| 临海市| 亚洲欧美日韩在线码| 亚洲粉嫩av一区二区黑人| 377p日本欧洲亚洲大胆张筱雨| gogogo高清在线观看视频中文| 午夜天堂av天堂久久久| 亚洲av成人一区二区三区| 香港特级三A毛片免费观看| 97精品伊人久久大香线蕉APP | 在线播放亚洲成人av| 米奇亚洲国产精品思久久| 中文国产成人精品久久不卡| 亚洲综合伊人久久综合| 国产精品人成视频免费国产| 国产三级精品三级在线专区1| 秋霞人妻无码中文字幕| 欧美啪啪网|