ASP.NET MVC v praxi od A do Z, 11. díl – Autentizace a autorizace
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

ASP.NET MVC v praxi od A do Z, 11. díl – Autentizace a autorizaceASP.NET MVC v praxi od A do Z, 11. díl – Autentizace a autorizace

 

ASP.NET MVC v praxi od A do Z, 11. díl – Autentizace a autorizace

Google       Google       16. 9. 2009       14 834×

Momentálně může kterýkoliv uživatel naší aplikace vytvářet a upravovat detaily o všech večeřích. Měli bychom tuto svobodu trochu omezit, a proto dnes zavedeme podporu pro registrace a přihlašování.

Reklama
Reklama

Pro začátek si uděláme trochu pořádek v terminologii a vysvětlíme si, co to je autentizace a autorizace.

Autentizace

Autentizace si klade za cíl zjistit, kdo uživatel je. ASP.NET podporuje hned několik typů autentizace, například Windows nebo Passport autentizaci, ale nejčastěji používaná je Forms autentizace. Ta nám umožňuje vytvořit si vlastní formulář pro přihlašování (zatímco u Windows autentizace se objeví systémový přihlašovací dialog a u Passport je uživatel přesměrován na jiný web) a zadané údaje pak jsou porovnány s databází (nebo jiným úložištěm). Pokud je kombinace jména a hesla správná, můžeme vytvořit cookie, která bude jakýmsi „průkazem totožnosti“ uživatele během užívání aplikace. Forms autentizaci použijeme i my.

Autorizace

Jakmile je uživatel autentizován, můžeme přejít k autorizaci. Ta zjišťuje, jaká má přihlášený uživatel práva přístupu k různým částem aplikace nebo k provedení nějaké akce. My například budeme chtít, aby jen přihlášení uživatelé mohli otevřít URL „/Dinners/Create“ a aby večeře mohl upravit jen ten, kdo je vytvořil.

AccountController

Výchozí aplikace, kterou ASP.NET MVC vytvoří do nového projektu, už v základu umožňuje formulářovou autentizaci a registrace, včetně všech potřebných formulářů. Velmi to usnadňuje práci, my vlastně nemusíme dělat vůbec nic. Já jen počeštil jednotlivé views, které najdete v adresáři „/Views/Account/“.

Zkusíme se zaregistrovat, takže aplikaci spustíme a klikneme na tlačítko „Přihlásit“ vpravo nahoře. Svůj účet ještě nemáme, proto přejdeme na stránku s registrací pomocí odkazu na stránce.

Stačilo rovnou zadat URL „/Account/Register“, ale proč se na chvíli nevžít do role uživatele? Na této stránce už se můžeme zaregistrovat:

O celé přihlašování, odhlašování a registrace se stará AccountController, který byl vytvořen společně s MVC projektem. Tento controller využívá známé Membership API, pomocí kterého spravuje všechny zaregistrované uživatele uložené v databázi. Pokud v Solution Exploreru klikneme na tlačítko „Show All Files“, pak tento databázový soubor uvidíme v adresáři App_Data:

Omezení přístupu k /Dinners/Create

Registrace už máme (vlastně jsme je měli už od začátku), ale vytvářet večeře pořád může i anonymní uživatel. Zamezení přístupu nezaregistrovaným uživatelům k metodě Create je dost snadné, stačí jen přidat atribut Authorize:

// GET: /Dinners/Create
[Authorize]
public ActionResult Create()
{
    // implementace
}

// POST: /Dinners/Create
[AcceptVerbs(HttpVerbs.Post), Authorize]
public ActionResult Create(Dinner dinner)
{
    // implementace
}

ASP.NET MVC totiž umožňuje tvorbu tzv. „akčních filtrů“ (action filters), které pak můžeme deklarativně aplikovat na akční metody, případně i třídy. Authorize je jedním z nich, díky němu můžeme nařídit, aby uživatel musel být přihlášený, pokud chce označenou metodu zavolat. Když nebude přihlášený, bude automaticky přesměrován na stránku s přihlašovacím formulářem. Pokud k tomuto dojde, předá se původní URL jako querystring parametr (například /Account/LogOn?ReturnUrl=%2fDinners%2fCreate) a jakmile se uživatel přihlásí, bude přesměrován zpět na stránku, kterou se pokoušel otevřít.

