Daily Archives: 2007.03.4. 14:41

CardSpace és ASP.NET AJAX 5: Adatok feldolgozása szerver oldalon

Aki a bevezetőtől kezdve egészen az előző részig lelkesen követte a CardSpace implementálásának lépéseit, mostanra eljutott odáig, hogy képes egy csili-vili felhasználói felületen keresztül egy gusztustalan XML-t elküldeni a kliensről szerver oldalra. A következő feladatunk, hogy mindezt feldolgozzuk.

Miután Server.HtmlDecode() segítségével visszaállítottuk azt az XML-t, amit az identity selector visszaadott, elkezdhetjük kibogarászni annak tartalmát. Ehhez nagyságrendileg 500 sor kódot kell írni, de ez mindegy is, hiszen erre szerintem halandók amúgy sem képesek. De ne keseredjünk el, keresgéljünk egy TokenProcessor nevű névteret lelkesen a guglival és ha elég ügyesek vagyunk, akkor meg is találjuk a CardSpace community site Samples galériájában Decrypting a Security Token (in C#) néven.

A használata pofonegyszerű: példányosítsuk meg a Token osztályt a klienstől kapott XML tokennel, majd a Claims tulajdonságon keresztül olvassuk ki a kártya egyes mezőinek értékét. Ez a tulajdonság sztringgel indexelhető, a sztringben pedig azokat a hosszú és megjegyezhetetlen séma URI-ket kell átadnunk, amiket már az OBJECT tag PARAM eleménél láttunk. Szerencsére ezek a konstansok elérhetőek a System.IdentityModel.Claims.ClaimTypes osztály tulajdonságaiként.

Az e-mail címet például így nyerhetjük ki a kártyából:

    string xmlToken = this.Server.HtmlDecode( this.hidIdentityToken.Value );
    Token token = new Token( xmlToken );
    string email = token.Claims[ ClaimTypes.Email ];

A kártyát egyedileg azonosító private personal identifiert a ClaimTypes.PPID segítségével olvashatjuk ki. Nem bonyolult ez, ha egyszer sikerül megfejteni!

Kártya adatainak tárolása és kezelése

Praktikus lenne eltárolnunk a kártya adatait egy adatbázis táblában. Az az út járható ugyanis, hogy a felhasználó beregisztrál a portálunkra, majd a személyes adatait kezelő oldalon hozzárendel egy kártyát a saját felhasználói fiókjához. Amikor legközelebb kártyával akar bejelentkezni, mi megnézzük, hogy az adott kártyához tartozik-e felhasználó és ha igen, bejelentkeztetjük.

Az én esetemben az adatbázis tábla így néz ki:

  • Id: uniqueidentifier DEFAULT( NewSequentialID() ) PK
  • UserId: uniqueidentifier
  • CardId: nvarchar( 255 )
  • DisplayName: nvarchar( 50 )

A CardId a kártya PPID-je, amiről nem találtam dokumentációt, hogy milyen hosszú lehet. Aki tudja, írja meg! A DisplayName pedig azért kell, hogy a felhasználónak meg tudjunk jeleníteni valami értelmeset a kártyáról. Össze lehet fűzni bele a givenname, surname és emailaddress claim-eket és akkor nem is kell küzdeni a kitöltésével.

Természetesen ezekhez kell írni tárolt eljárásokat, nálam ezek születtek, a nevek magukért beszélnek:

  • AddCard – kártya hozzárendelése a felhasználóhoz.
  • DeleteCard – kártya törlése.
  • GetCardsByUserId – a felhasználóhoz tartozó kártyák lekérdezése, hogy a személyes adatok oldalon meg tudjuk jeleníteni.
  • GetUserIdByCardId – bejelentkezéskor használjuk, hogy lekérdezzük az adott kártyához tartozó felhasználó azonosítóját.

Haladunk, de hátra van még, hogy ezeket a tárolt eljárásokat meghívjuk kódból. Erre sokféle megoldás létezik, mindenkinek biztosan van már kedvence, nagyon tudom javasolni a DLINQ használatát, ehhez Scott Guthrie-nál és Sahil Maliknál találunk útmutatást.

Végül ne felejtsünk el készíteni egy oldalt a bejelentkezett felhasználók számára, ahol hozzárendelhetnek kártyákat a felhasználói fiókjukhoz, megtekinthetik a korábban hozzárendelt kártyák adatait és törölhetik a hozzárendeléseket.

Utolsó lépésként pedig nem is marad más hátra, mint a felhasználó bejelentkeztetése InfoCard használatával…. Folyt. köv.

 

Technorati tags: , , ,

CardSpace és ASP.NET AJAX 4: Böngészőfüggés

Az előző részben sikerült röviden megismerkednünk az InfoCard adatok bekérésének módjával és két problémát meg is oldottunk, íme még néhány:

ASP.NET-függés

Miután bekértük a kártya adatait, a FORM submit metódusát használva, magunk küldjük el az űrlapot a szervernek. Nos, a korábban mutatott $get( "form1" ).submit(); nem bolondálló, IIS 7 alatt például a FORM ID attribútumának értéke aspnetForm. Ha nem akarunk sok kódot írni, akkor trükközhetünk (értsd: nem támogatott megoldást használunk a megoldás körülményes kódolása helyett): kihasználhatjuk, hogy az ASP.NET magának generál egy theForm nevű változót, hívhatjuk azt:

    theForm.submit();

Protokoll függés

A kártya kiválasztásához használt idenitity selector komponens csak akkor hajlandó működni, ha a kliens HTTPS kapcsolaton keresztül éri el a szervert. Ezért kellett nekünk a tanusítvány! Ne felejtsük el szegény felhasználót figyelmeztetni, hogy használjon SSL-t, mert a CardSpace hibaüzenete elég semmitmondó. Szerver oldalon például így ellenőrizhetjük annak az utolsó S-nek a meglétét:

    if( this.Request.Url.Scheme != Uri.UriSchemeHttps )
    {
        // TODO: Hibaüzenet megjelenítése, kontroll elrejtése stb.
    }

CardSpace támogatás

Nem vagyunk még túl a platformfüggés problémáin! A Windows CardSpace szolgáltatás csak akkor elérhető, ha telepítve van a .NET Framework 3.0. Ezt szokásos módon szerver oldalon tudjuk ellenőrizni a böngésző által elküldött User-Agent fejléc mező alapján, például így:

    if( this.Request.Browser.ClrVersion < new Version( "3.0.04506" ) )
    {
        // TODO: Hibaüzenet megjelenítése
    }

Persze az sehol nincs megírva, hogy a böngészőnek el kell küldenie a CLR verziószámát, tehát ebben nem bízhatunk egészen. Szerencsére Garrett Serack közzétette egy JavaScript függvény kódját, amivel mindezt kliens oldalon ellenőrizhetjük.

Garrett függvény elvileg Firefoxra is működik, azt ellenőrzi, hogy a böngésző képes-e az x-informationcard mimeType kezelésére. Bár a függvény remek, azt vettem észre, hogy a Firefoxhoz letölthető CardSpace plugin bizony nem tökéletes, ugyanis nálam következetesen kétszer olvasta ki az OBJECT tag value tulajdonságát: egyszer, amikor a saját scriptem kérte, egyszer pedig elküldés előtt, ami természetesen két identity selector ablak megjelenítését eredményezte. Csak úgy sikerült tökéletes működésre bírnom, ha kihagytam a saját scriptemet, akkor viszont nem volt HTML Encode, kénytelen voltam külön FORM-ba tenni az egészet, így pedig már nem lehetett kontrollban implementálni a kártya bekérését. A lényeg, röviden: Firefox alatt szívás van!

Mégsem

Nem foglalkoztunk még azzal, hogy mi történik akkor, ha a felhasználó rábök a kártya bekérés linkre, megkapja az identity selector ablakot, de meggondolja magát és bezárja kártya kiválasztása nélkül. A jó hír, hogy ebben az esetben az OBJECT tag value tulajdonsága undefined értékű lesz. Ezt könnyen tudjuk ellenőrizni és ebben az esetben természetesen nem küldjük el az oldalt.

Na a helyzet nem ilyen egyszerű: mindkét böngésző család esetén kivételt fogunk kapni, IE7 alatt No such interface supported, Firefox alatt pedig CardSpace Returned Error value description értékkel. Itt tagadhatatlanul a Firefox produkált értelmesebb leírást.

OK, kezeljük a hibaüzenetet, a felhasználó visszakapja az oldalt, rájön, hogy az InfoCard neki nem pálya, megadja a nevét és jelszavát, majd elküldi az oldalt. Ámde! Mi már korábban beállítottuk az OBJECT tag type tulajdonságát, amit csak akkor lehet runtime állítani, ha az még definiálatlan (pontosabban üres sztring értékű), azaz nem tudjuk kitörölni sem, ha már egyszer beállítottuk. Mi fog történni? A felhasználó megadja a nevét és jelszavát, rábök az elküldés gombra és megkapja megint az identity selector ablakot, hiszen az űrlap elküldésekor a böngésző kiolvassa a value tulajdonság értékét.

Tanulság: a Windows CardSpace-t nem nehéz implementálni önmagában, egy komplett webalkalmazáson kívül, demó környezetben. Lehet használni persze éles körülmények között is, de szedjünk hozzá nyugibogyót.

Folyt.köv.

 

Technorati tags: , ,