[Windows Azure] 使用 Windows Azure Access Control Service 2.0 開發 ASP.NET MVC 單一簽入應用程式

單一簽入 (Single Sign On) 一直是驗證存取權機制的最終境界,整合單一簽入的技術在市場上早已炒到不能再炒了,而且也有相當多的單一簽入解決方案,其中包含 OAuth 1.0/2.0,Open ID,Active Directory,LDAP 等等協定和服務,而在社群網路流行後,幾個重要的大型帳戶儲存庫像 Facebook, Google, Yahoo, Twitter, Plurk, Linked In 等廠商也相繼的開發了認證的 API 群,以支援來自不同設備或用戶端的驗證需求,而在台灣最新的個人資料保護法正式施行前,外部的單一簽入已經成為應用程式認證機制的首選,尤其是小型網站或新進市場的應用程式,透過大廠來處理驗證,使用者不但不用記太多的帳戶密碼,也容易吸引使用者登錄資料...

單一簽入 (Single Sign On) 一直是驗證存取權機制的最終境界,整合單一簽入的技術在市場上早已炒到不能再炒了,而且也有相當多的單一簽入解決方案,其中包含 OAuth 1.0/2.0,Open ID,Active Directory,LDAP 等等協定和服務,而在社群網路流行後,幾個重要的大型帳戶儲存庫像 Facebook, Google, Yahoo, Twitter, Plurk, Linked In 等廠商也相繼的開發了認證的 API 群,以支援來自不同設備或用戶端的驗證需求,而在台灣最新的個人資料保護法正式施行前,外部的單一簽入已經成為應用程式認證機制的首選,尤其是小型網站或新進市場的應用程式,透過大廠來處理驗證,使用者不但不用記太多的帳戶密碼,也容易吸引使用者登錄資料。

身為雲端主要供應商之一的微軟,當然也不能坐視這個趨勢,尤其是 Windows Live ID,更不能被大家晾在一邊,只是可能剛做雲端腦筋不太靈光,在 Windows Azure Platform 的初期開發的 AppFabric Access Control 服務,不但沒有支援 OAuth/Open ID,還要使用者自己用一個很不好用的工具 (內含在 AppFabric SDK 內) 建置自己的帳戶資料庫,然後設定關聯和規則,數以打計的步驟要做,光是看就眼花了,何況要實作 ...

還好的是,只是一開始不太靈光而已,到了 2011 年,Access Control Service 發布了新的版本 2.0,重新修改了架構,不但可支援 OAuth/Open ID,還可以支援 WS-Federation 和 ADFS (Active Directory Federation Service) 等不同的驗證方式,而在 Spring Release 時更發表了 Enterprise Graph API 技術,讓單一簽入的整合更加的容易。同時 ACS 2.0 也支援 Windows Identity Foundation 基礎架構,用戶端程式使用 WIF SDK 即可順利整合不同的驗證機制。

未來還會有機會介紹更多,不過本文只要介紹一件事:如何使用 ASP.NET MVC 和 ACS 2.0 整合以支援單一簽入機制。在 Windows Azure 的官方網站上有 HOW TO 的範例,不過因為它對應的是 Web Form,所以筆者就來寫一篇以 MVC 為主的流程。

首先,登入到 Silverlight-based Portal (新的 Portal 還沒有 ACS 的管理介面,只能先由原本的進入),然後在左側選單中選擇 “服務匯流排,存取控制與快取”,然後選擇 “存取控制”,如果沒有建立帳戶,可按工具列的 “新增”,然後在可用的服務中勾選存取控制,並在一般屬性中輸入唯一的命名空間,然後選擇要設定此服務的國家,再按 “建立命名空間”即可。

image

 

接著,選取帳戶後,按工具列上的 “存取控制服務”:

image

 

即會進入管理工具的畫面:

image

 

接著,請點按 “識別提供者”(Identity Provider),識別提供者是實際提供帳戶驗證的供應商,在 ACS 2.0 中,可支援 Windows Live ID, Facebook, Google 和 Yahoo 四個預設的 OAuth 提供者:

image

 

不過預設並沒有 Facebook,所以要按 “新增”加入 Facebook:

image

然後設定 Facebook 登入的細節:

image

其中的應用程式識別碼就是在 Facebook 中建立應用程式時所產生的 App ID,密碼則是 App Secret,這兩項資料可由 Facebook 的應用程式頁面獲得,並且要記得保密,以避免被盜用。設定完以後按畫面最小方的 “儲存”即可。

接著,選擇 “信賴憑證者應用程式”(Relying Party Application; RP Application),並按 “新增”,進入設定畫面:

image

畫面很長,但只要注意幾個部份:

  • 名稱:給定一個應用程式的名稱,例如 My Application 或是 mysite.com 都可以。
  • 模式:採用預設的手動輸入設定即可。
  • 領域:應用程式所使用的 URI,若是網站的話建議使用根 URL (可用 localhost),若是非網站則是取名一個唯一的 URI。
  • 傳回 URL:應用程式接收來自 Identity Provider 和 ACS 伺服器傳回資訊的 URL (可用 localhost)。
  • 錯誤 URL:ACS 認證失敗時會導向的 URL (可用 localhost)。
  • 權仗格式:ACS 產生的憑證格式,若是使用 Windows Identity Foundation 的話,建議使用 SAML 2.0。
  • 權仗加密原則:指示 ACS 是否要加密權仗資訊,只有在特定情況才會需要。
  • 權仗存留期:登入權仗的有效期限,預設 600 秒,可視需求縮短或延長。

image

這個畫面的設定,可決定要使用哪些識別提供者,以及建立規則群組 (如果是新的應用程式,預設會勾選建立新的規則群組,使用預設值即可),然後按 “儲存”即可。

接著,到 “規則群組”管理功能:

image

點按前一步設定的應用程式名稱,然後按 “產生”,由 ACS 產生預設的規則,然後按 “儲存”即可:

image

至此,ACS 服務上的設定就完成了。

接著,打開 Visual Studio,新增一個 ASP.NET MVC 應用程式專案,然後在專案的快顯功能表上,選擇 “Add STS reference…” (這個選項要安裝 Windows Identity Foundation SDK 才會出現):

image

 

此時會出現 Federation Utility Wizard,首先要設定 Application URI,這個 URI 必須要對應前面在 ACS 的應用程式中設定的領域 URI

image

 

然後會出現一個提示,說此連線沒有使用 SSL (https://),不過現階段不用也沒關係,所以按是即可:

image

 

接著會進入 Security Token Service 的設定頁,請選擇 “Use an existing STS”,而這個 STS WS-Federation metadata document location 的 URL 可以由 ACS 服務的管理介面的 “應用程式整合”頁中取得。

image

這個 STS WS-Federation metadata document location 的 URL 可以由 ACS 服務的管理介面的 “應用程式整合”頁中取得,即畫面中的 “WS-同盟中繼資料”的 URL,將它複製出來貼到 Security Token Service 的 STS WS-Federation metadata document location 欄位內,然後按下一步:

image

 

接著,會要求選擇是否啟用簽署憑證鏈 (signing certificate chain) 驗證的功能 (因為目前 ACS 核發的是由 ACS 自行產生的憑證,而不是由像 Verisign 這種憑證商核發的),請直接接受預設值即可:

image

 

接著,會要求確認是否要對權仗進行加密,本例不用,所以接受預設值即可:

image

 

接著,會出現目前 STS 設定的證書 (Claims) 的型別,直接接受預設值即可:

image

 

最後按完成即可,WIF 會自動在 Web.config 中加入相關設定,並且在專案中加入對 Microsoft.IdentityMode.dll 組件的參考 (如果用的是 MVC 4 RC 的話,有可能不會自動加,這時要用手動的方式加):

image

 

接著在專案中新增一個 Controller (筆者是用空白 MVC 專案,所以新增的是 HomeController),然後加入下列程式碼:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Microsoft.IdentityModel;
using Microsoft.IdentityModel.Web;
using Microsoft.IdentityModel.Claims;
using System.Threading;

namespace AzureLiveCast.Web.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            if (Thread.CurrentPrincipal.Identity == null)
            {
                return Content("Not authenticated.");
            }
            else
            {
                List<string> data = new List<string>();
                data.Add("Claims Received from ACS:");
                ClaimsIdentity ci = Thread.CurrentPrincipal.Identity as ClaimsIdentity; 
                
                foreach (Claim c in ci.Claims)
                {
                    data.Add("Type: " + c.ClaimType + "- Value: " + c.Value + "");
                }

                return Content(string.Join("<br />", data.ToArray()));
            }
        }

    }
}

這樣就完成了。

接下來只要啟動應用程式,就可以看到要求驗證的畫面了:

image

 

點 Windows Live ID 登入,會看到權仗的資訊:

image

 

這樣就表示登入成功了。

如何?雖然程序有點長,但實際程式只有寫一點點,夠簡單吧 微笑

 

Reference: https://www.windowsazure.com/en-us/develop/net/how-to-guides/access-control/