前言
ASP.NET Identity是微軟所貢獻的開源專案,用來提供ASP.NET的驗證、授權等等機制。本篇文章介紹ASP.NET Identity在執行登入功能時,與瀏覽器、還有第三方驗證服務之間的運作流程。主要為自己留個紀錄,也希望能幫助到有需要的開發人員。(本篇內容大幅度簡化了ASP.NET Identity的運作細節,用以傳達登入功能的運作概念。實際ASP.NET Identity在運作的時候,比本篇說明的複雜很多。)
Unauthorized(未登入)
-
當使用者使用瀏覽器,第一次進入ASP.NET站台。
-
因為還沒有完成登入的動作,所以被ASP.NET判斷為「未登入」。
-
這時使用者要求使用的資源,如果是被打上[Authorize]標籤的Controller或是Action。[Authorize]標籤會判別使用者未登入,就回傳HTTP 401狀態碼。
-
ApplicationCookieMiddleware是一個Identity掛載到ASP.NET的Middleware,這個Middleware會去攔截HTTP 401狀態碼。
-
ApplicationCookieMiddleware攔截到HTTP 401狀態碼之後,會更改回傳的內容。改為回傳HTTP 302狀態碼以及一個Login頁面的URL。
-
瀏覽器接收到HTTP 302狀態碼,會自動跳轉頁面到回傳內容所夾帶的Login頁面URL。
-
ASP.NET站台會回傳Login頁面給瀏覽器,要求使用者進行登入作業。
Authentication(驗證)
-
使用者在Login頁面,選擇使用Facebook驗證後,Login頁面會連結到ExternalLogin這個Action。
-
ExternalLogin在收到使用者選擇使用Facebook驗證後,會回傳一個ChallengeResult, 來引發Challenge。因為使用者是選擇使用Facebook驗證,所以這個Challenge動作會交由FacebookAuthenticationMiddleware來處理。
-
接著FacebookAuthenticationMiddleware會發起一個OAuth的流程,來在Facebook站台、使用者瀏覽器之間交換資訊,用以認證一個使用者。(參考資料:OAuth 2.0 筆記 - Yu-Cheng Chuang)
-
完成OAuth流程之後,FacebookAuthenticationMiddleware就可以依照取得的使用者資訊,來建立一個FBUser。
-
FBUser會被拿來做為SignIn動作的參數。這個SignIn動作,會被導到Identity掛載的ExternalCookieMiddleware去執行。
-
在ExternalCookieMiddleware裡,會將FBUser編碼為Cookie內容,並且附加到回傳內容裡。
-
完成SignIn動作後,FacebookAuthenticationMiddleware會更改回傳的內容。改為回傳HTTP 302狀態碼、編碼為Cookie內容的FBUser、以及一個ExternalLoginCallback URL。
Authorization(授權)
-
瀏覽器接收到HTTP 302狀態碼,會自動跳轉頁面到回傳內容所夾帶的ExternalLoginCallback URL,並且也同時回傳編碼為Cookie內容的FBUser。
-
ASP.NET會從Cookie內容裡解碼出FBUser,並且依照編碼FBUser為Cookie時的定義,將登入狀態定義為「未登入」。
-
接著這個FBUser,會被提交給ASP.NET Identity,用以從Identity裡取得系統使用的APPUser。這個APPUser除了使用者相關資料外,也包含了授權給該使用者的Role資料。
-
APPUser會被拿來做為SignIn動作的參數。這個SignIn動作,會被導到Identity掛載的ApplicationCookieMiddleware去執行。
-
在ApplicationCookieMiddleware裡,會將APPUser編碼為Cookie內容,並且附加到回傳內容裡。
-
完成SignIn動作後,ASP.NET Identity會更改回傳的內容。改為回傳HTTP 302狀態碼、以及編碼為Cookie內容的APPUser。
Authorized(已登入)
-
完成上述流程之後。使用者每次使用瀏覽器進入ASP.NET站台時,都會夾帶編碼為Cookie內容的APPUser。
-
ASP.NET會從Cookie內容裡解碼出APPUser,並且依照編碼APPUser為Cookie時的定義,將登入狀態定義為「已登入」。
-
使用者要求使用的資源,如果是被打上[Authorize]標籤的Controller或是Action。[Authorize]標籤會判別使用者已登入,允許並執行功能內容。
-
ASP.NET站台執行執行功能內容後,會回傳功能頁面給瀏覽器。至此也就完成了,整個ASP.NET Identity登入的流程。
能以更簡潔的文字與程式碼,傳達出程式設計背後的精神。
真正做到「以形寫神」的境界。