Tato kapitola ukazuje, jak zabezpečit web tak, aby některé stránky byly dispozici pouze přihlášeným uživatelům. (Dozvíte se také, jak vytvořit stránky, ke kterým může přistupovat kdokoli.)
Co se naučíte:
V této kapitole budou představeny následující funkce technologie ASP.NET:
WebSecuritySimpleMembershipReCaptcha
Svůj web můžete nastavit tak, aby se k němu uživatelé mohli přihlásit, tedy aby podporoval členství. To může být užitečné z mnoha důvodů. Web například může mít funkce, které jsou k dispozici pouze pro členy. V některých případech můžete požadovat, aby se uživatelé přihlásili, pokud vám chtějí zaslat své podněty nebo přidat komentář.
I pokud web podporuje členství, není nutné, aby se uživatelé museli vždy nejdříve přihlásit, pokud chtějí používat některé stránky na webu. Nepřihlášení uživatelé jsou označováni jako anonymní uživatelé.
Uživatelé se mohou na webu zaregistrovat a poté se k němu přihlásit. Web vyžaduje uživatelské jméno (často to bývá e-mailová adresa) a heslo pro potvrzení toho, že uživatel je tím, za koho se vydává. Proces přihlášení a potvrzení identity uživatele bývá označován jako ověřování.
V prostředí WebMatrix můžete pomocí šablony Starter Site (Počáteční web) vytvořit web obsahující následující funkce:
// označeny jako komentáře:@{ WebSecurity.InitializeDatabaseConnection("StarterSite", "UserProfile", "UserId", "Email", true); // WebMail.SmtpServer = "mailserver.example.com"; // WebMail.EnableSsl = true; // WebMail.UserName = "username@example.com"; // WebMail.Password = "your-password"; // WebMail.From = "your-name-here@example.com"; }
K odesílání e-mailů můžete použít pomocnou třídu WebMail (Webová pošta). Ta následně vyžaduje přístup k serveru SMTP, jak popisuje kapitola 11 – Přidání e-mailu na web. V této kapitole jste se dozvěděli, jak nastavit různá nastavení protokolu SMTP v jedné stránce. V této kapitole použijeme stejná nastavení, ale uložíme je v jednom centrálním souboru, aby nebylo třeba neustále přidávat kód do všech stránek. (Pro zřízení registrační databáze není nutné konfigurovat nastavení protokolu SMTP. Nastavení protokolu SMTP jsou zapotřebí pouze v případě, že budete chtít ověřovat uživatele z jejich e-mailové adresy nebo jim poskytnout možnost vytvořit nové heslo pro případ, že své heslo zapomenou.)
// před jednotlivými příkazy.)WebMail.SmtpServer (Webová pošta.Server SMTP) nastavte na název serveru SMTP, ke kterému máte přístup.WebMail.EnableSsl (Webová pošta.Povolit SSL) ponechte nastavenou na hodnotu true. Toto nastavení zajišťuje zabezpečení přihlašovacích údajů zasílaných SMTP serveru jejich zašifrováním. WebMail.UserName (Webová pošta.Uživatelské jméno) nastavte na uživatelské jméno pro váš účet na serveru SMTP.WebMail.Password (Webová pošta.Heslo) nastavte na heslo pro váš účet na serveru SMTP.WebMail.From (Webová pošta.Od) nastavte na svou vlastní e-mailovou adresu. Jedná se o e-mailovou adresu, ze které bude zpráva odeslána.Při vytvoření webu ze šablony Starter Site (Počáteční web) byla na webu ve složce App_Data vytvořena databáze s názvem StarterSite.sdf. Při registraci jsou vaše uživatelské informace přidány do této databáze. Na uvedenou e-mailovou adresu je odeslána zpráva umožňující registraci dokončit.
Po přihlášení budou odkazy Login (Přihlásit se) a Register (Zaregistrovat) nahrazeny odkazem Logout (Odhlásit se).
Bude zobrazena stránka About.cshtml. Po přihlášení je zatím jedinou viditelnou změnou změněný stav přihlášení – zpráva Welcome Joe! (Vítejte, Joe!) a odkaz Logout (Odhlásit se).
WebMail.EnableSsl=true stejně jako v předchozím příkladu. Další informace o protokolu SSL získáte v článku Zabezpečení komunikace na webu: certifikáty, SSL a https://.Prozatím kdokoli může procházet všechny stránky na webu. Ale možná chcete mít stránky, které jsou k dispozici jen pro přihlášené uživatele (tj. členy). ASP.NET umožňuje nakonfigurovat stránky tak, aby k nim měli přístup jen přihlášení členové. Když se anonymní uživatel pokusí přistoupit ke stránce určené pouze pro členy, je obvykle přesměrován na stránku pro přihlášení.
V rámci tohoto postupu omezíme přístup ke stránce About (O webu), About.cshtml, tak, aby k ní měli přístup jen přihlášení členové.
IsAuthenticated (Je ověřen) objektu WebSecurity (Zabezpečení webu), která vrací hodnotu true, pokud je uživatel přihlášen. V opačném případě kód volá metodu Response.Redirect (Odpověď.Přesměrovat), čímž uživatele přesměruje na stránku Login.cshtml (Přihlášení) ve složce Account (účet). Kompletní soubor About.cshtml vypadá takto:
@if (!WebSecurity.IsAuthenticated) { Response.Redirect("/Account/Login"); } @{ Layout = "/_SiteLayout.cshtml"; Page.Title = "About My Site"; } <p> This web page was built using ASP.NET Web Pages. For more information, visit the ASP.NET home page at <a href="http://www.asp.net" target="_blank">http://www.asp.net</a> </p>
Pro zabezpečení přístupu k více stránkám můžete buď přidat kontrolu zabezpečení do všech stránek, nebo můžete vytvořit stránku s rozložením podobnou stránce _SiteLayout.cshtml, která zahrnuje kontrolu zabezpečení. Na tuto stránku obsahující kontrolu zabezpečení byste se pak odkazovali z ostatních stránek na webu, stejně jako se stránka Default.cshtml momentálně odkazuje na stránku _SiteLayout.cshtml.
Pokud má web hodně členů, není efektivní, abyste kontrolovali oprávnění jednotlivých uživatelů předtím, než jim umožníte si stránku prohlédnout. Místo toho můžete vytvořit skupiny neboli role, do nichž jednotliví členové patří. Oprávnění pak můžete kontrolovat na základě rolí. V této části vytvoříme roli „admin“ (správce) a poté vytvoříme stránku přístupnou uživatelům, kteří jsou součástí (patří do) této role.
Nejdříve musíme přidat informace o rolích do databáze členů.
Teď, když jsou role nadefinované, můžeme stránku nakonfigurovat tak, aby byla přístupná uživatelům, kteří patří do této role.
@{ Layout = "/_SiteLayout.cshtml"; PageData["Title"] = "Admin-only Error"; } <p>You must log in as an admin to access that page.</p>
@{ Layout = "/_SiteLayout.cshtml"; PageData["Title"] = "Administrators only"; } @if ( Roles.IsUserInRole("admin")) { <span> Welcome <b>@WebSecurity.CurrentUserName</b>! </span> } else { Response.Redirect("/AdminError"); }
Metoda Roles.IsUserInRole (Role.Je uživatel v roli) vrací hodnotu true, pokud je aktuální uživatel členem role „admin“ (správce).
Uživatelům můžete poskytnout možnost změnit své heslo tak, že vytvoříte stránku pro změnu hesla. Tento příklad ukazuje základy stránky vytvořené za tímto účelem. (Součástí šablony Starter Site je soubor ChangePassword.cshtml obsahující úplnější kontrolu chyb než stránka, kterou vytvoříte v rámci tohoto postupu.)
@{ Layout = "/_SiteLayout.cshtml"; PageData["Title"] = "Change Password"; var message = ""; if(IsPost) { string username = Request["username"]; string newPassword = Request["newPassword"]; string oldPassword = Request["oldPassword"]; if(WebSecurity.ChangePassword(username, oldPassword, newPassword)) { message="Password changed successfully!"; } else { message="Password could not be changed."; } } } <style> .message {font-weight:bold; color:red; margin:10px;} </style> <form method="post" action=""> Uživatelské jméno: <input type="text" name="username" value="@WebSecurity.CurrentUserName" /> <br/> Old Password: <input type="password" name="oldPassword" value="" /> <br/> New Password: <input type="password" name="newPassword" value="" /> <br/><br/> <input type="submit" value="Change Password" /> <div class="message">@message</div> <div><a href="Default.cshtml">Return to home page</a></div> </form>
Tělo stránky obsahuje textová pole, pomocí nichž uživatelé mohou zadat své uživatelské jméno a staré a nové heslo. V kódu voláme metodu ChangePassword (Změnit heslo) pomocné třídy WebSecurity (Zabezpečení webu) a předáváme jí hodnoty, které jsme získali od uživatele.
WebSecurity.ChangePassword (Zabezpečení webu.Změnit heslo) bude neúspěšné a bude zobrazena chybová zpráva.Pokud uživatelé zapomenou své heslo, můžete jim dovolit, aby vygenerovali heslo nové. (Je to něco jiného než změna hesla, které znají.) Abychom uživatelům umožnili získat nové heslo, vygenerujeme token pomocí metody GeneratePasswordResetToken (Vygenerovat token pro vytvoření nového hesla) pomocné třídy WebSecurity (Zabezpečení webu). (Token je kryptograficky zabezpečený řetězec odeslaný uživateli, který uživatele jednoznačně identifikuje, například za účelem vytvoření nového hesla.) Tento postup ukazuje typický způsob, jak to všechno lze provést – vygenerovat token, odeslat jej uživateli v e-mailu a poté jej odkázat na stránku, která token přečte a umožní uživateli zadat nové heslo. Odkaz, který uživatel obdrží v e-mailu, bude vypadat přibližně takto:
http://localhost:36916/Account/PasswordReset2?PasswordResetToken=08HZGH0ALZ3CGz3
Náhodně vypadající znaky na konci adresy URL představují token.
(Součástí šablony Starter Site je soubor ForgotPassword.cshtml, který obsahuje úplnější kontrolu chyb než níže uvedený příklad.)
@{ Layout = "/_SiteLayout.cshtml"; PageData["Title"] = "Forgot your password?"; var message = ""; var username = ""; if (WebMail.SmtpServer.IsEmpty() ){ // Výchozí konfigurace protokolu SMTP probíhá v souboru _start.cshtml. message = "Please configure the SMTP server."; } if(IsPost) { username = Request["username"]; var resetToken = WebSecurity.GeneratePasswordResetToken(username); var portPart = ":" + Request.Url.Port; var confirmationUrl = Request.Url.Scheme + "://" + Request.Url.Host + portPart + VirtualPathUtility.ToAbsolute("/Account/PasswordReset2?PasswordResetToken=" + Server.UrlEncode(resetToken)); WebMail.Send( to: username, subject: "Password Reset", body: @"Your reset token is:<br/><br/>" + resetToken + @"<br/><br/>Visit <a href=""" + confirmationUrl + @""">" + confirmationUrl + @"</a> to activate the new password." ); message = "An email has been sent to " + username + " with a password reset link."; } } <style> .message {font-weight:bold; color:red; margin:10px;} </style> <form method="post" action=""> @if(!message.IsEmpty()) { <div class="error">@message</div> } else{ <div> Enter your email address: <input type="text" name="username" /> <br/> <br/><br/> <input type="submit" value="Get New Password" /> </div> } </form>
Tělo stránky obsahuje textové pole, které uživatele vyzývá k zadání e-mailové adresy. Když uživatel formulář odešle, nejprve ověříme, že byl nastaven protokol SMTP pro pomocnou třídu Mail, protože účelem této stránky je odeslání e-mailu.
Jádrem stránky je vygenerování tokenu pro vytvoření nového hesla, což provedeme následujícím způsobem a předáme při tom e-mailovou adresu (uživatelské jméno) poskytnutou uživatelem:
string resetToken = WebSecurity.GeneratePasswordResetToken(username);
Zbytek kódu je určen pro odeslání e-mailové zprávy. Většina kódu byla převzata ze souboru Register.cshtml, který je součástí webu vytvořeného ze šablony.
Vlastní odeslání e-mailu provedeme s použitím pomocné třídy WebMail (Webová pošta) voláním její metody Send (Odeslat). Tělo e-mailu je vytvořeno zřetězením proměnných a řetězců, které obsahující text a také elementy jazyka HTML. Tělo e-mailu, který uživatel obdrží, vypadá asi takto:
@{ Layout = "/_SiteLayout.cshtml"; PageData["Title"] = "Password Reset"; var message = ""; var passwordResetToken = ""; if(IsPost) { var newPassword = Request["newPassword"]; var confirmPassword = Request["confirmPassword"]; passwordResetToken = Request["passwordResetToken"]; if( !newPassword.IsEmpty() && newPassword == confirmPassword && WebSecurity.ResetPassword(passwordResetToken, newPassword)) { message = "Password changed!"; } else { message = "Password could not be reset."; } } } <style> .message {font-weight:bold; color:red; margin:10px;} </style> <div class="message">@message</div> <form method="post" action=""> Enter your new password: <input type="password" name="newPassword" /> <br/> Confirm new password: <input type="password" name="confirmPassword" /><br/> <br/> <input type="submit" value="Submit"/> </form>
Tato stránka je spuštěna, když uživatel klikne na odkaz v e-mailu pro vytvoření nového hesla. Tělo stránky obsahuje textová pole, pomocí nichž uživatel může zadat a potvrdit nové heslo.
Token pro vytvoření nového hesla získáme z adresy URL přečtením položky Request["PasswordResetToken"]. Musíte mít na paměti, že adresa URL bude vypadat přibližně takto:
http://localhost:36916/Account/PasswordReset2?PasswordResetToken=08HZGH0ALZ3CGz3
Kód získá token (v tomto příkladu 08HZGH0ALZ3CGz3) a poté zavolá metodu ResetPassword (Vytvořit nové heslo) pomocné třídy WebSecurity (Zabezpečení webu) a předá jí token spolu s novým heslem. Pokud je token platný, pomocná třída aktualizuje heslo uživatele, který token obdržel e-mailem. V případě, že nové heslo bylo úspěšně vytvořeno, metoda ResetPassword vrací hodnotu true.
V tomto příkladu je volání metody ResetPassword (Vytvořit nové heslo) spojeno s dalšími ověřeními pomocí operátoru && (logická spojka A). Logika je taková, že vytvoření nového hesla je úspěšné, pokud:
newPassword (nové Heslo) není prázdné (operátor ! znamená zápor) anewPassword (nové Heslo) a confirmPassword (potvrzení Hesla) se shodují a ResetPassword (Vytvořit nové heslo) byla úspěšná.Přihlašovací stránka nezabrání v registraci na webu automatizovaným programům (někdy označovaným jako weboví roboti nebo programy bot). (Programy bot se často snaží připojovat ke skupinám uživatelů, aby mohli vystavovat adresy URL produktů nabízených k prodeji.) Že uživatel je skutečná osoba a nikoli počítačový program, se můžete ujistit pomocí testu CAPTCHA pro ověření vstupu. Akronym CAPTCHA je vytvořen ze slov Completely Automated Public Turing test to tell Computers and Humans Apart (Zcela automatizovaný veřejný Turingův test pro rozlišení počítačů a lidí).
Na stránkách ASP.NET můžete test CAPTCHA vykreslit s použitím pomocné třídy ReCaptcha založené na službě reCAPTCHA (http://recaptcha.net). Pomocná třída ReCaptcha zobrazí obrázek se dvěma zkreslenými slovy, která uživatel musí správně zadat, aby stránka byla ověřena. Odpověď uživatele je ověřena službou ReCaptcha.Net.
// před proměnnou captchaMessage (zpráva testu CAPTCHA).PRIVATE_KEY (PRIVáTNí_KLíČ) vložte řetězec se svým privátním klíčem.// z řádku obsahujícího volání metody ReCaptcha.Validate (ReCaptcha.Ověřit).Následující příklad ukazuje hotový kód. Místo textu user-key-here (sem přijde klíč uživatele) vložte svůj klíč.
// Ověření odpovědi uživatele if (!ReCaptcha.Validate("user-key-here")) { captchaMessage = "Response was not correct"; isValid = false; }
PUBLIC_KEY (VEŘEJNý_KLíČ) řetězcem s vaším veřejným klíčem.ReCaptcha. Následující příklad ukazuje hotový kód (pouze musíte vložit svůj kód místo textu user-key-here):
@ReCaptcha.GetHtml("user-key-here", theme: "white")
defaultproxy (výchozí proxy server) v souboru Web.config. Následující příklad ukazuje soubor Web.config, ve kterém byl nakonfigurován element defaultproxy, tak aby mohla fungovat služba reCAPTCHA.
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.net> <defaultProxy> <proxy usesystemdefault = "false" proxyaddress="http://myProxy.MyDomain.com" bypassonlocal="true" autoDetect="False" /> </defaultProxy> </system.net> </configuration>