[ASP.NET MVC] ASP.NET Identity登入技術剖析

前言

ASP.NET Identity是微軟所貢獻的開源專案,用來提供ASP.NET的驗證、授權等等機制。本篇文章介紹ASP.NET Identity在執行登入功能時,與瀏覽器、還有第三方驗證服務之間的運作流程。主要為自己留個紀錄,也希望能幫助到有需要的開發人員。(本篇內容大幅度簡化了ASP.NET Identity的運作細節,用以傳達登入功能的運作概念。實際ASP.NET Identity在運作的時候,比本篇說明的複雜很多。)

前言01

Unauthorized(未登入)

未登入01

  1. 當使用者使用瀏覽器,第一次進入ASP.NET站台。

  2. 因為還沒有完成登入的動作,所以被ASP.NET判斷為「未登入」。

  3. 這時使用者要求使用的資源,如果是被打上[Authorize]標籤的Controller或是Action。[Authorize]標籤會判別使用者未登入,就回傳HTTP 401狀態碼。

  4. ApplicationCookieMiddleware是一個Identity掛載到ASP.NET的Middleware,這個Middleware會去攔截HTTP 401狀態碼。

    未登入02

  5. ApplicationCookieMiddleware攔截到HTTP 401狀態碼之後,會更改回傳的內容。改為回傳HTTP 302狀態碼以及一個Login頁面的URL。

    未登入03

  6. 瀏覽器接收到HTTP 302狀態碼,會自動跳轉頁面到回傳內容所夾帶的Login頁面URL。

  7. ASP.NET站台會回傳Login頁面給瀏覽器,要求使用者進行登入作業。

Authentication(驗證)

驗證01

  1. 使用者在Login頁面,選擇使用Facebook驗證後,Login頁面會連結到ExternalLogin這個Action。

  2. ExternalLogin在收到使用者選擇使用Facebook驗證後,會回傳一個ChallengeResult, 來引發Challenge。因為使用者是選擇使用Facebook驗證,所以這個Challenge動作會交由FacebookAuthenticationMiddleware來處理。

  3. 接著FacebookAuthenticationMiddleware會發起一個OAuth的流程,來在Facebook站台、使用者瀏覽器之間交換資訊,用以認證一個使用者。(參考資料:OAuth 2.0 筆記 - Yu-Cheng Chuang)

  4. 完成OAuth流程之後,FacebookAuthenticationMiddleware就可以依照取得的使用者資訊,來建立一個FBUser。

  5. FBUser會被拿來做為SignIn動作的參數。這個SignIn動作,會被導到Identity掛載的ExternalCookieMiddleware去執行。

    驗證02

  6. 在ExternalCookieMiddleware裡,會將FBUser編碼為Cookie內容,並且附加到回傳內容裡。

  7. 完成SignIn動作後,FacebookAuthenticationMiddleware會更改回傳的內容。改為回傳HTTP 302狀態碼、編碼為Cookie內容的FBUser、以及一個ExternalLoginCallback URL。

Authorization(授權)

授權01

  1. 瀏覽器接收到HTTP 302狀態碼,會自動跳轉頁面到回傳內容所夾帶的ExternalLoginCallback URL,並且也同時回傳編碼為Cookie內容的FBUser。

  2. ASP.NET會從Cookie內容裡解碼出FBUser,並且依照編碼FBUser為Cookie時的定義,將登入狀態定義為「未登入」。

    授權02

  3. 接著這個FBUser,會被提交給ASP.NET Identity,用以從Identity裡取得系統使用的APPUser。這個APPUser除了使用者相關資料外,也包含了授權給該使用者的Role資料。

  4. APPUser會被拿來做為SignIn動作的參數。這個SignIn動作,會被導到Identity掛載的ApplicationCookieMiddleware去執行。

  5. 在ApplicationCookieMiddleware裡,會將APPUser編碼為Cookie內容,並且附加到回傳內容裡。

  6. 完成SignIn動作後,ASP.NET Identity會更改回傳的內容。改為回傳HTTP 302狀態碼、以及編碼為Cookie內容的APPUser。

Authorized(已登入)

已登入01

  1. 完成上述流程之後。使用者每次使用瀏覽器進入ASP.NET站台時,都會夾帶編碼為Cookie內容的APPUser。

  2. ASP.NET會從Cookie內容裡解碼出APPUser,並且依照編碼APPUser為Cookie時的定義,將登入狀態定義為「已登入」。

    已登入02

  3. 使用者要求使用的資源,如果是被打上[Authorize]標籤的Controller或是Action。[Authorize]標籤會判別使用者已登入,允許並執行功能內容。

  4. ASP.NET站台執行執行功能內容後,會回傳功能頁面給瀏覽器。至此也就完成了,整個ASP.NET Identity登入的流程。

期許自己
能以更簡潔的文字與程式碼,傳達出程式設計背後的精神。
真正做到「以形寫神」的境界。