ASP.NET Alapozó 6. gyak Authentikáció és Authorizáció 1. feladat
Authentikáció és Authorizáció A gyakorlaton megoldandó feladat Egy leegyszerűsített online műszaki áruházat szeretnénk megvalósítani, mely jelenesetben két oldalból fog állni. Az egyik oldalon kilistázzuk az akciós termékeket, melyeknek az árait csak a bejelentkezett felhasználók láthatják. A másik oldalon pedig felületet biztosítunk az oldal tulajdonosának a termékek szerkesztésére.
Áttekintés Eme alkalmazáson keresztül megismerkedünk a felhasználók azonosításával, illetve a jogosultságok kezelésével ASP.NET-ben. Az alábbi új vezérlőket, technikákat, illetve segédeszközt fogjuk felhasználni a feladat megvalósítása során: Login, LoginView, CreateUserWizard, Authentication, Authorization, WebSite Administration Tool, stb.
Probléma - Tervezés Ahogyan a való életben úgy a webes alkalmazásoknál is gyakran felmerülő igény a személy (kliens) azonosítása. Mindenki rendelkezik valamilyen azonosítóval (vagy rendszer által generált, vagy általunk választott), viszont ez nem mindig elég ahhoz, hogy bebizonyítsuk, tényleg azok vagyunk, akiknek mondjuk magunkat. Emiatt a valóéletben általában valamilyen egyedi jellemzővel (arc fényképpel, ujjlenyomattal, retina szerkezettel, stb.) együtt történik az azonosítás folyamata, míg a web-es világban általában valamilyen titok/jelszó/jelmondat segítségével valósul meg ugyanez. (A továbbiakban a felhasználónév, jelszó páros érvényességének ellenőrzősére, mint a felhasználók azonosítása/hitelesítése (Authentication) fogunk hivatkozni.) Miután megtörtént az adott felhasználó hitelesítése, utána a rendszer feladata, hogy eldöntse mely műveletekhez, oldalakhoz van hozzáférési joga. Teljesen hasonlóan, mint a való életben: vannak, akik egyenlőbbek az egyenlők között, vagyis vannak, akik több jogosultsággal bírnak a többieknél, vagy jobb szolgáltatásokhoz férhetnek hozzá. A hozzáférési jogok eldöntésének folyamatát jogosultságkezelésnek (Authorization) nevezzük alkalmazások esetén. ASP.NET-ben ez mappa, illetve szerepkör alapú. Vagyis a könyvtáraknak tudjuk a hozzáférési jogait korlátozni felhasználók egy-egy csoportjára. ASP.NET 2.0 óta a rendszer szerves részét képezi a felhasználó-azonosítás, illetve jogosultságkezelés. Ezen szolgatatások beállításához kapunk egy egyszerű, de jól használható web-es felületet, amelyet WebSite Administration Tool-nak vagy ASP.NET Configuration-nek hívnak. (a továbbiakban WSAT). Az ezen szolgáltatások által használt, illetve generált adatokat egy úgynevezett ASPNETDB.mdf fájlban tárolja az ASP.NET az App_Data könyvtáron belül (alap esetben). Ehhez a wwwroot szintű web.config-ban tárolódik egy connectionstring LocalSqlServer néven, amely természetesen az alkalmazásban felülírható. (remove (vagy clear) + add tag együttes használata)
ASP.NET Alapozó 6. gyak Authentikáció és Authorizáció 1. feladat
Megvalósítás A Starter projektben található néhány segédfájl, amelyeket az alkalmazás fejlesztése során fel fogunk használni. Adatforrásként most egy xml fájlt1 fogunk használni, amelyben a műszaki cikkek adatai találhatóak. (lásd 1. Függelék). Az ebből történő adatkinyerést a DAL osztály GetAllElectronics metódusa valósítja meg, míg ennek a frissítéséért az Update metódus a felelős (lásd 2. Függelék). ----------------------------------------------------------------------------------------------------Először készítsük el a felhasználó azonosításért felelős felületet. (Pontosabban, inkább csak magyarosítsuk.) Az Account könyvtár Login.aspx oldala pontosan ezt a funkciónalítást valósítja meg. Az oldal markup kódjában található egy Login vezérlő, amely nem a standard megjelenítést használja. Íme, egy összehasonló kép az alap és az úgynevezett template-esített verziókhoz.
A template-ezhetőség nagy előnye, hogy így könnyen az oldalunk kinézetéhez alakíthatjuk a vezérlőket úgy, hogy közben minden funkcionalitásuk megmarad. Template-esíteni úgy lehet egy Login vezérlőt, hogy a gyorsmenüjében a Convert to template menüpontot válasszuk. A vezérlők elrendezése teljesen átszabható, viszont a vezérlők azonosítója kötött! (pl.: UserName, az a TextBox, amibe a felhasználónév került; RememberMe, az a CheckBox, amellyel engedélyezni lehet az azonosításhoz szükséges adatok sütiben történő tárolását; LoginButton, az a Button vezérlő, melyre kattintva a felhasználónév jelszó páros ellenőrzésre kerül). Természetesen a LayoutTemplate felüldefiniálása esetén a Validator vezérlőkről is nekünk kell gondoskodnunk. ----------------------------------------------------------------------------------------------------Most a Register.aspx oldalt magyarosítsuk annak érdekében, hogy a felhasználók tudjanak regisztrálni az oldalunkon. Ehhez egy némileg átalakított vezérlőt használunk, amely nem más, mint az úgynevezett CreateUserWizard (a továbbiakban CUW). Íme, ismét egy összehasonlító kép:
1
A webes világban a relációs adatbázisok mellett gyakran szokás xml-t (, mint félig strukturált adatszerkezetet) használni adatok tárolására, főképp a szabványos mivolta miatt mely elősegíti a különböző rendszerek közötti kommunikációt. Gyakori használata miatt ebben a példaalkalmazásban xml alapú adatforrást használunk.
ASP.NET Alapozó 6. gyak Authentikáció és Authorizáció 1. feladat
Alapjában véve két oldalból (WizardStep-ből) áll ez a varázsló. Az első oldalon (CreateUserWS) összegyűjtjük a felhasználó adatait, míg a másodikon (CompletedWS) értesítjük a sikeres regisztrációról. Amennyiben szükségünk lenne extra információkra is a regisztráló személyről, abban az esetben létrehozhatunk saját varázsló oldalakat (WizardStep-eket) is, (vagy kibővíthetjük akár az első oldalt is a template-sítés után). Ezeket a CUW gyorsmenüjében az Add new WizardStep menüponttal tudjuk megtenni. Az ilyen oldalakon összegyűjtött információk eltárolásáért mi vagyunk a felelősek, ezért érdemes a CreatedUser vagy a ContinueButtonClick nevű eseményre feliratkozni. ----------------------------------------------------------------------------------------------------Gyakori feladat szokott lenni webes alkalmazásoknál, hogy attól függően, hogy a felhasználó be van-e már jelentkezve vagy még nem, különböző adatot/vezérlőt/felületet jelenítsünk meg a számára. Ehhez nagy segítség lehet a LoginView vezérlő, amelynek két külön sablonja van az előbb említett két állapothoz (AnonymousTemplate, LoggedInTemplate)2. Ezeken belül bármilyen tartalom elhelyezhető. Mi jelenesetben ezt arra fogjuk használni, hogy az árakat csak a bejelentkezett felhasználóknak jelenítsük meg. Ennek a kódja az alábbi módon áll össze:
Csak belépetteknek <%# Eval("Price", "{0} Ft") %>
----------------------------------------------------------------------------------------------------A jogosultságkezelést először engedélyeznünk kell. Ehhez indítsuk el a WSAT-ot. A Solution Explorerben kattintsunk az alábbi ikonra: , vagy válasszuk a Website >> ASP.NET Configuration menüpontot. Ha elindult a böngészőben az oldal, akkor kattintsunk a Security linkre. Ezek után a középső blokkban (Roles) kattintsunk az Enabled Roles linkre. Majd a Create or Manage rules linkre való kattintás után írjunk be a szövegdobozba, hogy admin. Végül kattintsunk az Add role-ra, majd utána pedig a Back gombra. Így, sikeresen létrehoztunk egy szerepkört.
2
A View-k közötti váltás automatikus. A User segédosztály Indentity.IsAuthenticated tulajdonságától függően jeleníti meg a megfelelő felületet.
ASP.NET Alapozó 6. gyak Authentikáció és Authorizáció 1. feladat Most adjuk hozzá valamelyik felhasználót ehhez a szerepkörhöz. A Security oldal legbaloldaliabb (Users) blokkjában kattintsunk a Manage users linkre. Itt keressük ki a megfelelő felhasználót, majd klikkeljünk az Edit Roles-ra. Ilyenkor a jobboldalon meg fog jelenni egy újabb panel, ahonnan kiválaszthatjuk, melyik szerepkörhöz szeretnénk hozzáadni az adott felhasználót. Jelenesetben az admin-t pipáljuk be, majd kattintsunk a Back gombra. Végezetül hozzuk létre a szabályokat. A legjobboldalibb blokkban (Access Rules) klikkeljünk a Create access rules linkre. A Select a directory for this rule címke alatt található Treeview vezérlőben keressük meg azt a mappát, amelynek a hozzáférési jogait korlátozni szeretnénk, jelenesetben ez az Admin könyvtár. A Rule applies to felirat alatt most válasszuk ki a Role admin-t, a Permission-nél pedig az Allow legyen bekattintva. Végül klikkeljünk az OK gombra. Így már van hozzáférési joga az admin csoporthoz tartozó felhasználóknak az Admin mappához, viszont a többi felhasználónak is, ezért ezt tiltsuk le. Ismét navigáljunk el a Create access rules oldalra, majd az alábbi módon állítsuk be a vezérlőket: Select a directory for this rule: Admin; Rule applies to: All users; Permission: Deny. Ezek után már ténylegesen csak az admin jogokkal rendelkező felhasználók jogosultak az Admin könyvtár megtekintésére. A Manage access rules alatt, ha megnézzük az admin könyvtárat, akkor azt láthatjuk, hogy 3 szabály van hozzá, pedig mi csak kettőt hoztunk létre. Ez azért van így, mivel alapból minden felhasználó hozzáférhet bármelyik fájlhoz. (Ezért volt szükség a 2. szabályra.) Értelemszerűen a tiltás erősebb, mint az engedélyezés, emiatt Allow [all] valójában nincs is ott. [Lépésről lépésre 12 képen keresztül]
Képernyőképek A főoldalon egy ListView vezérlővel jelenítjük meg a műszaki cikkeket. A dolog érdekessége, hogy nem egymás alatt vannak felsorolva az elemek, hanem 3 cikk található egy sorban. Ez két egyszerű css beállításnak köszönhető (display: inline; float: left). Az admin oldalon egy DetailsView található.
ASP.NET Alapozó 6. gyak Authentikáció és Authorizáció 1. feladat
1. Függelék – Electronics.xml ]> <electornics> <device image="imgs/hdtv.png" price="120000">HD TV <device image="imgs/tv.png" price="75000">TV <device image="imgs/mobile.png" price="30000">Mobil <device image="imgs/pocket_pc.png" price="60000">Noteszgép <device image="imgs/mp3_player.png" price="10000">MP3-lejátszó <device image="imgs/video_camera.png" price="100000">Kamera <device image="imgs/camera.png" price="80000">Fényképező <device image="imgs/speakers.png" price="60000">Hangszoró <device image="imgs/printer.png" price="40000">Nyomtató <device image="imgs/washing_machine.png" price="90000">Mosogató
2. Függelék – DAL.cs public class DAL { private static List
devices; private static string xmlpath = Server.MapPath("~//App_Data//Electronics.xml"); public static List GetAllElectronics() { if(devices == null) LoadDevices(); return devices; } public static void Update(Device d) { XDocument doc = XDocument.Load(xmlpath); var modified = (from device in doc.Descendants("device") where (string)device.Value == d.Name select device).First(); modified.SetValue(d.Name); modified.SetAttributeValue("price", d.Price); modified.SetAttributeValue("image", d.ImageUrl); doc.Save(xmlpath); LoadDevices(); } private static void LoadDevices() { XDocument doc = XDocument.Load(xmlpath); devices = (from device in doc.Descendants("device") select new Device { Name = (string)device.Value, Price = (int)device.Attribute("price"), ImageUrl = (string)device.Attribute("image") }).ToList(); } } public class Device { public string Name { get; set; } public string ImageUrl { get; set; } public int Price { get; set; } }