2007 年 8 月
簡介:為什麼 AuthSub 很重要?
Google Data API (簡稱「GData」) 的一大優點,在於開發人員能夠打造出與 Google 服務互動的應用程式。具體來說,這類 API 可讓您存取可在應用程式中使用的私人使用者資料。這些 API 可讓您編寫應用程式來同步處理、匯入、匯出及管理這些資料。儘管 API 提供的功能相當強大,但請務必記得以負責任的方式使用這些功能。由於使用者資料屬於私人資訊,因此您想要透過安全的方式存取這些資料。重要的一環是能夠以安全的方式驗證 Google 伺服器。
假設您有一個優質的新網路應用程式,且想要與儲存在 Google 網路服務中的資料連結。現在,您必須驗證才能存取這項私人資料。為何不單純使用 ClientLogin 之類的簡單方法?雖然這可行,但您將處理更多的私人資料:使用者的登入憑證。ClientLogin 會要求您的應用程式要求使用者的 Google 使用者名稱和密碼。這對在個人用電腦上執行的桌面應用程式而言,這個做法並不適合使用網路應用程式。除了在自己的伺服器上處理這些憑證的責任之外,有些較謹慎的使用者也可能讓您儲存他們的資訊。還有一項使用者常抱持的疑慮,就是他們只想將計劃存取權授予特定的服務 (例如「Google 日曆」中的活動),而不授予其他服務 (例如「Google 文件」) 的存取權。AuthSub 可讓使用者透過 Google 伺服器進行驗證,讓程式只能要求存取,藉此解決這兩個問題。
瞭解 AuthSub 背後的理論後,接下來就要開始寫程式了!在這篇文章中,我決定將簡單明瞭的一切匯集到單一 ASP 網頁中,但您應該能在自己的應用程式中輕鬆運用這裡提到的技巧。
處理驗證
那麼,要在網頁應用程式中實際使用 AuthSub 需要具備哪些條件?首先,GData 用戶端程式庫會提供一些標準匯入項目:
<%@ Import Namespace="Google.GData.Client" %> <%@ Import Namespace="Google.GData.Extensions" %> <%@ Import Namespace="System.Net" %>
現在,您需要將使用者傳送到專門的 URL。如此一來,Google 的伺服器便會處理驗證,並將使用者重新導向回您的網站。幸好,您不需要手動產生這個網址,因為我們有幾種方式為您代勞。以下面這段程式碼為例:
authSubUrl = AuthSubUtil.getRequestUrl(target, scope, secure, session);
- target:這個字串包含您網路應用程式的網址。使用者完成驗證後,系統會將他們重新導向至這裡。
- scope 這個字串取決於您使用的 API。其對應 GData API 中的其中一個資訊提供。例如,內含使用者所有日曆資訊的資訊提供為「http://www.google.com/calendar/feeds/default/private/full」。
- 安全:這個布林值會告知伺服器您已向 Google 註冊,並用加密編譯的方式,將您的要求簽署到伺服器。根據預設,這個引數通常是 false,特別是在測試環境中作業時。
- session:這是另一個布林值,表示您想要「sessiontoken」,而非「一次性使用權杖」。這個引數的角色在稍後會更加清楚。
使用者只要按一下產生的網址,系統就會將他們帶往 Google 帳戶頁面,使用者可以透過這個頁面登入 Google 帳戶。之後,系統會將其重新導向回您在「target」變數中指定的網頁,但使用包含「一次性」權杖的查詢參數「token」。一般來說,這個符記只能使用一次。換句話說,它可以用來對指定的資訊提供執行一項動作。不過,如果您將「session」參數指定為 true,就能交換為「工作階段符記」,可在使用者結束工作階段之前重複使用。您可以選擇下列其中一種操作方式:
String token = Request.QueryString["token"]; Session["token"] = AuthSubUtil.exchangeForSessionToken(token, null).ToString();
您可以在這裡從查詢參數中擷取憑證,並交換以用於「工作階段符記」。然後,您就可以儲存該憑證儲存在 .NET 的自動 Session
陣列中。不過,您也可以選擇將憑證儲存在資料庫中。下一步是使用這組憑證提出經過驗證的要求:
GAuthSubRequestFactory authFactory = new GAuthSubRequestFactory("cl", "My-Cool-Application"); authFactory.Token = (String) Session["token"]; CalendarService service = new CalendarService(authFactory.ApplicationName); service.RequestFactory = authFactory;
在這個步驟中,您可以設定 CalendarService 物件,透過 AuthSub 進行驗證以與 Google Calendar API 互動。請注意,GAuthSubRequestFactory
建構函式中使用的「cl」是 Google 日曆的服務名稱。如需其他服務名稱的資訊,請參閱 Google Data API 常見問題。
安全 (已註冊) AuthSub
如果您選擇註冊網路應用程式,可以在使用 AuthSub 時提升安全性。如此一來,您就能以數位方式簽署程式碼提出的所有要求,這樣一來,除非他人有私密金鑰,否則他人無法使用核發給您的 AuthSub 憑證。第一步是確定您在呼叫 AuthSubUtil.getRequestUrl
時將「secure」引數設為 true,以產生正確的 AuthSub 連結。您需要另外進行兩項程式碼變更:
String token = Request.QueryString["token"]; Session["token"] = AuthSubUtil.exchangeForSessionToken(token, rsaKey).ToString(); ... authFactory.PrivateKey = rsaKey;
首先,請注意 null
,而不是將 null
傳送至變數的「rsaKey」。設定與服務的連線時,這個變數也會用來設定 GAuthSubRequestFactory
的屬性。「rsaKey」變數是一個 RSACryptoServiceProvider
,對應您在 Google 註冊的 x509 憑證的私密金鑰元件。
產生 RSA 私密金鑰和自行簽署憑證有時並不容易,尤其是 .NET 架構無法解讀以 PEM 格式儲存的金鑰或憑證。下列指令示範如何使用 OpenSSL 工具產生私密金鑰和公開憑證:
openssl req -x509 -nodes -days 365 -newkey rsa:1024 -sha1 -subj \ '/C=US/ST=CA/L=Mountain View/CN=www.example.com' -keyout \ test_key.pem -out test_cert.pem openssl pkcs12 -export -in test_cert.pem -inkey test_key.pem \ -out test_cert.pfx -name "Testing Certificate"
第一個步驟會產生分別採用「test_key.pem」和「test_cert.pem」的 PEM 格式的私密金鑰和公開 X509 憑證。請注意,憑證的註冊狀態為「www.example.com」,位於美國加州山景城。請將其中的值替換為貴公司的值。「test_cert.pem」檔案包含您要在 AuthSub 註冊頁面提交的資訊。
第二個步驟則會透過您的私密金鑰和憑證產生 PFX 檔案。這個檔案可匯入 .NET 用戶端程式庫,以數位方式簽署對 GData API 發出的要求。以下程式碼顯示如何將私密金鑰從 PFX 檔案匯入網路應用程式:
protected AsymmetricAlgorithm getRsaKey() { X509Certificate2 cert = new X509Certificate2("C:/MyAspSite/test_cert.pfx",""); RSACryptoServiceProvider privateKey = cert.PrivateKey as RSACryptoServiceProvider; return privateKey; }
用於驗證 API 的程式碼片段時,這個程式碼片段定義的 getRsaKey()
函式可以取代上述的「rsaKey」變數。您應將產生的路徑改成您產生的 PFX 檔案的適當位置。
完整程式碼清單
使用上一個範例所示範的方法,示範如何使用上一節所述的方法。以下範例程式碼是一個簡單的 ASP 網頁,該頁面使用 AuthSub 驗證使用者,然後列印其「Google 日曆」的活動。
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <%@ Import Namespace="Google.GData.Client" %> <%@ Import Namespace="Google.GData.Extensions" %> <%@ Import Namespace="Google.GData.Calendar" %> <%@ Import Namespace="System.Net" %> <script runat="server"> void PrintCalendar() { GAuthSubRequestFactory authFactory = new GAuthSubRequestFactory("cl", "TesterApp"); authFactory.Token = (String) Session["token"]; CalendarService service = new CalendarService(authFactory.ApplicationName); service.RequestFactory = authFactory; EventQuery query = new EventQuery(); query.Uri = new Uri("http://www.google.com/calendar/feeds/default/private/full"); try { EventFeed calFeed = service.Query(query); foreach (Google.GData.Calendar.EventEntry entry in calFeed.Entries) { Response.Write("Event: " + entry.Title.Text + "<br/>"); } } catch (GDataRequestException gdre) { HttpWebResponse response = (HttpWebResponse)gdre.Response; //bad auth token, clear session and refresh the page if (response.StatusCode == HttpStatusCode.Unauthorized) { Session.Clear(); Response.Redirect(Request.Url.AbsolutePath, true); } else { Response.Write("Error processing request: " + gdre.ToString()); } } } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Test Site</title> </head> <body> <form id="form1" runat="server"> <h1>AuthSub Sample Page</h1> <div> <% GotoAuthSubLink.Visible = false; if (Session["token"] != null) { PrintCalendar(); } else if (Request.QueryString["token"] != null) { String token = Request.QueryString["token"]; Session["token"] = AuthSubUtil.exchangeForSessionToken(token, null).ToString(); Response.Redirect(Request.Url.AbsolutePath, true); } else //no auth data, print link { GotoAuthSubLink.Text = "Login to your Google Account"; GotoAuthSubLink.Visible = true; GotoAuthSubLink.NavigateUrl = AuthSubUtil.getRequestUrl(Request.Url.ToString(), "http://www.google.com/calendar/feeds/",false,true); } %> <asp:HyperLink ID="GotoAuthSubLink" runat="server"/> </div> </form> </body> </html>
結語
AuthSub 可讓網路應用程式以安全且可控制的方式存取儲存在使用者 Google 帳戶中的資料。使用 .NET 用戶端程式庫可以輕鬆地將 ASP 網站與 Google 服務整合。本文旨在協助您快速上手,但仍建議您參考下列額外資源: