Implementowanie uwierzytelniania opartego na formularzach w aplikacji ASP.NET przy użyciu języka C#.NET
W tym artykule pokazano, jak zaimplementować uwierzytelnianie oparte na formularzach przy użyciu bazy danych do przechowywania użytkowników. Odwołuje się ona do następujących przestrzeni nazw biblioteki klas programu Microsoft .NET Framework:
System.Data.SqlClient
System.Web.Security
Oryginalna wersja produktu: ASP.NET
Oryginalny numer KB: 301240
Wymagania
Na poniższej liście przedstawiono zalecany sprzęt, oprogramowanie, infrastrukturę sieciową i wymagane dodatki Service Pack:
- Visual Studio .NET
- Internet Information Services (IIS) w wersji 5.0 lub nowszej
- SQL Server
Tworzenie aplikacji ASP.NET przy użyciu platformy .NET w języku C#
- Otwórz program Visual Studio .NET.
- Utwórz nową aplikację internetową ASP.NET i określ nazwę i lokalizację.
Konfigurowanie ustawień zabezpieczeń w pliku Web.config
W tej sekcji przedstawiono sposób dodawania i modyfikowania <authentication>
sekcji konfiguracji i <authorization>
w celu skonfigurowania aplikacji ASP.NET do korzystania z uwierzytelniania opartego na formularzach.
W Eksplorator rozwiązań otwórz plik Web.config.
Zmień tryb uwierzytelniania na Formularze.
<Forms>
Wstaw tag i wypełnij odpowiednie atrybuty. Skopiuj następujący kod, a następnie wybierz pozycję Wklej jako kod HTML w menu Edycja , aby wkleić kod w<authentication>
sekcji pliku:<authentication mode="Forms"> <forms name=".ASPXFORMSDEMO" loginUrl="logon.aspx" protection="All" path="/" timeout="30" /> </authentication>
Odmowa dostępu do użytkownika anonimowego
<authorization>
w sekcji w następujący sposób:<authorization> <deny users ="?" /> <allow users = "*" /> </authorization>
Tworzenie przykładowej tabeli bazy danych w celu przechowywania szczegółów użytkowników
W tej sekcji pokazano, jak utworzyć przykładową bazę danych do przechowywania nazwy użytkownika, hasła i roli dla użytkowników. Potrzebujesz kolumny roli, jeśli chcesz przechowywać role użytkowników w bazie danych i implementować zabezpieczenia oparte na rolach.
W menu Start wybierz pozycję Uruchom, a następnie wpisz Notatnik, aby otworzyć Notatnik.
Wyróżnij następujący kod skryptu SQL, kliknij prawym przyciskiem myszy kod, a następnie wybierz polecenie Kopiuj. W Notatniku wybierz pozycję Wklej w menu Edycja , aby wkleić następujący kod:
if exists (select * from sysobjects where id = object_id(N'[dbo].[Users]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[Users] GO CREATE TABLE [dbo].[Users] ([uname] [varchar] (15) NOT NULL, [Pwd] [varchar] (25) NOT NULL, [userRole] [varchar] (25) NOT NULL, ) ON [PRIMARY] GO ALTER TABLE [dbo].[Users] WITH NOCHECK ADD CONSTRAINT [PK_Users] PRIMARY KEY NONCLUSTERED ([uname] ) ON [PRIMARY] GO INSERT INTO Users values('user1','user1','Manager') INSERT INTO Users values('user2','user2','Admin') INSERT INTO Users values('user3','user3','User') GO
Zapisz plik jako Users.sql.
Na komputerze z programem SQL Server otwórz Users.sql w Analizatorze zapytań. Z listy baz danych wybierz pozycję puby i uruchom skrypt. Ta operacja tworzy przykładową tabelę użytkowników i wypełnia tabelę w bazie danych Pubs, która ma być używana z tą przykładową aplikacją.
Tworzenie strony Logon.aspx
Dodaj nowy formularz sieci Web do projektu o nazwie Logon.aspx.
Otwórz stronę Logon.aspx w edytorze i przejdź do widoku HTML.
Skopiuj następujący kod i użyj opcji Wklej jako HTML w menu Edycja , aby wstawić kod między tagami
<form>
:<h3> <font face="Verdana">Logon Page</font> </h3> <table> <tr> <td>Email:</td> <td><input id="txtUserName" type="text" runat="server"></td> <td><ASP:RequiredFieldValidator ControlToValidate="txtUserName" Display="Static" ErrorMessage="*" runat="server" ID="vUserName" /></td> </tr> <tr> <td>Password:</td> <td><input id="txtUserPass" type="password" runat="server"></td> <td><ASP:RequiredFieldValidator ControlToValidate="txtUserPass" Display="Static" ErrorMessage="*" runat="server" ID="vUserPass" /> </td> </tr> <tr> <td>Persistent Cookie:</td> <td><ASP:CheckBox id="chkPersistCookie" runat="server" autopostback="false" /></td> <td></td> </tr> </table> <input type="submit" Value="Logon" runat="server" ID="cmdLogin"><p></p> <asp:Label id="lblMsg" ForeColor="red" Font-Name="Verdana" Font-Size="10" runat="server" />
Ten formularz sieci Web służy do prezentowania użytkownikom formularza logowania, aby umożliwić użytkownikom podanie nazwy użytkownika i hasła w celu zalogowania się do aplikacji.
Aby uzyskać więcej informacji, zobacz RequiredFieldValidator Class (Klasa RequiredFieldValidator).
Przejdź do widoku Projektu i zapisz stronę.
Kod programu obsługi zdarzeń w celu zweryfikowania poświadczeń użytkownika
W tej sekcji przedstawiono kod umieszczony na stronie za pomocą kodu (Logon.aspx.cs).
Kliknij dwukrotnie pozycję Zaloguj się , aby otworzyć plik Logon.aspx.cs .
Zaimportuj wymagane przestrzenie nazw w pliku za kodem:
using System.Data.SqlClient; using System.Web.Security;
ValidateUser
Utwórz funkcję, aby zweryfikować poświadczenia użytkownika, wyszukując w bazie danych. Upewnij się, że zmienionoConnection
ciąg tak, aby wskazywał bazę danych.private bool ValidateUser( string userName, string passWord ) { SqlConnection conn; SqlCommand cmd; string lookupPassword = null; // Check for invalid userName. // userName must not be null and must be between 1 and 15 characters. if ( ( null == userName ) || ( 0 == userName.Length ) || ( userName.Length > 15 )) { System.Diagnostics.Trace.WriteLine( "[ValidateUser] Input validation of userName failed." ); return false; } // Check for invalid passWord. // passWord must not be null and must be between 1 and 25 characters. if ( ( null == passWord ) || ( 0 == passWord.Length ) || ( passWord.Length > 25 )) { System.Diagnostics.Trace.WriteLine( "[ValidateUser] Input validation of passWord failed." ); return false; } try { // Consult with your SQL Server administrator for an appropriate connection // string to use to connect to your local SQL Server. conn = new SqlConnection( "server=localhost;Integrated Security=SSPI;database=pubs" ); conn.Open(); // Create SqlCommand to select pwd field from users table given supplied userName. cmd = new SqlCommand( "Select pwd from users where uname=@userName", conn ); cmd.Parameters.Add( "@userName", SqlDbType.VarChar, 25 ); cmd.Parameters["@userName"].Value = userName; // Execute command and fetch pwd field into lookupPassword string. lookupPassword = (string) cmd.ExecuteScalar(); // Cleanup command and connection objects. cmd.Dispose(); conn.Dispose(); } catch ( Exception ex ) { // Add error handling here for debugging. // This error message should not be sent back to the caller. System.Diagnostics.Trace.WriteLine( "[ValidateUser] Exception " + ex.Message ); } // If no password found, return false. if ( null == lookupPassword ) { // You could write failed login attempts here to event log for additional security. return false; } // Compare lookupPassword and input passWord, using a case-sensitive comparison. return ( 0 == string.Compare( lookupPassword, passWord, false )); }
Możesz użyć jednej z dwóch metod do wygenerowania pliku cookie uwierzytelniania formularzy i przekierowania użytkownika do odpowiedniej strony w
cmdLogin_ServerClick
zdarzeniu. Przykładowy kod jest dostarczany w obu scenariuszach. Użyj jednego z nich zgodnie z wymaganiami.Wywołaj metodę
RedirectFromLoginPage
, aby automatycznie wygenerować plik cookie uwierzytelniania formularzy i przekierować użytkownika do odpowiedniej strony wcmdLogin_ServerClick
przypadku:private void cmdLogin_ServerClick(object sender, System.EventArgs e) { if (ValidateUser(txtUserName.Value,txtUserPass.Value)) FormsAuthentication.RedirectFromLoginPage(txtUserName.Value, chkPersistCookie.Checked); else Response.Redirect("logon.aspx", true); }
Wygeneruj bilet uwierzytelniania, zaszyfruj go, utwórz plik cookie, dodaj go do odpowiedzi i przekierowuj użytkownika. Ta operacja zapewnia większą kontrolę nad sposobem tworzenia pliku cookie. W tym przypadku można również uwzględnić dane
FormsAuthenticationTicket
niestandardowe.private void cmdLogin_ServerClick(object sender, System.EventArgs e) { if (ValidateUser(txtUserName.Value,txtUserPass.Value)) { FormsAuthenticationTicket tkt; string cookiestr; HttpCookie ck; tkt = new FormsAuthenticationTicket(1, txtUserName.Value, DateTime.Now, DateTime.Now.AddMinutes(30), chkPersistCookie.Checked, "your custom data"); cookiestr = FormsAuthentication.Encrypt(tkt); ck = new HttpCookie(FormsAuthentication.FormsCookieName, cookiestr); if (chkPersistCookie.Checked) ck.Expires=tkt.Expiration; ck.Path = FormsAuthentication.FormsCookiePath; Response.Cookies.Add(ck); string strRedirect; strRedirect = Request["ReturnUrl"]; if (strRedirect==null) strRedirect = "default.aspx"; Response.Redirect(strRedirect, true); } else Response.Redirect("logon.aspx", true); }
Upewnij się, że następujący kod został dodany do
InitializeComponent
metody w kodzie generowanym przez projektanta formularzy internetowych:this.cmdLogin.ServerClick += new System.EventHandler(this.cmdLogin_ServerClick);
Tworzenie strony Default.aspx
Ta sekcja tworzy stronę testową, do której użytkownicy są przekierowywani po uwierzytelnieniu. Jeśli użytkownicy przejdą do tej strony bez uprzedniego zalogowania się do aplikacji, zostaną przekierowani na stronę logowania.
Zmień nazwę istniejącej strony WebForm1.aspx na Default.aspx i otwórz ją w edytorze.
Przejdź do widoku HTML i skopiuj następujący kod między tagami
<form>
:<input type="submit" Value="SignOut" runat="server" id="cmdSignOut">
Ten przycisk służy do wylogowania się z sesji uwierzytelniania formularzy.
Przejdź do widoku Projektu i zapisz stronę.
Zaimportuj wymagane przestrzenie nazw w pliku za kodem:
using System.Web.Security;
Kliknij dwukrotnie pozycję SignOut , aby otworzyć stronę za pomocą kodu (Default.aspx.cs) i skopiować następujący kod w procedurze
cmdSignOut_ServerClick
obsługi zdarzeń:private void cmdSignOut_ServerClick(object sender, System.EventArgs e) { FormsAuthentication.SignOut(); Response.Redirect("logon.aspx", true); }
Upewnij się, że następujący kod został dodany do
InitializeComponent
metody w kodzie generowanym przez projektanta formularzy internetowych:this.cmdSignOut.ServerClick += new System.EventHandler(this.cmdSignOut_ServerClick);
Zapisz i skompiluj projekt. Teraz możesz użyć aplikacji.
Dodatkowe uwagi
Możesz bezpiecznie przechowywać hasła w bazie danych. Możesz użyć
FormsAuthentication
funkcji narzędzia klasy o nazwieHashPasswordForStoringInConfigFile
, aby zaszyfrować hasła przed zapisaniem ich w bazie danych lub pliku konfiguracji.Możesz przechowywać informacje o połączeniu SQL w pliku konfiguracji (Web.config), aby w razie potrzeby można je było łatwo modyfikować.
Możesz rozważyć dodanie kodu, aby uniemożliwić hakerom, którzy próbują użyć różnych kombinacji haseł podczas logowania. Można na przykład uwzględnić logikę, która akceptuje tylko dwie lub trzy próby logowania. Jeśli użytkownicy nie mogą zalogować się w niektórych próbach, możesz ustawić flagę w bazie danych, aby nie zezwalać im na logowanie się, dopóki użytkownicy nie ponownie włączą swoich kont, odwiedzając inną stronę lub wywołując linię pomocy technicznej. Ponadto należy dodać odpowiednią obsługę błędów wszędzie tam, gdzie jest to konieczne.
Ponieważ użytkownik jest identyfikowany na podstawie pliku cookie uwierzytelniania, możesz chcieć użyć protokołu Secure Sockets Layer (SSL) w tej aplikacji, aby nikt nie mógł oszukać pliku cookie uwierzytelniania i wszelkich innych cennych informacji, które są przesyłane.
Uwierzytelnianie oparte na formularzach wymaga zaakceptowania lub włączenia plików cookie przez klienta w przeglądarce.
Parametr
<authentication>
limitu czasu sekcji konfiguracji kontroluje interwał, w którym plik cookie uwierzytelniania jest ponownie wygenerowany. Możesz wybrać wartość, która zapewnia lepszą wydajność i bezpieczeństwo.Niektóre pośredniczące serwery proxy i pamięci podręczne w Internecie mogą buforować odpowiedzi serwera sieci Web zawierające
Set-Cookie
nagłówki, które następnie są zwracane do innego użytkownika. Ponieważ uwierzytelnianie oparte na formularzach używa pliku cookie do uwierzytelniania użytkowników, takie zachowanie może spowodować, że użytkownicy przypadkowo (lub celowo) personifikują innego użytkownika, odbierając plik cookie z pośredniczącego serwera proxy lub pamięci podręcznej, która nie była pierwotnie przeznaczona dla nich.