Web Forms i bazy danych
-
- Tomasz Kopacz,
- 30.09.2005
ASP.NET 2.0 pozwala programiście bez większych trudności zbudować aplikację współpracującą z bazą danych, a nowe kontrolki i providery umożliwiają szybkie utworzenie systemu autoryzacji użytkownika.
ASP.NET 2.0 pozwala programiście bez większych trudności zbudować aplikację współpracującą z bazą danych, a nowe kontrolki i providery umożliwiają szybkie utworzenie systemu autoryzacji użytkownika.
Aby zobaczyć, jak działa ASP.NET, utworzymy prostą aplikację do uzupełniania dat płatności na fakturach. Taka aplikacja powinna:
- Pozwolić użytkownikowi na zalogowanie się.
- Pokazać listę faktur.
- Przypisać daty wpływu płatności za dane faktury.
Po założeniu projektu WWW o nazwie EnterPayment trzeba tak skonfigurować aplikację WWW, żeby wybrany był provider SQL AspNetSqlProvider (jako Membership Provider i jako Role Provider). Warto nacisnąć Test i sprawdzić, czy witryna połączyła się z lokalną instancją SQLEXPRESS. Następnie należy zmienić tryb autoryzacji z Windows (domyślnego) na Forms (czyli na karcie Security wybrać From the Internet). Wtedy .NET będzie używać tzw. autoryzacji Web Forms, która w uproszczeniu polega na tym, że gdy użytkownik się zaloguje, do każdego kolejnego żądania wysyłanego na serwer doklejane będzie ciasteczko (cookie) autoryzacyjne, identyfikujące go i określające jego prawa. Należy również włączyć mechanizm ról. Ostatecznie plik web.config w głównym folderze aplikacji powinien wyglądać mniej więcej tak:
<?xml version="1.0"?>
<system.web>
<roleManager enabled="true"/>
<authentication mode="Forms"/>
</system.web>
</configuration>
Następnie warto dodać stronę typu master (MasterPage.master) - zawsze przydaje się do tworzenia witryn, ponieważ w każdym projekcie strony są pewne wspólne elementy, jak stopka, jakiś nagłówek itp. Co na tej stronie zostanie umieszczone, zależy już od inwencji autora.
Następnie trzeba dodać stronę do logowania (może być oparta na dodanej przed chwilą stronie głównej) Login.aspx. Tej nazwy domyślnie używa .NET 2.0, gdy użytkownikowi brakuje uprawnień do otwarcia pewnej strony. Oczywiście można użyć innej, ale wymaga to potem zmian w konfiguracji autoryzacji Web Forms (odpowiednich wpisów w web.config).
Na stronę logowania przeciągamy kontrolkę Login i ewentualnie na dole umieszczamy ValidationSummary, aby kontrolka zebrała informacje o błędach podczas logowania (trzeba ustawić jej właściwość ValidationGroup na nazwę kontrolki do logowania).
I w zasadzie to wszystkie informacje niezbędne, żeby utworzyć interfejs do zalogowania użytkownika bez jednego wiersza kodu. Ostatecznie w naszej Web Form powinny się znajdować:
<asp:Login ID="Login1" runat="server">
</asp:Login>
<asp:ValidationSummary ID="ValidationSummary1" runat="server" ValidationGroup="Login1" />
Założymy, że użytkownik, który ma prawo wprowadzać informację o datach płatności, musi mieć przypisaną rolę UpdatePaymentRole. Wszystkie formy (dokładniej jedna) używane do edycji będą umieszczone w podfolderze EDIT. Aby wyłącznie odpowiedni użytkownik mógł uruchamiać strony z tego folderu, wystarczy dodać odpowiedni plik web.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<system.web>
<authorization>
<allow roles="UpdatePaymentRole" />
<deny users="*" />
</authorization>
</system.web>
</configuration>
W tym wypadku określamy, że na stronę mogą wejść tylko użytkownicy, którzy mają przypisaną rolę UpdatePaymentRole, a nieuprawnieni podczas prób dostępu do jakiejś strony (np. edit.aspx) znajdującej się w tym folderze, będą automatycznie przekierowani na stronę login.aspx i dopiero gdy się odpowiednio zalogują, zostaną przekierowani z powrotem na stronę EDIT/edit.aspx.
Osoby zainteresowane dalszymi informacjami o zabezpieczeniach w ASP.NET 2.0 mogą sięgnąć po ciekawy dokument PAG (dostępny w MSDN) pod tytułem "Security Practices: ASP.NET 2.0 Security Practices at a Glance".
Pozostaje pytanie, w jaki sposób aplikacja ma sprawdzić, czy na pewno jest właściwie skonfigurowana, a zwłaszcza czy dana rola istnieje itp.
W .NET podczas startu aplikacji WWW, obsługi poszczególnej strony itp. są zgłaszane rozmaite zdarzenia. Jeżeli do projektu dodamy stronę Global.asax, to można będzie zdefiniować pewne globalne procedury obsługi zdarzeń, zgłaszane np. podczas wchodzenia na każdą stronę, otwierania sesji czy przed wysłaniem każdej strony do przeglądarki - jest ich ponad 20. Do sprawdzenia konfiguracji aplikacji wykorzystamy Application_Start, zdarzenie zgłaszane raz, podczas startu aplikacji (dokładniej - gdy pierwszy klient wejdzie na jakąkolwiek stronę danej aplikacji). A więc jeżeli tam sprawdzimy, czy aplikacja jest prawidłowo skonfigurowana, to mamy prawie pewność, że reszta kodu będzie działać właściwie.
void Application_Start(Object sender, EventArgs e) {
if (!Roles.RoleExists("UpdatePaymentRole")) {
Roles.CreateRole("UpdatePaymentRole");
}
if (Membership.FindUsersByName("test").Count == 0) {
MembershipCreateStatus stat;
Membership.CreateUser("test", "[email protected]", "[email protected]"
"123456AA", "AA654321", true, out stat);
if (stat == MembershipCreateStatus.Success) {
Roles.AddUsersToRole(new string[] { "test" }
"UpdatePaymentRole");
} else {
// Trudno...
throw new ApplicationException("Nie można utworzyć użytkownika");
}
}
}
Najpierw sprawdzamy, czy jest rola o danej nazwie. Obiekt Roles ma statyczną metodę RoleExists, która pozwala to wykonać. Jeżeli roli nie ma, to jest tworzona.
W powyższym przykładzie wykonujemy jeszcze jedną operację - two-rzymy testowego użytkownika, żeby ktoś na pewno miał prawo wprowadzać daty. Operacja przebiega analogicznie, tyle że używany jest obiekt Membership. Najpierw sprawdzamy, czy użytkownik istnieje (można też szukać użytkowników według adresów e-mail). Tworząc użytkownika, warto pamiętać, że domyślnie providery w .NET wymagają mocnych haseł, dlatego użytkownik test ma hasło [email protected]