Tags: | Categories: C# Posted by talgiladi on 10/3/2008 8:47 PM | Comments (5)

החלטתי לכתוב קצת על שירותי רשת, שירותי ווב או בקיצור web services...
אז מכיוון שכולנו יודעים ליצור שירות בסיסי אני אדלג על ההתחלה ואעבור ישירות לשירותים מתקדמים.
כשאני אומר שירותים מתקדמים אני לא מתכוון לקוד מתוחכם שאנחנו יוצרים, אלא לתמיכה מובנית, סטנדרטים חדשים שצומחים לאיטם
שמטרתם להוסיף פיצ'רים חדשים ותמיכה בעוד סוגי שירותים לשירותי הרשת.
לדוגמה -  תמיכה מובנית בהצפנה, חתימה דיגיטלית, טרנזאקציות ועוד...

הבשורה הרעה שכולנו לא אוהבים לשמוע, זה שצריך להוריד משהו מהאינטרנט... כן, זה עדיין לא בא בתור סטנדרט בתוך הפריימוורק, אולי בעתיד...
אז תגשו לגוגל ותחפשו wse, בפעם האחרונה שבדקתי הגירסה הייתה 3.0 ולינק ההורדה ממיקרוסופט הוא כאן
לאחר ההתקנה יהיו לכם כמה דוגמאות קוד והוראות שימוש די נוחות...
הדבר הראשון שצריך לעשות אם אנחנו רוצים להשתמש בחתימה דיגיטלית זה להתקין מפתח אסימטרי.
למזלנו הקובץ מגיע עם 4 מפתחות לצורך הדוגמה, והדבר היחיד שצריך לעשות זה להריץ את הקובץ setup.bat שנמצא בתוך ספריית ההתקנה, בתוך ספריית samples, רק שימו לב שצריך לפתוח את שורת הפקודה של ויזואל סטודיו קודם:

cmd

ללכת לנתיב שציינתי, ואז לכתוב את שם הקובץ להרצה... תתפללו שהכל יעבוד, ואם כן אז יש לכם 4 מפתחות להצפנה מותקנים על ה iis.

אם ממש בא לראות אותן, ניתן להקיש בשורת הפקודה mmc כדי לפתוח את הקונסול, אחר כך להקיש על file->Add/Remove snap in->Add->certificates->Add
ואז תראו שם את כל המפתחות שמותקנות אצלכם על המחשב מהגלישה באינטרנט... אלו שעכשיו התקנו -  אחת מופיע תחת personal , עוד אחת תחת other people ועוד 2 איפשהו שם...

איך עובדת החתימה הדיגיטלית בשירותי רשת?
כמו בכל מקום אחר. הלקוח מייצר מפתח פרטי-ציבורי מהחתימה שלו. את המפתח הציבורי הוא ישלח ביחד עם ההודעה לשרת שמפעיל את שירותי הרשת.
הלקוח עושה האש על ההודעה.
על קוד ההאש שקיבלנו, אנו מבצעים את ההצפנה בעזרת המפתח הפרטי, מה שקיבלנו עכשיו זו בעצם החתימה הדיגיטלית.
את החתימה אנחנו מצרפים להודעה שאנחנו שולחים.

בצד השרת- השרת מקבל את ההודעה ורואה חתימה דיגיטלית מצורפת ב header של ההודעה.
בעזרת המפתח הציבורי שהלקוח צירף, השרת מנסה לפענח את החתימה. אם הצליח אז עכשיו יש בידינו את קוד ההאש של ההודעה.
כעת השרת יעשה בעצמו חישוב האש על ההודעה (כמובן בעזרת אותו אלגוריתם שהלקוח השתמש - הלקוח צריך להעביר גם את הפרט הזה בהודעה...)
ועכשיו נשאר רק להשוות אם ההאש שפיענחנו מהלקוח זהה להאש שביצענו בעצמנו... אם לא, ההודעה שונתה בדרך...

תמיכה נוספת למעין חתימה דיגיטלית היא חתימה על ידי שם משתמש וסיסמא, שהם משמשים בעצם במקום המפתח הפרטי. החיסרון הברור הוא שלשרת צריכים להיות
את שם המשתמש והסיסמא כדי לוודא שאכן החתימה אמיתית...

רק עוד דקה של תיאוריה, דבר שצריך לדעית לפני שמתחילים עם כל השירותים המורחבים האלה, זה שכל התוספות האלה מצורפות ל headers של ההודעה, ה wse יושב ומאזין בשרת ואצל הלקוח, וברגע שהלקוח שולח הודעה, אז לפי ההגדרות ה wse לוקח את ההודעה, עושה מה שצריך איתה, ומעביר אותה הלאה לשרת. בצד השרת שוב ה wse מאזין להודעות המגיעות, מנתח אותן לפי ההגדרות, ואז אם הכל בסדר מעביר את ההודעה לקוד שלנו. כך שאם אתם בדיבאג על השרת, ומשום מה הודעה לא מגיעה לשם, כנראה היא לא עברה את  מחסום ה wse...