Pokud chceme, můžeme specifikovat i jednotlivé povolené uživatele, případně uživatelské role. Požadavek pak bude takový, aby uživatel byl zároveň přihlášený a zároveň přítomen mezi specifikovanými uživateli. Takhle vypadá kód, který dovolí přístup jen uživateli se jménem Chrasty:

// GET: /Dinners/Create
[Authorize(Users = "Chrasty")]
public ActionResult Create()
{
    // ...
}

Je asi jasné, že ručně vypisovat jednotlivé uživatele je trochu nepraktické, proto je lepším způsobem rozčlenit uživatele do rolí (například administrátoři, moderátoři, uživatelé, …) a nastavit atribut Authorize následovně:

// GET: /Dinners/Create
[Authorize(Roles = "admin")]
public ActionResult Create()
{
    // ...
}

My se obejdeme bez jakýchkoli úprav a jen nám bude stačit, aby byl uživatel přihlášený.

Vlastnost User.Identity.Name při vytváření večeří

Jméno přihlášeného uživatele můžeme získat kdekoliv v aplikaci pomocí vlastnosti User.Identity.Name, takže toho hned využijeme v POST verzi metody Create, kde jsme doteď měli natvrdo nastaveného zakladatele večeře na „Někdo“. Když už jsme u toho, tak rovnou ke každé nově vytvořené večeři automaticky přidáme i jeden RSVP objekt reprezentující prvního účastníka – hostitele večeře.

// POST: /Dinners/Create
[AcceptVerbs(HttpVerbs.Post), Authorize]
public ActionResult Create(Dinner dinner)
{
    if (ModelState.IsValid)
    {
        try
        {
            dinner.HostedBy = User.Identity.Name;

            RSVP rsvp = new RSVP();
            rsvp.AttendeeName = User.Identity.Name;
            dinner.RSVPs.Add(rsvp);

            dinnerRepository.Add(dinner);
            dinnerRepository.Save();

            return RedirectToAction("Details", new { id = dinner.DinnerID });
        }
        catch
        {
            ModelState.AddRuleViolations(dinner.GetRuleViolations());
        }
    }

    return View(new DinnerFormViewModel(dinner));
}

Nemusíme vůbec kontrolovat, jestli náhodou User.Identity.Name není null, protože aby se metoda Create vůbec zavolala, musí být uživatel přihlášený, tudíž tato vlastnost bude vždy obsahovat nějaké jméno.

Vlastnost User.Identity.Name při upravování večeří

Teď ještě nastavíme, aby uživatel mohl upravit večeři, jen pokud ji sám vytvořil.

Vytvoříme si pomocnou metodu IsHostedBy uvnitř třídy Dinner. Tato metoda bude vracet true nebo false v závislosti na tom, zda se předané jméno v parametru rovná hodnotě vlastnosti HostedBy (mimo to během porovnávání ignoruje velikost písmen):

public bool IsHostedBy(string userName)
{
    return HostedBy.Equals(userName, StringComparison.InvariantCultureIgnoreCase);
}

Stejně jako při vytváření večeří, i tady přidáme atribut Authorize k akčním metodám Edit. Pak zavoláme naši novou metodu IsHostedBy, abychom porovnali, zda se přihlášené jméno rovná hostiteli upravované večeře. Pokud to tak není, zobrazíme chybový view „InvalidOwner“ (viz níže):

// GET: /Dinners/Edit/2
[Authorize]
public ActionResult Edit(int id)
{
    Dinner dinner = dinnerRepository.GetDinner(id);
    if (!dinner.IsHostedBy(User.Identity.Name))
        return View("InvalidOwner");

    return View(new DinnerFormViewModel(dinner));
}

// POST: /Dinners/Edit/2
[AcceptVerbs(HttpVerbs.Post), Authorize]
public ActionResult Edit(int id, FormCollection formValues)
{
    Dinner dinner = dinnerRepository.GetDinner(id);
    if (!dinner.IsHostedBy(User.Identity.Name))
        return View("InvalidOwner");
    try
    {
        UpdateModel(dinner);
        dinnerRepository.Save();

        return RedirectToAction("Details", new {id = dinner.DinnerID});
    }
    catch
    {
        ModelState.AddRuleViolations(dinner.GetRuleViolations());

        return View(new DinnerFormViewModel(dinner));
    }
}

Musíme přidat šablonu InvalidOwner, jak se dělá, už určitě víte. Není nutné cokoliv nastavovat, jen ji pojmenujte „InvalidOwner“ a vložte do ní tento kód:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
    Tato večeře není Vaše
