文章出處

  Membership 三步曲之入門篇 - Membership基礎示例

  1. Membership三步曲之入門篇 -  Membership基礎示例
  2. Membership三步曲之進階篇 -  深入剖析Provider model
  3. Membership三步曲之高級篇 -  從Membership 到 .NET 4.5 之 AspNet.Identity

  Membership是ASP.NET為我們提供的一套驗證和存儲用戶憑證的框架。它可以幫助我們快速的開發用戶登錄、管理以及權限驗證相關的模塊,很多人可能會說Membership開發起來確實很快,但是總是和需求有那么一點不匹配,那我們就要用到Membership的自定義擴展功能了,如果真正掌握了Membership的話,對于我們快速開發還是有很大幫助的,更重要的是Membership是一套可靈活擴展的框架,包括里面的Provider模型對于想學習架構的同學來說是一個不錯的案例,那么接下來我們就來一步一步的看看Membership是如何做到的。 

  入門篇會從0開始將Membership集成到一個空的MVC站點中,并且與ASP.NET的權限管理體系相結合。進階篇將剖析Membership的設計理念以及它的結構。高級篇我們將會擴展自己的MembershipProvider和RolesProvider,目地是直接利用我們老系統中已經存在的用戶表和角色表,也就是用我們已經存在的數據庫去集成Membership。

  注意:使用VS2012建立一個Internet的MVC項目,會直接幫助我們生成一個已經集成好Membership的一個項目。但是我們會從頭開始自己把Membership加入到一個空的項目中,這樣更有利于我們理解它的工作原理 :)。

目錄

  1. Membership類成員介紹
  2. 集成Membership到ASP.NET MVC網站中
  3. 為Membership啟用角色管理

Membership類成員介紹

  一般來講我們的網站要實現的與用戶相關的最基本功能包括:注冊,登錄,修改用戶資料和密碼。Membership為我們提供了以下幾個類來幫助我們完成這些功能。

  在System.Web.Security的命名空間包含了上圖中的8個類,但是實際上我們只需要Membership一個類就可以幫助我們完成大部份的功能。接下來我們就來一步一步的將Membership集成到我們的MVC站點中去。

集成Membership到ASP.NET MVC網站中

  這里我們的需求很簡單,只是要實現一個包含注冊、登錄、以及修改密碼功能的網站就可以了。我們接下來要做的就是建立一個基本的MVC站點,然后再配置Membership,加上我們的功能代碼。

2.1 新建一個基本的MVC站點

  

  

  我們的站點默認已經啟用Forms認證,如果不了解Foms的話,園子里面有一篇比較好的文章,我已經加上鏈接了。但是Forms有安全方面的隱患,這個系列的后面我們會對比各種認證方式,有興趣的同學請繼續關注。

  同時,還為我們默認配置了一個MembershipProvider(我們下面會說這個東西,這里暫時忽略也沒有關系)

2.2 添加功能代碼

  雖然說我們建立的這個項目已經配置好了Membership,但是并沒有地方去使用它。我們沒有Controller也沒有View。所以接下來我們就要開始加入調用Membership的代碼了。

  首先我們在Layout里面加上三個鏈接:Register, Login, 如果已經登錄的話我們就顯示用戶名和LogOff。 

  當然我們還得加上HomeController并且添加一個默認的Index Action。然后我們再加上AccountController并且添加4個Action(Login和Register的Get、Post版本),View的代碼我就不貼了,大家可以到未尾下載整個項目的源碼。

  登錄代碼

public ActionResult Login()
{
    return View();
}

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
    // Membership.ValidateUser 判斷用戶名和密碼是否正確
    if (ModelState.IsValid && Membership.ValidateUser(model.UserName, model.Password))
    {
        // 調用Forms 的登錄 User.Identity.IsAuthenticated 將設置為True
        // User.Identity.Name 會設置成我們下面的UserName
        FormsAuthentication.SetAuthCookie(model.UserName, false);
        return RedirectToLocal(returnUrl);
    }

    ModelState.AddModelError("", "The user name or password provided is incorrect.");
    return View(model);
}

   注冊相關代碼

public ActionResult Register()
{
    return View();
}

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterModel model)
{
    if (ModelState.IsValid)
    {
        try
        {   
            // Membership.CreateUser去創建用戶
            var user = Membership.CreateUser(model.UserName, model.Password);
            if (user != null)
            {
                //注冊完成之后直接登錄用戶
                FormsAuthentication.SetAuthCookie(user.UserName, false);
            }
            return RedirectToAction("Index", "Home");
        }
        catch (MembershipCreateUserException e)
        {
            ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
        }
    }
    return View(model);
}

   登出相關代碼

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
    FormsAuthentication.SignOut();
    return RedirectToAction("Index", "Home");
}

  修改密碼相關代碼

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
    FormsAuthentication.SignOut();
    return RedirectToAction("Index", "Home");
}

[Authorize]
public ActionResult Manage()
{
    return View();
}

/**************************************************/
/*注意我們為Manage這兩個Action加上了Authorize標簽,只有登錄過的用戶才能訪問
  如果用戶沒有登錄直接訪問/Account/Manage會被跳到/Account/Login要求登錄*/

[Authorize]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Manage(LocalPasswordModel model)
{
    if (ModelState.IsValid)
    {
        bool changePasswordSucceeded;
        try
        {
            var user = Membership.GetUser(User.Identity.Name);
            changePasswordSucceeded = user.ChangePassword(model.OldPassword,
                model.NewPassword);
        }
        catch (Exception)
        {
            changePasswordSucceeded = false;
        }

        if (changePasswordSucceeded)
        {
            return RedirectToAction("Manage", new { Message = "修改密碼成功!"});
        }
        else
        {
            ModelState.AddModelError("", "老密碼不正確或新密碼不符合要求");
        }
    }
    return View(model);
}

  就是這么簡單,我們的注冊,登錄,以及修改密碼功能就完成了。

  來看一下我們用到了哪些Membership的功能:

  • Membership.ValidateUser 驗證用戶名和密碼實現登錄 
  • Membership.CreateUser 創建新用戶
  • Membership.GetUser 獲取用戶
  • MembershipUser.ChangePassword 修改密碼

  還有更多的方法我們可以使用,在最上面的表中我們已經列出來了,大家可以自行嘗試。這些功能都出來以后,我們還有一個疑問沒有解答,那就是我們的用戶保存到哪里去了? 

  Membership的配置節點中有一個connctionStringName的屬性,可以指定我們的數據庫連接字符串。那我們就來看一下它都幫我們搞了一個什么樣的數據庫。注:這個數據庫是Membership幫我們生成的,我之前并沒有創建它,也就是我們只需要寫好連接字符串就可以了。

  而我們的用戶信息就保存在Users表和Memberships表中。

為Membership啟用角色管理

  我們已經完成了登錄、注冊和修改密碼的功能。登錄屬性認證的范疇,而與認證如影隨形的還是授權。通俗的講,認證是看這個用戶是不是合法的,像一扇門,你放不放穿上用戶進來。而授權是在他進來之后能夠干什么,他可以坐在椅子上,但絕對不能坐在你頭上,又或者你只允許你爸或者你老婆坐在你頭上,這就是授權了。

  相信很多人都自己寫過權限相關的代碼,也有人會寫出一套權限管理的框架來。其實ASP.NET已經有一套比較成熟的權限體系,加上它的自定義功能基本可以滿足我們大多數的需求了。

  在我們創建這個MVC站點的時候,VS也為我們配置了權限模塊。就在挨著membership結點的下方:

  因為我們這里面的連接字符串與我們的membersihp中用到的是同一個,所以和權限相關的表Roles、UserInRoles也創建到了同一個數據庫中。不一樣的是我們不需要寫一行代碼就可以完成角色管理的功能,包括創建/修改/刪除角色,以及給用戶賦予角色。

  通過項目->ASP.NET 配置就可以打開這個小網站去管理我們的角色(抱歉,我用的英文版 - -! )。

  我們可以點擊Security(安全)到管理用戶和角色的地頁面。

我們先添加3個角色:Admin, Manager, User

然后我們就可以給我們的用戶賦予角色了。

  接下來我們就可以在代碼中使用User.IsInRole方法是看用戶是否具有某一個角色的權限了。在MVC的Action上我們可以直接在Authorize標簽中指定某個角色,那么這個Action就只有這個角色下的用戶才能夠訪問了。

[Authorize(Roles="Admin")]
public ActionResult Manage()
{
    return View();
}

  我們還可以通過調用Roles.GetRolesForUser將這個用戶相關的角色的都取出來。

  現在我們就已經為我們的網站添加認證和授權模塊了,分分搞定啊!功能是完成了,但是還留下了不少的問題需要解決,因為大多數情況下我們的User表都不會這么簡單,要多加一些字段怎么辦? 我們使用了EF需要使用User entity怎么辦?又或者角色是有父子關系的又該如何做呢?我們后面的進階篇將會告訴你答案。

  Demo下載:http://pan.baidu.com/s/1gduY5CR (你點或不點,推薦按鈕就在右下角 !)


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()