2012年11月25日 星期日

ASP.Net MVC中的OAuth

image

         撰寫任何公開的系統都需要有適當的驗證/授權機制作為安全性控管。在ASP.Net MVC 4中,提供了相當完整的機制,除了預設的表單驗證之外,還加入了一個令人振奮的特性-OAuth。而本篇文章將以大家最常會使用到的Facebook作為OAuth的範例作說明。

       打開App_Start底下的AuthConfig.cs這個檔案來看,我們會發現到裡面的內容幾乎全部都被註解了

    public static class AuthConfig
    {

        public static void RegisterAuth()
        {

            // 若要讓此網站的使用者使用其他網站 (如 Microsoft、Facebook 和 Twitter) 的帳戶登入,

            // 您必須更新此網站。如需詳細資訊,請造訪 http://go.microsoft.com/fwlink/?LinkID=252166

            //OAuthWebSecurity.RegisterMicrosoftClient(

            //    clientId: "",

            //    clientSecret: "");

            //OAuthWebSecurity.RegisterTwitterClient(

            //    consumerKey: "",

            //    consumerSecret: "");

            //OAuthWebSecurity.RegisterFacebookClient(

            //    appId: "",

            //    appSecret: "");

            //OAuthWebSecurity.RegisterGoogleClient();
        }
    }
 
從註解的內容我們發現到一個事實,RegisterAuth這個靜態方法的內容具有四個很快就被人觀注的四個東西:
  • RegisterMicrosoftClient
  • RegisterTwitterClient
  • RegisterFacebookClient
  • RegisterGoogleClient
     從上述所列的名稱可以更進一步推敲,這似乎是在針對目前時下最廣為大家使用的四個社群網站:Microsoft, Twitter, Facebook, Google。再來我們回到這些方法的類別: OAuth。
OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。
      上述是我引用Wiki對於OAuth的描述,老實說,我還真是看不太懂它的內容。吐舌頭不過我們可以使用另一種較快速吸收的方式來解釋它:利用目前現成的社群網站所提供的驗證服務來對使用者進行驗證。當然,OAuth所提供的能力當然不僅僅於此,甚至可以說,用了它之後就可以對使用者提供更多的服務,例如像是可以取得使用者在Facebook上的一些資訊,而這些資訊可以讓網頁呈現的更豐富也更能讓使用者快速上手,畢竟使用者已經很習慣Facebook的操作介面或是資料呈現,如果自己所提供的網站與Facebook有更多的重疊性,就能提高使用者的接受度。

    在本篇文章中,主要針對的部份是驗證/授權,因此,所需要涵蓋的範圍也比較廣,除了要介紹AuthConfig.cs中的內容之外,也必需要介紹Controllers資料夾底下的AccountController。首先先來看一下AccountController在處理表單驗證的部份。

[Authorize]
    [InitializeSimpleMembership]
    public class AccountController : Controller
    {
        //
        // GET: /Account/Login

        [AllowAnonymous]
        public ActionResult Login(string returnUrl)
        {

            …省略…
        }

        //
        // POST: /Account/Login
        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public ActionResult Login(LoginModel model, string returnUrl)
        {

            …省略…
        }

        //
        // POST: /Account/LogOff
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult LogOff()
        {
            …省略…}

        //
        // GET: /Account/Register
        [AllowAnonymous]
        public ActionResult Register()
        {
           …省略…        
        }

        //
        // POST: /Account/Register
        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public ActionResult Register(RegisterModel model)
        {
            …省略…
        }

        //
        // POST: /Account/Disassociate
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Disassociate(string provider, string providerUserId)
        {
            …省略…
        }

        //
        // GET: /Account/Manage
        public ActionResult Manage(ManageMessageId? message)
        {
            …省略…        
        }

        //
        // POST: /Account/Manage
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Manage(LocalPasswordModel model)
        {
            …省略…
        }

}

        AccountController主要有兩大部份,一個是針對表單驗證的部門,另一個則是針對OAuth驗證的部份,而上述程式碼僅是針對表單驗證的部份。在表單驗證的部份一共有下列方法:
  • Login(登入)
  • LogOff(登出)
  • Register(註冊)
  • Disassociate(刪除帳號與第三方網站的關聯)
  • Manage(變更帳戶密碼)

       某些方法有Get與Post分別,所以會在上述程式碼中看到某幾個方法會重覆出現,但是該重覆的方法會有一個很明顯的特徵就是其方法上頭會有一個[HttpPost]的屬性標籤。MVC4與MVC3在AccountController上有很大的不同,除了多了另一個部份是在處理OAuth之外,方法的屬性標籤也變得更多了,茲羅列MVC4在AccountController用到那些屬性標籤:
  • Authorize(需通過授權才能使用)
  • InitializeSimpleMembership(初始化帳戶管理相關機制)
  • AllowAnonymous(在執行Action時,略過驗證/授權的處理)
  • ValidateAntiForgeryToken(避免CSRF攻擊)
  • ChildActionOnly(不允許使用者直接輸入Url呼叫)

       由上面描述可以看到,在AccountController中有許多的屬性標籤都和安全性息息相關,這樣一來,對於安全性的部份開發人員僅需在自己的Action加上適當的屬性標籤就能具有基本的安全性,不再像過去需要撰寫太多的程式碼在處理安全性相關的議題。

        其中要注意某些屬性標籤對於Get和Post的Http操作是有很大的限制的,舉例來說ValidateAntiforgeryToken這個屬性標籤就無法和Get使用,因此,使用ValidateAntiForgeryToken時,務必要在該Action上加上HttpPost屬性標籤,否則會發生錯誤。

        除了上述的方法概述以及屬性標籤之外,其中較為特別的是方法的內容中有個極其顯眼的類別:WebSecurity,這個類別就像是過去的MemberShip,它們的任務和功用都很單純,全都是帳戶的處理。

        介紹完表單驗證之後,我們再回到本篇文章的主題: OAuth。其實MVC的範本中就有相當豐富的OAuth範例,其中牽涉到的部份除了App_Start下的AuthConfig.cs外,再來就是Controllers中的AccountController了,在AuthConfig.cs中,主要在處理的是與第三方驗證單位的設定,觀其四個方法可以知道分別是不同的第三方單位,僅需選擇其中一個使用就可以了。
  
        點擊這個網址可以連結到Facebook的開發人員中心,但使用前需要進行一連串的註冊動作。(使用前需有Facebook帳號)

        步驟1: 輸入Facebook開發人員專屬特區的名字和名稱空間(這個可不用輸入)
image
       
         步驟2: 輸入安全驗證碼

                 image

         步驟3: 取得"應用程式ID/ API鑰匙",並設定AuthConfig.cs的參數

image
             
          而上面的"應用程式ID / API鑰匙"以及”應用程式密鑰”,記得要複製下來準備貼到App_Start底下的AuthConfig中。

image
   
        將”應用程式ID/ API鑰匙”填入appId(字串型式);將”應用程式密鑰”填入appSecret中(字串型式)。做完這堆事情之後,還得前往Facebook的應用開發中心打開WebSite With Facebook Login這項功能。

         步驟4: 啟用WebSite With Facebook Login

image
 
       點擊編輯應用程式,進入下一個面頁開啟WebSite With Facebook Login功能。

image

        萬事具備,再來就可以直接執行MVC專案並進入登入頁面。

image

        點選右側的Facebook登入按鈕。

image

image

image

總結:OAuth在MVC中相當的方便就能夠達成,可以多多參考MVC中有關註冊的範本。

沒有留言:

張貼留言