</asp:Content>

<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Chyba při přístupu k večeři</h2>

    <p>Omlouvám se, ale jen hostitel večeře ji může upravit nebo smazat.</p>

</asp:Content>

Stejný postup použijeme i pro metody Delete – opět jim dáme atribut Authorize a vložíme do nich na vhodné místo kontrolu uživatelského jména a zobrazení naší nové view šablony.

Zobrazení/skrytí odkazů pro úpravu a mazání

Momentálně zobrazujeme odkazy pro smazání a upravování večeří každému uživateli bez výjimky. To teď upravíme, aby je viděl jen hostitel večeře. Bude to skutečně snadné, stačí jen vlézt do šablony Details a před zobrazením odkazů přidat jednoduchou podmínku:

<% if (Model.IsHostedBy(Context.User.Identity.Name)) { %>
    <%= Html.ActionLink("Upravit večeři", "Edit", new { id = Model.DinnerID })%>
    <%= Html.ActionLink("Smazat večeři", "Delete", new { id = Model.DinnerID })%>
<% } %>

To je zase jednou vše, příště uvidíme, jak umožnit zalogovaným uživatelům přihlášení k různým večeřím s použitím AJAXu.

Zdroj: http://nerddinnerbook.s3.amazonaws.com/Part9.htm

×Odeslání článku na tvůj Kindle

Zadej svůj Kindle e-mail a my ti pošleme článek na tvůj Kindle.
Musíš mít povolený příjem obsahu do svého Kindle z naší e-mailové adresy kindle@programujte.com.

E-mailová adresa (např. novak@kindle.com):

TIP: Pokud chceš dostávat naše články každé ráno do svého Kindle, koukni do sekce Články do Kindle.

Hlasování bylo ukončeno    
0 hlasů
Google
(fotka) Jakub KottnauerJakub studuje informatiku na FIT ČVUT, jeho oblíbenou platformou je .NET.
Web     Twitter     Facebook     LinkedIn    

Nové články

Obrázek ke článku NEWTON Media prohledá 200  milionů mediálních zpráv během sekund díky Cisco UCS

NEWTON Media prohledá 200 milionů mediálních zpráv během sekund díky Cisco UCS

Česká společnost NEWTON Media provozuje největší archiv mediálních zpráv ve střední a východní Evropě. Mezi její zákazníky patří například ministerstva, evropské instituce nebo komerční firmy z nejrůznějších oborů. NEWTON Media rozesílá svým zákazníkům každý den monitoring médií podle nastavených klíčových slov a nabízí online službu, kde lze vyhledat mediální výstupy v plném znění od roku 1996.

Reklama
Reklama
Obrázek ke článku Delphi 10.1.2 (Berlin Update 2) – na co se můžeme těšit

Delphi 10.1.2 (Berlin Update 2) – na co se můžeme těšit

Touto roční dobou, kdy je zem pokrytá barevným listím a prsty křehnou v mrazivých ránech, se obvykle těšíme na zbrusu novou verzi RAD Studia. Letos si však ale budeme muset počkat na Godzillu a Linux až do jara. Vezměme tedy za vděk alespoň updatem 2 a jelikož dle vyjádření pánů z Embarcadero se budou nové věci objevovat průběžně, pojďme se na to tedy podívat.

Obrázek ke článku Konference: Moderní datová centra pro byznys dneška se koná už 24. 11.

Konference: Moderní datová centra pro byznys dneška se koná už 24. 11.

Stále rostoucí zájem o cloudové služby i maximální důraz na pružnost, spolehlivost a bezpečnost IT vedou k výrazným inovacím v datových centrech. V infrastruktuře datových center hraje stále významnější roli software a stále častěji se lze setkat s hybridními přístupy k jejich budování i provozu.

Obrázek ke článku Konference: Mobilní technologie mají velký potenciál pro byznys

Konference: Mobilní technologie mají velký potenciál pro byznys

Firmy by se podle analytiků společnosti Gartner měly  rychle přizpůsobit skutečnosti, že mobilní technologie už zdaleka nejsou horkou novinkou, ale standardní součástí byznysu. I přesto - nebo možná právě proto - tu nabízejí velký potenciál. Kde tedy jsou ty největší příležitosti? I tomu se bude věnovat již čtvrtý ročník úspěšné konference Mobilní řešení pro business.

loadingtransparent (function() { var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; po.src = 'https://apis.google.com/js/plusone.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })();
Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý