[ASP.NET MVC] 利用OAuth2為網站進行使用者認證的簡單實作

前言:
公司最近打算使用由政府提供的市民登入平台,原因是利用這個平台登入的帳號具有等同自然人的法律效力,其他廠商不用老遠跑來公司簽約可以直接網路上搞定。政府使用的技術是OAuth2認證機制,所以小弟必需被逼研究熟悉整個流程再把公司的系統整合進去。

老實說,Oauth2一開始還真的看得我一頭霧水(霧煞煞),因為OAuth2跟傳統UserName Password的認證方式很不一樣,而且OAuth2在網站上及APP上的實現方法也不同,再加上網路上的圖文說明也很複雜。最後找到神人「鴨七」大大整理出三百多頁的PPT[1]及他在網站上的詳細介紹[2],來回看了幾次終於比較明白整套理論,以下說明是精簡版本,全部概念以網站架構為中心,未必完全適用於APP及Winform:

為什麼要OAuth2?
政府用的是OAuth2小弟又有什麼辦法呢  我個人的看法是使用OAuth2的網站必須先向提供OAuth2的服務提供者進行登記,再加上對用戶的認證以後,就相當於有兩層的保護。再加上網站從頭到尾沒有碰過你的使用者帳號跟密碼,減少被盜取的可能,當然trust機制還是會有很多漏洞,例如User亂授權,不過已經是社交層面了。


OAuth2常用角色

  • Client: 通常是指你自己開發的系統。 
  • Authorization Server: 處理認證、發出access Token的伺服器。
  • Resource Server:保持資源的伺服器,在facebook的例子就是你的個人資料。
  • Resource Owner: 就是人,或者User。 
  • User Agent: 用戶代理,通常指的是Browser。
OAuth2常用術語
  • Client ID and Client secret:
    由於使用OAuth2的Client網站要先向Authorzation Endpoint(OAuth2提供者)進行登記,說明用途及Redirect URL,登記完之後Client ID就像OAuth2提供者發給你網站的身份證字號,通常為亂數, 而srcret就是公開金鑰。
  • Redirect URL:
    由於當完成OAuth2程序後轉回Client網站的動作是由OAuth2提供者直接執行,以防止CSRF (Cross-site request forgery)攻擊。所以必須向Authorization Server登記URL。
  • AccessToken:
    要讀取Resource Server的重要Resource,唯一的方法就是用AccessToken。 而整個OAuth2的授權流程目的就是獲得AccessToken (寶庫的鑰匙)。
    • AccessToken本身可設期限及Scope (獲得多少資料)。

  • Authorization code:
    Client網站向 Authorzation Endpoint發出Request, Authorzation回傳授權頁面給Resource Owner,如果Resource Owner確認授權,Client會收到一組Authorization Code。Client拿著Authorization Code、Client Id、 Client secret、 已登記的Redirect URL去拿可以讀取資料的AccessToken。 


OAuth2認證流程種類
可以分成四類:

  1. Authorization Code Grant Flow
    流程最嚴密的模式,下面的例子也是用這種。
  2. Implicit Grant Flow
    直接跳過先獲得Authorization Code再換取Access Token的過程,直接發AccessToken給User Agent。
  3. Resource Owner Password Credentials Grant Flow
    用戶向Client直接提供自己的名稱跟密碼,Client拿著使用者的名稱跟密碼去Authorization Server獲得授權。通常用在對客戶端高度信任的情況下,或者OAuth2提供者自己寫的APP才使用,例如facebook自己的手機APP。
  4. Client Credentials Grant Flow
    Authorization Server看到信任的Client直接發AccessToken。
這四種的差異網路上的資源很多,我是看鴨七大[2]、 Ping Identity[4]還有阮一峰[5]大大的Blog看懂的。


OAuth2認證的簡易流程說明:

如果真的沒時間看懂全部的話,可以看看以下的部分。以下利用facebook的 OAuth2 provider為例子,說明如何使用OAuth2。

  • 公司網站必須先在facebook註冊並填寫RedirectURL,需要填寫RedirectURL是由於當完成OAuth2程序後轉回公司網站的動作是由Facebook直接執行,以防止CSRF (Cross-site request forgery)攻擊。
  • 公司在facebook註冊後會獲得一組client_id及client_secret,以確認就算使用者授權存取他的個人資料後還是只有公司網站才能存取。


好,開始吧:

圖1: 鴨七大的認證概念PPT擷圖[1]

現在再以facebook為例子。假設你的個人資料儲存在facebook,在OAuth2的基礎下公司網站並不能直接拿著你facebook帳號跟密碼去facebook的伺服器取得你的個人資料。公司網站必須透過redirect把你轉到facebook Authorization Server的授權頁面,你在Authorization Server的頁面按下授權後Authorization Server會跟據你在facebook之前登記的client_id,client_secret發一張Access Token給公司網站,這張Access Token就像門票一樣,公司網站可以拿著Access Token、 client_id、 client_secret到facebook的Resource Server換領獎品取得你的個人資料 (Profile)。 Access Token本身具有時限性、還說明了可以取得的資訊量(scope), 就像演唱會的門票過期就沒用,而且門票只能進入場館的某個區域,整個概念就像圖1。

那政府登入網站呢?
把以上說明「facebook」換成「政府登入平台」再看一次,原理是一模一樣。


實作方法
包括OAuth2是開源專案,當然可以跟著說明文件慢慢寫Https request(我試過,我真的試過),不過光是注意http表頭格式、request規格已經想放棄了。所以官方網站詳細推介一系列的懶人包可以直接拿來使用不需要專注每一項細節,至於Microsoft陣營的話我是用比較多人使用的DotNetOpenAuth

動手做:在ASP.net MVC上使用OAuth2 (以DotNetOpenAuth為例子)
我是參考ASP.NET中「OWIN OAuth 2.0 Authorization Server」這篇文章「Create OAuth 2.0 Clients」這一節。
  1. 建立 _webServerClient 物件:
    設定Authorization Server、Resource Server位置、Client Id, secret Id參數。
  2. 取得AccessToken:
    由於DotNetOpenAuth已經幫你處理好拿authorization code換accessToken的步驟,所以不用擔心。
  3. 取得Resource

總結: 
沒有完全明白OAuth2沒關係,因為複雜的部分已經有神人幫忙寫好,只要知道基本概念,有問題的時候會trace就行。


References:
1. 簡單易懂的 OAuth 2.0byYu-Cheng Chuang
2. OAuth 2.0 筆記 Yu-Cheng Chuang
3. OAuth2 官方網站 , 有很多Coding的例子
4. OAuth2 Developer guide , 介紹OAuth2
5. http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html 理解OAuth 2.0

Popular posts from this blog

[SQL SERVER] 找出LOCK方法懶人包

[SQL Server] 解決log檔(ldf file)過度膨脹的實戰經驗

[開箱] Dell P2415Q 4K螢幕開箱