אז בואו נתחיל עם חתימה על ידי שם משתמש וסיסמא.

הגדרת צד השרת

  1. קודם כל ניצור אתר פשוט. 
     
    עכשיו כמה הגדרות
    בואו נפתח את כלי הקונפיגורציה שהגיע עם ההתקנה. אם אתם כבר בויזואל סטודיו אז לחצן ימני על הפרוייקט ותראו למטה לחצן בשם wse settings. (אם לא, אז פשוט תתחילו את התוכנה  לבד דרך תפריט ההתחלה:

    openConfiguration

    אבל אז תצטרכו למקם את הקובץ שנוצר לבד בתוך תיקיית האתר שלכם)

    התוכנה הזאת בעצם חוסכת מאיתנו את המשחק בווב קונפיג ומכניסה לשם את ההגדרות הדרושות.
  2. בטאב הראשון נאפשר את השימוש בהרחבות המתקדמות בפרוייקט שלנו:

    enableWSE
  3. בטאב ה security בחלק של seucrity tokens manager נוסיף מנהל חדש על ידי לחיצה על add

    AddToken

    תבחרו בקומבו בוקס Username Token Manager ושאר הפרטים יתמלאו לבד.
    כאן בעצם הגדרנו שההודעה שלנו צריכה להכיל חתימה בעזרת שם משתמש וסיסמה.

  4. אנחנו צריכים לעשות זה ליצור מחלקה שאליה יעביר ה wse את שם המשתמש, והיא תחזיר לו את הסיסמה
    כדי שהוא יוכל לבדוק את החתימה הדיגיטלית. המחלקה הזאת במצב רגיל מן הסתם תמשוך את המידע מדטה בייס או קובץ.
    את שם המחלקה, שעוד מעט נראה איך ליצור, אנו כותבים בתיבת הטקסט Type. אני קראתי למחלקה UserNameTokenHandler

    UserNameTokenHandler

    תקליקו על אישור

  5. עוד דבר יש לנו בטאב הזה, כדי שנוכל לשחק עם המפתחות שלנו, שאינן אמיתיים ולא הונפקו על ידי חברה מורשית כגון verisign וכו',

    יש לסמן צ'ק בוקס בשם Allow test roots
    allowTestRoots


  6. עלינו ליצור קובץ שיכיל את ה Policy. הקובץ הזה מכיל הגדרות שונות לגבי החתימה הדיגיטלית. אתם יכולים להעתיק את הקובץ מספריית הדוגמאות שהגיעה עם התקנה ה wse, שם הקובץ הוא wse3policyCache.config והתוכן שלו הוא

    <policies xmlns="http://schemas.microsoft.com/wse/2005/06/policy">

      <extensions>

        <extension name="usernameForCertificateSecurity" type="Microsoft.Web.Services3.Design.UsernameForCertificateAssertion, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

        <extension name="x509" type="Microsoft.Web.Services3.Design.X509TokenProvider, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

        <extension name="requireActionHeader" type="Microsoft.Web.Services3.Design.RequireActionHeaderAssertion, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

      </extensions>

      <policy name="ServerPolicy">

        <usernameForCertificateSecurity establishSecurityContext="false" requireSignatureConfirmation="false" messageProtectionOrder="SignBeforeEncrypt" requireDerivedKeys="true" ttlInSeconds="300">

          <serviceToken>

            <x509 storeLocation="LocalMachine" storeName="My" findValue="CN=WSE2QuickStartServer" findType="FindBySubjectDistinguishedName" />

          </serviceToken>

          <protection>

            <request signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="true" />

            <response signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="true" />

            <fault signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="false" />

          </protection>

        </usernameForCertificateSecurity>

        <requireActionHeader />

      </policy>

    </policies>

    פה בעצם אמרנו למנהל המפתחות הכן נימצא המפתח שלי, מה השם שלו ואיך למצוא אותו. הגדרנו גם איך צריכה להיראות בקשה לשרת, התגובה מהשרת והודעות שגיאה.

    7. כעת נראה למנהל ה Policy  היכן ניתן למצוא את הקובץ. לכו לטאב של ה Policy, תסמנו את הצ'ק בוקס כדי לאפשר Policy, תקליקו על Browse ותמצאו את הקובץ הנ"ל.
    כעת תנו שם ל Policy. אצלנו השם הוא ServerPolicy
    AllowPolicy

    תלחצו על אישור
  7. בואו ניצור את המחלקה שתטפל בשם המשתמש:
    ניצור מחלקה בשם UserNameTokenHandler שתירש מהמחלקה UsernameTokenManager. נדרוס את הפונקציה AuthenticateToken שהחתימה שלה היא

    protected override string AuthenticateToken(UsernameToken token)


    הפונקציה הזאת מקבלת מה wse את ה UsernameToken ואמורה להחזיר את הסיסמה עבור המשתמש הזה. עם הסיסמה שאנחנו מחזירים, ה wse מנסה לפענח את החתימה הדיגיטלית, ואם הוא מצליח הוא אז הוא יעשה האש להודעה וישווה לערך שנמצא בחתימה הדיגיטלית. לצורך הדוגמה הקוד יהיה פשוט

     protected override string AuthenticateToken(UsernameToken token)

        {

            if (token.Username == "talg")

            {

                return "mypassword";

            }

            else

            {

                return null;

            }

        }

     

    להורדת הקוד של המחלקה
  8. ניצור ווב סרביס פשוט, ניתן אפילו להשתמש בשלום עולם שנוצר אוטומטי. השינוי היחד שאנחנו צריכים לעשות זה לציין באיזה פוליסי הסרביס הזה ישתמש. אנו יצרנו כבר פוליסי בשם ServerPolicy ובא נשתמש על ידי הוספת המאפיין לפני שם המחלקה של הווב סרביס:

    [Policy("ServerPolicy")]

    וסיימנו את צד השרת... היה ארוך, אבל רוב ההגדרות הן חד פעמיות, וכעת כל סרביס נוסף שתגדירו לא ידרוש שום הגדרה נוספת. אם ה wse יחליט שהבקשה עונה על הדרישות, שבמקרה שלנו הם חתימה דיגיטלית בעזרת שם משתמש וסיסמה, הוא יעביר את הבקשה לסרביס שלנו, אם לא, אנחנו אפילו לא נדע מזה, הודעת שגיאה תיזרק לצד הלקוח...

    להורדת קוד והגדרות השרת

הגדרת צד הלקוח
בצד הלקוח נעשה קצת אחרת, נוריד את ההגדרות מהקופיגורציה ונכניס אותם לקוד, כדי שיקביל לדוגמאות שהגיעו עם ההתקנה.

  1. ניצור פרוייקט, אני יצרתי אפליקציית קונסול.
  2. לחצן ימני על הגדרות פרוייקט-> wse settings
  3. לסמן את הצ'ק בוקס הראשון שמופיע, שבעצם מאפשר שימוש ב wse בפרוייקט הזה:

     enableWSEClient
  4. כעת ניצור הפנייה לווב סרביס בשרת שלנו על ידי הוספת web reference כרגיל. כעת לנקודה הכי חשובה! הפנייה רגילה לווב סרביס יורשת מהמחלקה SoapHttpClientProtocol , אנו צריכים לשנות כך שההפניה שלנו תירש מ WebServicesClientProtocol, שום שינוי אחר לא נדרש בקוד של ההפניה. רק שימו לב שכדאי לכם להוציא את ההפניה מהתיקיה של web references, אחרת כל פעם כשיבוצע עידכון הקוד הישן ימחק ותיצטרכו שוב לשנות את שם המחלקה.
  5. הפנייה בקוד לווב סרביס

    SecureWebService.WebService ws = new WebServiceClient.SecureWebService.WebService();

  6. יצירת מקבילה בקוד לקובץ הפוליסי שיצרנו בשרת:

     UsernameForCertificateAssertion assertion = new UsernameForCertificateAssertion();

  7. נגדיר עם איזו חתימה להשתמש, ואיך למצוא אותה

    assertion.X509TokenProvider = new X509TokenProvider(StoreLocation.CurrentUser,

                                                                    StoreName.AddressBook,

                                                                    "CN=WSE2QuickStartServer",

                                                                    X509FindType.FindBySubjectDistinguishedName);

  8. עוד הגדרה שמופיעה אצלנו בקובץ הפוליסי בשרת:

      assertion.RequireDerivedKeys = true;

  9. כעת נכניס את השם המשתמש והסיסמה:

    assertion.UsernameTokenProvider = new UsernameTokenProvider("talg", "mypassword");

  10. ונוסיף את הפוליסי לווב סרביס:

      Policy policy = new Policy();

                policy.Assertions.Add(assertion);

                ws.SetPolicy(policy);

  11. ונקרא לשירות:

     string result = ws.HelloWorld();

    אם עשינו הכל כמו שצריך, נקבל תשובה, אם לא... אז תיזרק אקספשן...

    להורדת קוד פרוייקט הלקוח
Technorati Tags:

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Comments