אוגוסט 2007
מבוא: למה AuthSub חשוב?
היתרון הגדול של Google Data APIs (או בקיצור GData) הוא שהם מאפשרים למפתחים ליצור אפליקציות שמקיימות אינטראקציה עם שירותי Google. באופן ספציפי יותר, הם מאפשרים לכם לגשת לנתונים פרטיים של משתמשים לשימוש באפליקציה שלכם. ממשקי ה-API מאפשרים לכם לכתוב אפליקציות לסנכרון, לייבוא, לייצוא ולניהול הנתונים האלה. ממשקי ה-API האלה מאפשרים לכם לבצע פעולות עוצמתיות, אבל חשוב לזכור להשתמש בהם בצורה אחראית. נתוני משתמשים הם מידע פרטי, ולכן חשוב לגשת אליהם בצורה מאובטחת. חלק חשוב בתהליך הזה הוא היכולת לבצע אימות לשרתים של Google בצורה מאובטחת.
נניח שיש לכם אפליקציית אינטרנט חדשה ומצוינת שאתם רוצים לקשר לנתונים שמאוחסנים בשירותי האינטרנט של Google. עכשיו אתם רוצים לבצע אימות כדי לגשת לנתונים הפרטיים האלה. למה לא להשתמש במשהו פשוט, כמו ClientLogin? השיטה הזו תעבוד, אבל אז תצטרכו לטפל בנתונים פרטיים נוספים: פרטי הכניסה של המשתמש. ב-ClientLogin, האפליקציה שלכם צריכה לבקש את שם המשתמש והסיסמה של המשתמש ב-Google. זה בסדר באפליקציית מחשב שפועלת במחשב האישי של המשתמש, אבל זה פחות אידיאלי לאפליקציה מבוססת-אינטרנט. בנוסף לאחריות על הטיפול בפרטי הכניסה האלה בשרת שלכם, יכול להיות שחלק מהמשתמשים הזהירים יותר יחששו שתאחסנו את המידע שלהם. דאגה נפוצה נוספת של משתמשים היא אם הם רוצים להעניק לתוכנה גישה לשירות מסוים אחד (כמו האירועים ביומן Google) אבל לא לשירות אחר (כמו Google Docs). AuthSub פותרת את שתי הבעיות האלה בכך שהיא מאפשרת למשתמשים לבצע אימות דרך השרתים של Google, ומאפשרת לתוכנית שלכם לבקש רק את הגישה שהיא צריכה.
עכשיו, אחרי שקראתם מספיק על התיאוריה שמאחורי AuthSub, הגיע הזמן לעבור לכתיבת קוד. במאמר הזה בחרתי להשתמש בשיטה פשוטה ולבצע את כל הפעולות בדף ASP אחד, אבל אתם יכולים לשלב בקלות את הטכניקות שמוצגות כאן באפליקציה שלכם.
התנהלות עם אימות
אז מה צריך לעשות כדי להשתמש ב-AuthSub באפליקציית האינטרנט? קודם כל, יש כמה ייבוא סטנדרטיים מספריית הלקוח של GData:
<%@ Import Namespace="Google.GData.Client" %> <%@ Import Namespace="Google.GData.Extensions" %> <%@ Import Namespace="System.Net" %>
הדבר הראשון שצריך לעשות הוא לשלוח את המשתמש לכתובת URL שנוצרה במיוחד. כך השרתים של Google יכולים לטפל באימות ואז להפנות את המשתמש חזרה לאתר שלכם. למזלכם, לא צריך ליצור את כתובת ה-URL הזו באופן ידני, כי יש שיטות לעשות זאת בשבילכם. נבחן את הדוגמה הבאה:
authSubUrl = AuthSubUtil.getRequestUrl(target, scope, secure, session);
- target מחרוזת שמכילה את כתובת ה-URL של אפליקציית האינטרנט. כאן מציינים לאן המשתמש יופנה אחרי האימות.
- scope המחרוזת הזו נקבעת לפי ה-API שבו אתם משתמשים. הוא תואם לאחד הפידים ב-GData API. לדוגמה, הפיד שמכיל את כל פרטי היומן של משתמש הוא http://www.google.com/calendar/feeds/default/private/full.
- secure: ערך בוליאני שמציין לשרת שנרשמתם ב-Google ושבקשות שתשלחו לשרת ייחתמו בצורה מוצפנת. הארגומנט הזה הוא בדרך כלל False כברירת מחדל, במיוחד כשעובדים בסביבת בדיקה.
- session: עוד ערך בוליאני שמציין שאתם רוצים לקבל 'אסימון סשן' ולא 'אסימון לשימוש חד-פעמי'. התפקיד של הארגומנט הזה יתבהר בהמשך.
אחרי שהמשתמש לוחץ על כתובת ה-URL שנוצרה, הוא מועבר לדף של חשבונות Google שבו הוא יכול להיכנס לחשבון Google שלו. לאחר מכן הם יופנו בחזרה לדף האינטרנט שצוין במשתנה target, אבל עם פרמטר שאילתה token שמכיל טוקן לשימוש חד-פעמי. בדרך כלל, אפשר להשתמש באסימון הזה בדיוק פעם אחת. כלומר, אפשר להשתמש בו כדי לבצע פעולה אחת בפיד נתון. עם זאת, אם ציינתם את הפרמטר session כ-true, אפשר להחליף אותו ב-session token שאפשר להשתמש בו מחדש עד שהמשתמש יסיים את הסשן. כך עושים זאת:
String token = Request.QueryString["token"]; Session["token"] = AuthSubUtil.exchangeForSessionToken(token, null).ToString();
כאן מחלצים את האסימון מפרמטר השאילתה ומחליפים אותו ב "אסימון סשן". אחר כך, כדי שתוכלו לשמור אותו לשימוש מאוחר יותר, תוכלו לבחור לאחסן אותו במערך האוטומטי Session
של .NET. כמובן שתוכלו גם לבחור לאחסן את הטוקן במסד נתונים. השלב הבא הוא להשתמש באסימון הזה כדי לשלוח בקשה מאומתת:
GAuthSubRequestFactory authFactory = new GAuthSubRequestFactory("cl", "My-Cool-Application"); authFactory.Token = (String) Session["token"]; CalendarService service = new CalendarService(authFactory.ApplicationName); service.RequestFactory = authFactory;
כאן מגדירים אובייקט CalendarService כדי ליצור אינטראקציה עם Google Calendar API באמצעות AuthSub לאימות. שימו לב שהמחרוזת 'cl' שמשמשת בבונה של GAuthSubRequestFactory
היא שם השירות של יומן Google. שמות של שירותים אחרים מפורטים במאמר בנושא שאלות נפוצות על Google Data APIs.
מאובטח (רשום) AuthSub
אם תבחרו לרשום את אפליקציית האינטרנט, תוכלו להפעיל רמת אבטחה נוספת בזמן השימוש ב-AuthSub. כך תוכלו לחתום דיגיטלית על כל הבקשות שנוצרות על ידי הקוד שלכם, כך שאף אחד לא יוכל להשתמש בטוקנים של AuthSub שהונפקו לכם, אלא אם יש לו את המפתח הפרטי שלכם. השלב הראשון הוא לוודא שאתם יוצרים את קישור AuthSub הנכון כשאתם מתקשרים אל AuthSubUtil.getRequestUrl
על ידי הגדרת הארגומנט secure לערך true. יש עוד שני שינויים בקוד שצריך לבצע:
String token = Request.QueryString["token"]; Session["token"] = AuthSubUtil.exchangeForSessionToken(token, rsaKey).ToString(); ... authFactory.PrivateKey = rsaKey;
קודם כל, במקום null
, מעבירים עכשיו את המשתנה rsaKey לשיטה exchangeForSessionToken
. אותו משתנה משמש גם להגדרת מאפיין של GAuthSubRequestFactory
כשמגדירים את החיבור לשירות. המשתנה rsaKey הוא RSACryptoServiceProvider
שמתאים לרכיב המפתח הפרטי של אישור x509 שנרשם ב-Google.
יצירה של מפתח פרטי 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"
בשלב הראשון נוצר מפתח פרטי ואישור X509 ציבורי, שניהם בפורמט PEM, בשמות test_key.pem ו-test_cert.pem, בהתאמה. שימו לב שהאישור מוגדר להירשם לכתובת www.example.com שנמצאת במאונטיין ויו, קליפורניה, ארה"ב. כאן צריך להזין את הערכים המתאימים לחברה שלכם. הקובץ test_cert.pem מכיל את המידע שצריך לשלוח בדף הרישום של AuthSub.
בשלב השני נוצר קובץ PFX מהמפתח הפרטי ומהאישור. אפשר לייבא את הקובץ הזה לספריית הלקוח של .NET כדי לחתום דיגיטלית על בקשות שנשלחות אל GData APIs. הקוד הבא מראה איך אפשר לייבא את המפתח הפרטי מקובץ ה-PFX לאפליקציית אינטרנט:
protected AsymmetricAlgorithm getRsaKey() { X509Certificate2 cert = new X509Certificate2("C:/MyAspSite/test_cert.pfx",""); RSACryptoServiceProvider privateKey = cert.PrivateKey as RSACryptoServiceProvider; return privateKey; }
אפשר להשתמש בפונקציה getRsaKey()
שמוגדרת בקטע הקוד הזה במקום המשתנה rsaKey שמופיע למעלה, כשמשתמשים בה כדי לבצע אימות לממשקי ה-API. כמובן שצריך להחליף את נתיב הקובץ במיקום המתאים של קובץ ה-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. המאמר הזה נועד לעזור לכם להתחיל, אבל יש מקורות מידע נוספים שכדאי לעיין בהם: