Udostępnij za pośrednictwem


Tworzenie schematu członkostwa w programie SQL Server (C#)

Autor: Scott Mitchell

Uwaga

Ponieważ ten artykuł został napisany, dostawcy ASP.NET członkostwa zostały zastąpione przez usługę ASP.NET Identity. Zdecydowanie zalecamy aktualizowanie aplikacji w celu korzystania z platformy ASP.NET Identity , a nie dostawców członkostwa opisanych w tym artykule. ASP.NET Identity ma wiele zalet w systemie członkostwa ASP.NET, w tym :

  • Lepsza wydajność
  • Ulepszona rozszerzalność i możliwość testowania
  • Obsługa uwierzytelniania OAuth, OpenID Connect i uwierzytelniania dwuskładnikowego
  • Obsługa tożsamości opartej na oświadczeniach
  • Lepsza współdziałanie z platformą ASP.Net Core

Pobierz kod lub pobierz plik PDF

Ten samouczek rozpoczyna się od zbadania technik dodawania niezbędnego schematu do bazy danych w celu użycia obiektu SqlMembershipProvider. Następnie przeanalizujemy tabele kluczy w schemacie i omówimy ich przeznaczenie i znaczenie. Ten samouczek kończy się omówieniem sposobu powiedzieć aplikacji ASP.NET, która dostawca platformy członkostwa powinna używać.

Wprowadzenie

Poprzednie dwa samouczki zbadane przy użyciu uwierzytelniania formularzy w celu zidentyfikowania odwiedzających witrynę internetową. Struktura uwierzytelniania formularzy ułatwia deweloperom rejestrowanie użytkownika w witrynie internetowej i zapamiętywać je na stronach za pośrednictwem biletów uwierzytelniania. Klasa FormsAuthentication zawiera metody generowania biletu i dodawania go do plików cookie odwiedzających. Narzędzie FormsAuthenticationModule sprawdza wszystkie żądania przychodzące, a dla tych z prawidłowym biletem uwierzytelniania tworzy i kojarzy GenericPrincipal obiekt i FormsIdentity z bieżącym żądaniem. Uwierzytelnianie formularzy jest jedynie mechanizmem udzielania biletu uwierzytelniania odwiedzającym podczas logowania i analizowania tego biletu w celu określenia tożsamości użytkownika. Aby aplikacja internetowa obsługiwała konta użytkowników, nadal musimy zaimplementować magazyn użytkowników i dodać funkcje w celu zweryfikowania poświadczeń, zarejestrowania nowych użytkowników i niezliczonych zadań związanych z kontem użytkownika.

Przed ASP.NET 2.0 deweloperzy byli na haku do implementowania wszystkich tych zadań związanych z kontem użytkownika. Na szczęście zespół ASP.NET rozpoznał tę wadę i wprowadził strukturę członkostwa z ASP.NET 2.0. Struktura członkostwa to zestaw klas w .NET Framework, które zapewniają interfejs programowy do wykonywania podstawowych zadań związanych z kontem użytkownika. Ta struktura jest zbudowana na szczycie modelu dostawcy, który umożliwia deweloperom podłączanie dostosowanej implementacji do standardowego interfejsu API.

Jak opisano w samouczku Podstawy zabezpieczeń i ASP.NET Support, .NET Framework dostarczane z dwoma wbudowanymi dostawcami członkostwa: ActiveDirectoryMembershipProvider i SqlMembershipProvider. Jak wskazuje nazwa, SqlMembershipProvider jako magazyn użytkowników używa bazy danych microsoft SQL Server. Aby użyć tego dostawcy w aplikacji, musimy poinformować dostawcę, jakiego bazy danych używać jako magazynu. Jak można sobie wyobrazić, oczekuje, SqlMembershipProvider że baza danych magazynu użytkowników będzie miała pewne tabele, widoki i procedury składowane bazy danych. Musimy dodać ten oczekiwany schemat do wybranej bazy danych.

Ten samouczek rozpoczyna się od zbadania technik dodawania niezbędnego schematu do bazy danych w celu użycia elementu SqlMembershipProvider. Następnie przeanalizujemy tabele kluczy w schemacie i omówimy ich przeznaczenie i znaczenie. Ten samouczek kończy się omówieniem sposobu powiedzieć aplikacji ASP.NET, która dostawca platformy członkostwa powinna używać.

Zaczynamy!

Krok 1. Podejmowanie decyzji o miejscu umieszczenia magazynu użytkowników

Dane aplikacji ASP.NET są często przechowywane w wielu tabelach w bazie danych. Podczas implementowania schematu SqlMembershipProvider bazy danych musimy zdecydować, czy należy umieścić schemat członkostwa w tej samej bazie danych, co dane aplikacji, czy w alternatywnej bazie danych.

Zalecam znalezienie schematu członkostwa w tej samej bazie danych co dane aplikacji z następujących powodów:

  • Łatwość konserwacji " aplikacja, której dane są hermetyzowane w jednej bazie danych, jest łatwiej zrozumieć, obsługiwać i wdrażać niż aplikacja z dwoma oddzielnymi bazami danych.
  • Integralność relacyjna " lokalizując tabele powiązane z członkostwem w tej samej bazie danych, co tabele aplikacji, można ustanowić ograniczenia klucza obcego między kluczami podstawowymi w tabelach powiązanych z członkostwem i powiązanych tabelach aplikacji.

Oddzielenie danych magazynu użytkowników i aplikacji do oddzielnych baz danych ma sens tylko wtedy, gdy masz wiele aplikacji, które używają oddzielnych baz danych, ale muszą współdzielić wspólny magazyn użytkowników.

Tworzenie bazy danych

Aplikacja, która została utworzona od drugiego samouczka, nie potrzebowała jeszcze bazy danych. Potrzebujemy go teraz jednak dla sklepu użytkowników. Utwórzmy jeden, a następnie dodajmy do niego schemat wymagany przez dostawcę SqlMembershipProvider (zobacz Krok 2).

Uwaga

W tej serii samouczków będziemy używać bazy danych microsoft SQL Server 2005 Express Edition do przechowywania tabel aplikacji i schematuSqlMembershipProvider. Ta decyzja została podjęta z dwóch powodów: po pierwsze, ze względu na jego koszt - bezpłatna - Express Edition jest najbardziej czytelnie dostępna wersja SQL Server 2005; po drugie, SQL Server 2005 Express Edition bazy danych można umieścić bezpośrednio w aplikacji App_Data internetowej folder, co czyni go cinch spakować bazę danych i aplikację internetową razem w jednym pliku ZIP i ponownie wdrożyć go bez żadnych specjalnych instrukcji konfiguracji lub opcji konfiguracji. Jeśli wolisz korzystać z wersji innej niż Express Edition SQL Server, możesz skorzystać z bezpłatnej wersji. Kroki są praktycznie identyczne. Schemat SqlMembershipProvider będzie działać z dowolną wersją programu Microsoft SQL Server 2000 i nowszym.

W Eksplorator rozwiązań kliknij prawym przyciskiem myszy App_Data folder i wybierz polecenie Dodaj nowy element. (Jeśli nie widzisz App_Data folderu w projekcie, kliknij prawym przyciskiem myszy projekt w Eksplorator rozwiązań, wybierz pozycję Dodaj folder ASP.NET i wybierz pozycję App_Data.) W oknie dialogowym Dodawanie nowego elementu wybierz opcję dodania nowego SQL Database o nazwie SecurityTutorials.mdf. W tym samouczku dodamy SqlMembershipProvider schemat do tej bazy danych. W kolejnych samouczkach utworzymy dodatkowe tabele w celu przechwycenia danych aplikacji.

Dodawanie nowej bazy danych SQL Database o nazwie SecurityTutorials.mdf do folderu App_Data

Rysunek 1. Dodawanie nowej SQL Database nazwanej SecurityTutorials.mdf bazy danych do App_Data folderu (kliknij, aby wyświetlić obraz pełnowymiarowy)

Dodanie bazy danych do App_Data folderu powoduje automatyczne dodanie jej do widoku Eksploratora bazy danych. (W wersji programu Visual Studio innej niż Express Edition Eksplorator bazy danych jest nazywany Eksploratorem serwera). Przejdź do Eksploratora bazy danych i rozwiń właśnie dodaną SecurityTutorials bazę danych. Jeśli na ekranie nie widzisz Eksploratora baz danych, przejdź do menu Widok i wybierz pozycję Eksplorator bazy danych lub naciśnij klawisze Ctrl+Alt+S. Jak pokazano na rysunku SecurityTutorials 2, baza danych jest pusta — nie zawiera tabel, widoków ani procedur składowanych.

Baza danych SecurityTutorials jest obecnie pusta

Rysunek 2. Baza SecurityTutorials danych jest obecnie pusta (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Krok 2. Dodawanie schematuSqlMembershipProviderdo bazy danych

Wymaga SqlMembershipProvider to zainstalowania określonego zestawu tabel, widoków i procedur składowanych w bazie danych magazynu użytkowników. Te wymagane obiekty bazy danych można dodać za pomocą aspnet_regsql.exe narzędzia. Ten plik znajduje się w folderze %WINDIR%\Microsoft.Net\Framework\v2.0.50727\ .

Uwaga

Narzędzie aspnet_regsql.exe oferuje zarówno funkcje wiersza polecenia, jak i graficzny interfejs użytkownika. Interfejs graficzny jest bardziej przyjazny dla użytkownika i jest tym, co przeanalizujemy w tym samouczku. Interfejs wiersza polecenia jest przydatny, gdy dodanie schematu SqlMembershipProvider musi być zautomatyzowane, na przykład w skryptach kompilacji lub scenariuszach zautomatyzowanego testowania.

Narzędzie aspnet_regsql.exe służy do dodawania lub usuwania usług aplikacji ASP.NET do określonej bazy danych SQL Server. Usługi aplikacji ASP.NET obejmują schematy dla SqlMembershipProvider obiektów i SqlRoleProvideroraz schematy dla dostawców opartych na języku SQL dla innych platform ASP.NET 2.0. Musimy podać dwa bity informacji do aspnet_regsql.exe narzędzia:

  • Niezależnie od tego, czy chcemy dodać, czy usunąć usługi aplikacji oraz
  • Baza danych, z której ma zostać dodany lub usunięty schemat usług aplikacji

Podczas monitowania o użycie aspnet_regsql.exe bazy danych narzędzie prosi nas o podanie nazwy serwera, na którym znajduje się baza danych, poświadczenia zabezpieczeń służące do nawiązywania połączenia z bazą danych oraz nazwę bazy danych. Jeśli używasz wersji innej niż Express edition SQL Server, musisz już znać te informacje, ponieważ są to te same informacje, które należy podać za pośrednictwem parametry połączenia podczas pracy z bazą danych za pośrednictwem strony internetowej ASP.NET. Określenie nazwy serwera i bazy danych podczas korzystania z bazy danych SQL Server 2005 Express Edition w folderze App_Data jest jednak nieco bardziej zaangażowane.

W poniższej sekcji przedstawiono prosty sposób określania nazwy serwera i bazy danych dla bazy danych SQL Server 2005 Express Edition w folderzeApp_Data. Jeśli nie używasz SQL Server 2005 Express Edition możesz przejść do sekcji Instalowanie usług aplikacji.

Określanie nazwy serwera i bazy danych dla bazy danych SQL Server 2005 Express Edition w folderzeApp_Data

Aby użyć aspnet_regsql.exe narzędzia, musimy znać nazwy serwera i bazy danych. Nazwa serwera to localhost\InstanceName. Najprawdopodobniej nazwa wystąpienia to SQLExpress. Jeśli jednak zainstalowano SQL Server 2005 Express Edition ręcznie (czyli nie zainstalowano go automatycznie podczas instalowania programu Visual Studio), można wybrać inną nazwę wystąpienia.

Nazwa bazy danych jest nieco trudniejsza do ustalenia. Bazy danych w App_Data folderze zwykle mają nazwę bazy danych, która zawiera unikatowy identyfikator globalny wraz ze ścieżką do pliku bazy danych. Musimy określić tę nazwę bazy danych, aby dodać schemat usług aplikacji za pomocą polecenia aspnet_regsql.exe.

Najprostszym sposobem ustalenia nazwy bazy danych jest sprawdzenie jej za pośrednictwem SQL Server Management Studio. SQL Server Management Studio udostępnia graficzny interfejs do zarządzania bazami danych SQL Server 2005, ale nie jest dostarczane z wersją Express Edition SQL Server 2005. Dobrą wiadomością jest to, że możesz pobrać bezpłatną wersję Express Edition SQL Server Management Studio.

Uwaga

Jeśli na pulpicie zainstalowano również wersję inną niż Express Edition SQL Server 2005, prawdopodobnie zainstalowano pełną wersję programu Management Studio. Możesz użyć pełnej wersji, aby określić nazwę bazy danych, wykonując te same kroki, co opisane poniżej dla wersji Express.

Zacznij od zamknięcia programu Visual Studio, aby upewnić się, że wszystkie blokady nałożone przez program Visual Studio w pliku bazy danych są zamknięte. Następnie uruchom SQL Server Management Studio i połącz się z bazą localhost\InstanceName danych dla SQL Server 2005 Express Edition. Jak wspomniano wcześniej, prawdopodobieństwo, że nazwa wystąpienia to SQLExpress. Dla opcji Uwierzytelnianie wybierz pozycję Uwierzytelnianie systemu Windows.

Nawiązywanie połączenia z wystąpieniem SQL Server 2005 Express Edition

Rysunek 3. Nawiązywanie połączenia z wystąpieniem SQL Server 2005 Express Edition (kliknij, aby wyświetlić obraz pełnowymiarowy)

Po nawiązaniu połączenia z wystąpieniem SQL Server 2005 Express Edition program Management Studio wyświetla foldery bazy danych, ustawienia zabezpieczeń, obiekty serwera itd. Po rozwinięciu karty Bazy danych zobaczysz, że SecurityTutorials.mdf baza danych nie jest zarejestrowana w wystąpieniu bazy danych — najpierw musimy dołączyć bazę danych.

Kliknij prawym przyciskiem myszy folder Bazy danych i wybierz polecenie Dołącz z menu kontekstowego. Spowoduje to wyświetlenie okna dialogowego Dołączanie baz danych. W tym miejscu kliknij przycisk Dodaj, przejdź do SecurityTutorials.mdf bazy danych, a następnie kliknij przycisk OK. Rysunek 4 przedstawia okno dialogowe Dołączanie baz danych po wybraniu SecurityTutorials.mdf bazy danych. Rysunek 5 przedstawia Eksplorator obiektów programu Management Studio po pomyślnym dołączeniu bazy danych.

Dołączanie bazy danych SecurityTutorials.mdf

Rysunek 4. Dołączanie SecurityTutorials.mdf bazy danych (kliknij, aby wyświetlić obraz pełnowymiarowy)

Baza danych SecurityTutorials.mdf jest wyświetlana w folderze Bazy danych

Rysunek 5. Baza danych jest wyświetlana SecurityTutorials.mdf w folderze Bazy danych (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Jak pokazano na rysunku SecurityTutorials.mdf 5, baza danych ma dość abstruse nazwę. Zmieńmy ją na bardziej pamiętną (i łatwiejszą do wpisywania) nazwę. Kliknij prawym przyciskiem myszy bazę danych, wybierz polecenie Zmień nazwę z menu kontekstowego i zmień jego nazwę SecurityTutorialsDatabase. Nie powoduje to zmiany nazwy pliku, tylko nazwy używanej przez bazę danych do identyfikowania się w celu SQL Server.

Zmień nazwę bazy danych na SecurityTutorialsDatabase

Rysunek 6. Zmiana nazwy bazy danych na SecurityTutorialsDatabase(kliknij, aby wyświetlić obraz pełnowymiarowy)

W tym momencie znamy odpowiednio nazwy serwera i bazy danych dla SecurityTutorials.mdf pliku bazy danych: localhost\InstanceName i SecurityTutorialsDatabase. Teraz możemy przystąpić do instalowania usług aplikacji za pomocą aspnet_regsql.exe narzędzia.

Instalowanie usług aplikacji

Aby uruchomić aspnet_regsql.exe narzędzie, przejdź do menu Start i wybierz pozycję Uruchom. Wprowadź w %WINDIR%\Microsoft.Net\Framework\v2.0.50727\aspnet_regsql.exe polu tekstowym i kliknij przycisk OK. Alternatywnie możesz użyć Eksploratora Windows, aby przejść do szczegółów odpowiedniego folderu i kliknąć aspnet_regsql.exe dwukrotnie plik. Każda z tych metod będzie kompietować te same wyniki.

aspnet_regsql.exe Uruchomienie narzędzia bez żadnych argumentów wiersza polecenia powoduje uruchomienie graficznego interfejsu użytkownika Kreatora instalacji ASP.NET SQL Server. Kreator ułatwia dodawanie lub usuwanie usług aplikacji ASP.NET w określonej bazie danych. Pierwszy ekran kreatora, pokazany na rysunku 7, opisuje przeznaczenie narzędzia.

Dodawanie schematu członkostwa za pomocą Kreatora instalacji ASP.NET SQL Server

Rysunek 7. Użyj Kreatora konfiguracji ASP.NET SQL Server, aby dodać schemat członkostwa (kliknij, aby wyświetlić obraz pełnowymiarowy)

Drugi krok kreatora pyta nas, czy chcemy dodać usługi aplikacji, czy je usunąć. Ponieważ chcemy dodać tabele, widoki i procedury składowane niezbędne dla elementu SqlMembershipProvider, wybierz opcję Konfiguruj SQL Server dla usług aplikacji. Później, jeśli chcesz usunąć ten schemat z bazy danych, uruchom ponownie tego kreatora, ale zamiast tego wybierz opcję Usuń informacje o usługach aplikacji z istniejącej bazy danych.

Wybierz opcję Konfiguruj SQL Server dla usług aplikacji

Rysunek 8. Wybierz opcję Konfiguruj SQL Server dla usług aplikacji (kliknij, aby wyświetlić obraz pełnowymiarowy)

Trzeci krok monituje o informacje o bazie danych: nazwę serwera, informacje o uwierzytelnieniu i nazwę bazy danych. Jeśli wykonano czynności opisane w tym samouczku i dodano SecurityTutorials.mdf bazę danych do elementu , dołączono ją do App_Dataelementu i zmieniono jej nazwę na localhost\InstanceNameSecurityTutorialsDatabase, użyj następujących wartości:

  • Serwer: localhost\InstanceName
  • Uwierzytelnianie Windows
  • Baza danych: SecurityTutorialsDatabase

Wprowadź informacje o bazie danych

Rysunek 9. Wprowadź informacje o bazie danych (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Po wprowadzeniu informacji o bazie danych kliknij przycisk Dalej. Ostatni krok zawiera podsumowanie kroków, które zostaną wykonane. Kliknij przycisk Dalej, aby zainstalować usługi aplikacji, a następnie zakończ, aby ukończyć pracę kreatora.

Uwaga

Jeśli do dołączenia bazy danych i zmiany nazwy pliku bazy danych użyto programu Management Studio, pamiętaj, aby odłączyć bazę danych i zamknąć program Management Studio przed ponownym otwarciem programu Visual Studio. Aby odłączyć SecurityTutorialsDatabase bazę danych, kliknij prawym przyciskiem myszy nazwę bazy danych, a następnie z menu Zadania wybierz polecenie Odłącz.

Po zakończeniu pracy kreatora wróć do programu Visual Studio i przejdź do Eksploratora baz danych. Rozwiń folder Tables. Powinna zostać wyświetlona seria tabel, których nazwy zaczynają się od prefiksu aspnet_. Podobnie różne widoki i procedury składowane można znaleźć w folderach Widoki i Procedury składowane. Te obiekty bazy danych tworzą schemat usług aplikacji. Przeanalizujemy obiekty bazy danych specyficzne dla członkostwa i roli w kroku 3.

Do bazy danych dodano różne tabele, widoki i procedury składowane

Rysunek 10. Dodano do bazy danych różne tabele, widoki i procedury składowane (kliknij, aby wyświetlić obraz pełnowymiarowy)

Uwaga

Graficzny aspnet_regsql.exe interfejs użytkownika narzędzia instaluje cały schemat usług aplikacji. Jednak podczas wykonywania aspnet_regsql.exe z wiersza polecenia można określić, jakie składniki usług aplikacji mają być instalowane (lub usuwane). W związku z tym, jeśli chcesz dodać tylko tabele, widoki i procedury składowane niezbędne dla SqlMembershipProvider dostawców i SqlRoleProvider , uruchom polecenie aspnet_regsql.exe w wierszu polecenia. Alternatywnie można ręcznie uruchomić odpowiedni podzbiór skryptów tworzenia języka T-SQL używanych przez program aspnet_regsql.exe. Te skrypty znajdują się w folderze WINDIR%\Microsoft.Net\Framework\v2.0.50727\ o nazwach, takich jak InstallCommon.sql,InstallMembership.sqlInstallRoles.sql , InstallProfile.sql,InstallSqlState.sql i tak dalej.

W tym momencie utworzyliśmy obiekty bazy danych potrzebne przez SqlMembershipProviderprogram . Jednak nadal musimy poinstruować strukturę członkostwa, że powinna używać SqlMembershipProvider elementu (a powiedzmy ActiveDirectoryMembershipProvider) i że SqlMembershipProvider powinna używać SecurityTutorials bazy danych. Przyjrzymy się, jak określić, jakiego dostawcy używać i jak dostosować ustawienia wybranego dostawcy w kroku 4. Najpierw przyjrzyjmy się dokładniej obiektom bazy danych, które zostały właśnie utworzone.

Krok 3. Spojrzenie na podstawowe tabele schematu

Podczas pracy z strukturami członkostwa i ról w aplikacji ASP.NET szczegóły implementacji są hermetyzowane przez dostawcę. W przyszłych samouczkach omówimy interfejs z tymi strukturami za pośrednictwem klas i Roles .NET FrameworkMembership. W przypadku korzystania z tych interfejsów API wysokiego poziomu nie musimy martwić się szczegółami niskiego poziomu, takimi jak zapytania wykonywane lub jakie tabele są modyfikowane przez SqlMembershipProvider element i SqlRoleProvider.

W związku z tym możemy pewnie użyć struktur Członkostwa i ról bez eksplorowania schematu bazy danych utworzonego w kroku 2. Jednak podczas tworzenia tabel do przechowywania danych aplikacji może być konieczne utworzenie jednostek, które odnoszą się do użytkowników lub ról. Ułatwia to zapoznanie się ze SqlMembershipProvider schematami i SqlRoleProvider podczas ustanawiania ograniczeń klucza obcego między tabelami danych aplikacji a tymi tabelami utworzonymi w kroku 2. Ponadto w pewnych rzadkich okolicznościach może być konieczne użycie interfejsu z użytkownikiem i rolą przechowywanych bezpośrednio na poziomie bazy danych (zamiast za pomocą Membership klas lub Roles ).

Partycjonowanie magazynu użytkowników w aplikacjach

Struktury Członkostwa i ról zostały zaprojektowane tak, aby jeden magazyn użytkowników i ról mógł być współużytkowany między wieloma różnymi aplikacjami. Aplikacja ASP.NET korzystająca z platform członkostwa lub ról musi określać, która partycja aplikacji ma być używana. Krótko mówiąc, wiele aplikacji internetowych może używać tych samych magazynów użytkowników i ról. Rysunek 11 przedstawia magazyny użytkowników i ról podzielone na trzy aplikacje: HRSite, CustomerSite i SalesSite. Te trzy aplikacje internetowe mają własnych unikatowych użytkowników i ról, ale wszystkie fizycznie przechowują swoje konto użytkownika i informacje o roli w tych samych tabelach bazy danych.

Konta użytkowników mogą być podzielone na partycje w wielu aplikacjach

Rysunek 11. Konta użytkowników mogą być partycjonowane w wielu aplikacjach (kliknij, aby wyświetlić obraz pełnowymiarowy)

Tabela aspnet_Applications definiuje te partycje. Każda aplikacja, która używa bazy danych do przechowywania informacji o koncie użytkownika, jest reprezentowana przez wiersz w tej tabeli. Tabela aspnet_Applications zawiera cztery kolumny: ApplicationId, , LoweredApplicationNameApplicationNamei Description. ApplicationId jest typem uniqueidentifier i jest kluczem podstawowym tabeli. ApplicationName Zawiera unikatową przyjazną dla człowieka nazwę dla każdej aplikacji.

Inne tabele związane z członkostwem i rolami łączą się z polem ApplicationId w pliku aspnet_Applications. Na przykład aspnet_Users tabela zawierająca rekord dla każdego konta użytkownika ma pole klucza obcego ApplicationId ; ditto dla aspnet_Roles tabeli. Pole ApplicationId w tych tabelach określa partycję aplikacji, do którego należy konto użytkownika lub rola.

Przechowywanie informacji o koncie użytkownika

Informacje o koncie użytkownika znajdują się w dwóch tabelach: aspnet_Users i aspnet_Membership. Tabela aspnet_Users zawiera pola, które przechowują podstawowe informacje o koncie użytkownika. Trzy najbardziej istotne kolumny to:

  • UserId
  • UserName
  • ApplicationId

UserId jest kluczem podstawowym (i typem uniqueidentifier). UserName jest typu nvarchar(256) i wraz z hasłem składa się z poświadczeń użytkownika. (Hasło użytkownika jest przechowywane w aspnet_Membership tabeli). ApplicationId łączy konto użytkownika z określoną aplikacją w programie aspnet_Applications. W kolumnach UserName i ApplicationId występuje ograniczenie złożoneUNIQUE. Gwarantuje to, że w danej aplikacji każda nazwa użytkownika jest unikatowa, ale pozwala na użycie tego samego UserName elementu w różnych aplikacjach.

Tabela aspnet_Membership zawiera dodatkowe informacje o koncie użytkownika, takie jak hasło użytkownika, adres e-mail, data i godzina ostatniego logowania itd. Istnieje korespondencja jeden do jednego między rekordami w tabelach aspnet_Users i aspnet_Membership . Ta relacja jest zapewniana przez UserId pole w obiekcie aspnet_Membership, które służy jako klucz podstawowy tabeli. Podobnie jak tabelaaspnet_Users, zawiera ApplicationId pole, aspnet_Membership które łączy te informacje z określoną partycją aplikacji.

Zabezpieczanie haseł

Informacje o hasłach aspnet_Membership są przechowywane w tabeli. Umożliwia SqlMembershipProvider przechowywanie haseł w bazie danych przy użyciu jednej z następujących trzech technik:

  • Wyczyść — hasło jest przechowywane w bazie danych jako zwykły tekst. Zdecydowanie odradzam korzystanie z tej opcji. Jeśli baza danych zostanie naruszona - czy to przez hakera, który znajdzie tylne drzwi lub niezadowolony pracownik, który ma dostęp do bazy danych - każde poświadczenia jednego użytkownika są tam do podjęcia.
  • Skrót — hasła są skróty przy użyciu algorytmu skrótu jednokierunkowego i losowo wygenerowanej wartości soli. Ta wartość skrótu (wraz z solą) jest przechowywana w bazie danych.
  • Encrypted — zaszyfrowana wersja hasła jest przechowywana w bazie danych.

Użyta technika przechowywania haseł zależy od SqlMembershipProvider ustawień określonych w Web.configpliku . Przyjrzymy się dostosowywaniu SqlMembershipProvider ustawień w kroku 4. Domyślne zachowanie polega na przechowywaniu skrótu hasła.

Kolumny odpowiedzialne za przechowywanie hasła to Password, PasswordFormati PasswordSalt. PasswordFormat to pole typu int , którego wartość wskazuje technikę służącą do przechowywania hasła: 0 dla funkcji Clear; 1 dla skrótu; 2 dla funkcji Encrypted. PasswordSalt jest przypisany losowo wygenerowany ciąg niezależnie od używanej techniki przechowywania haseł; wartość jest PasswordSalt używana tylko podczas przetwarzania skrótu hasła. Na koniec kolumna Password zawiera rzeczywiste dane hasła, czy to hasło w postaci zwykłego tekstu, skrót hasła lub zaszyfrowane hasło.

Tabela 1 ilustruje, jak te trzy kolumny mogą wyglądać dla różnych technik magazynowania podczas przechowywania hasła MySecret! .

Technika< magazynowania_o3a_p /> Hasło<_o3a_p /> PasswordFormat<_o3a_p /> PasswordSalt<_o3a_p />
Czyste MySecret! 0 tTnkPlesqissc2y2SMEygA==
Mieszany 2oXm6sZHWbTHFgjgkGQsc2Ec9ZM= 1 wFgjUfhdUFOCKQiI61vtiQ==
Zaszyfrowane 62RZgDvhxykkqsMchZ0Yly7HS6onhpaoCYaRxV8g0F4CW56OXUU3e7Inza9j9BKp 2 LSRzhGS/aa/oqAXGLHJNBw==

Tabela 1. Przykładowe wartości pól Password-Related podczas przechowywania hasła MySecret!

Uwaga

Określony algorytm szyfrowania lub wyznaczania skrótów używany przez SqlMembershipProvider element jest określany przez ustawienia w elemecie <machineKey> .

Przechowywanie ról i skojarzeń ról

Struktura Role umożliwia deweloperom definiowanie zestawu ról i określanie, do jakich ról należą użytkownicy. Te informacje są przechwytywane w bazie danych za pomocą dwóch tabel: aspnet_Roles i aspnet_UsersInRoles. Każdy rekord w aspnet_Roles tabeli reprezentuje rolę dla określonej aplikacji. Podobnie jak tabela aspnet_Usersaspnet_Roles , tabela ma trzy kolumny istotne dla naszej dyskusji:

  • RoleId
  • RoleName
  • ApplicationId

RoleId jest kluczem podstawowym (i typem uniqueidentifier). RoleName jest typu nvarchar(256). Łączy ApplicationId konto użytkownika z określoną aplikacją w aspnet_Applicationsprogramie . W kolumnach RoleName i ApplicationId istnieje ograniczenie złożoneUNIQUE, dzięki czemu w danej aplikacji każda nazwa roli jest unikatowa.

Tabela aspnet_UsersInRoles służy jako mapowanie między użytkownikami i rolami. Istnieją tylko dwie kolumny — UserId i — i RoleId razem tworzą złożony klucz podstawowy.

Krok 4. Określanie dostawcy i dostosowywanie jego ustawień

Wszystkie struktury, które obsługują model dostawcy — takie jak struktury członkostwa i ról — nie zawierają samych szczegółów implementacji i zamiast tego delegują te obowiązki do klasy dostawcy. W przypadku struktury Membership członkostwa klasa definiuje interfejs API do zarządzania kontami użytkowników, ale nie współdziała bezpośrednio z żadnym magazynem użytkowników. Membership Zamiast tego metody klasy przekazują żądanie skonfigurowanemu dostawcy — użyjemy polecenia SqlMembershipProvider. Kiedy wywołujemy jedną z metod w Membership klasie, jak struktura członkostwa wie, aby delegować wywołanie do klasy SqlMembershipProvider?

Klasa Membership ma właściwość zawierającą Providers odwołanie do wszystkich zarejestrowanych klas dostawców dostępnych do użycia przez strukturę członkostwa. Każdy zarejestrowany dostawca ma skojarzona nazwę i typ. Nazwa oferuje przyjazny dla człowieka sposób odwołowania się do określonego dostawcy w Providers kolekcji, podczas gdy typ identyfikuje klasę dostawcy. Ponadto każdy zarejestrowany dostawca może zawierać ustawienia konfiguracji. Ustawienia konfiguracji dla platformy członkostwa obejmują passwordFormat i requiresUniqueEmail, między innymi. Zobacz tabelę 2, aby uzyskać pełną listę ustawień konfiguracji używanych przez usługę SqlMembershipProvider.

Zawartość Providers właściwości jest określana za pomocą ustawień konfiguracji aplikacji internetowej. Domyślnie wszystkie aplikacje internetowe mają dostawcę o nazwie AspNetSqlMembershipProvider typu SqlMembershipProvider. Ten domyślny dostawca członkostwa jest zarejestrowany w machine.config lokalizacji (znajdującej się w lokalizacji %WINDIR%\Microsoft.Net\Framework\v2.0.50727\CONFIG):

<membership>
 <providers>
 <add name="AspNetSqlMembershipProvider"
 type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 
 connectionStringName="LocalSqlServer"
 enablePasswordRetrieval="false"
 enablePasswordReset="true"
 requiresQuestionAndAnswer="true"
 applicationName="/"
 requiresUniqueEmail="false"
 passwordFormat="Hashed"
 maxInvalidPasswordAttempts="5"
 minRequiredPasswordLength="7"
 minRequiredNonalphanumericCharacters="1"
 passwordAttemptWindow="10"
 passwordStrengthRegularExpression=""/>
 </providers> 
</membership>

Jak pokazuje powyższy znacznik, <membership> element definiuje ustawienia konfiguracji dla struktury członkostwa, podczas gdy <providers> element podrzędny określa zarejestrowanych dostawców. Dostawcy mogą zostać dodani lub usunięci przy użyciu <add> elementów lub <remove> . Użyj <clear> elementu , aby usunąć wszystkich aktualnie zarejestrowanych dostawców. Jak pokazano powyżej znaczniki, machine.config dodaje dostawcę o nazwie AspNetSqlMembershipProvider typu SqlMembershipProvider.

Oprócz name atrybutów i type element zawiera atrybuty <add> definiujące wartości dla różnych ustawień konfigurowania. Tabela 2 zawiera listę dostępnych SqlMembershipProviderustawień konfiguracji specyficznych dla poszczególnych elementów wraz z opisem każdego z nich.

Uwaga

Wszystkie wartości domyślne zanotowane w tabeli 2 odwołują się do wartości domyślnych zdefiniowanych w SqlMembershipProvider klasie. Należy pamiętać, że nie wszystkie ustawienia konfiguracji w programie AspNetSqlMembershipProvider odpowiadają wartościom SqlMembershipProvider domyślnym klasy. Jeśli na przykład nie zostanie określony w dostawcy członkostwa, requiresUniqueEmail ustawienie ma wartość true. Zastępuje jednak tę wartość domyślną, AspNetSqlMembershipProvider jawnie określając wartość .false

Ustawienie<_o3a_p /> Opis<_o3a_p />
ApplicationName Pamiętaj, że struktura członkostwa umożliwia partycjonowanie jednego magazynu użytkowników w wielu aplikacjach. To ustawienie wskazuje nazwę partycji aplikacji używanej przez dostawcę członkostwa. Jeśli ta wartość nie zostanie jawnie określona, zostanie ustawiona w czasie wykonywania na wartość wirtualnej ścieżki głównej aplikacji.
commandTimeout Określa wartość limitu czasu polecenia SQL (w sekundach). Wartość domyślna to 30.
connectionStringName Nazwa parametry połączenia w elemecie używanym <connectionStrings> do nawiązywania połączenia z bazą danych magazynu użytkowników. Ta wartość jest wymagana.
description Zawiera przyjazny dla człowieka opis zarejestrowanego dostawcy.
enablePasswordRetrieval Określa, czy użytkownicy mogą pobrać zapomniane hasło. Wartość domyślna to false.
enablePasswordReset Wskazuje, czy użytkownicy mogą zresetować swoje hasło. Wartość domyślna to true.
maxInvalidPasswordAttempts Maksymalna liczba nieudanych prób logowania, które mogą wystąpić dla danego użytkownika podczas określonego passwordAttemptWindow przed zablokowaniem użytkownika. Wartość domyślna to 5.
minRequiredNonalphanumericCharacters Minimalna liczba znaków innych niż alfanumeryczne, które muszą być wyświetlane w haśle użytkownika. Ta wartość musi należeć do zakresu od 0 do 128; wartość domyślna to 1.
minRequiredPasswordLength Minimalna liczba znaków wymaganych w haśle. Ta wartość musi należeć do zakresu od 0 do 128; wartość domyślna to 7.
name Nazwa zarejestrowanego dostawcy. Ta wartość jest wymagana.
passwordAttemptWindow Liczba minut, w których są śledzone nieudane próby logowania. Jeśli użytkownik dostarcza nieprawidłowe poświadczenia maxInvalidPasswordAttempts logowania w tym określonym oknie, zostanie zablokowany. Wartość domyślna to 10.
PasswordFormat Format magazynu haseł: Clear, Hashedlub Encrypted. Wartość domyślna to Hashed.
passwordStrengthRegularExpression Jeśli to wyrażenie regularne jest używane do oceny siły wybranego hasła użytkownika podczas tworzenia nowego konta lub zmiany hasła. Wartością domyślną jest ciąg pusty.
requiresQuestionAndAnswer Określa, czy użytkownik musi odpowiedzieć na swoje pytanie zabezpieczające podczas pobierania lub resetowania hasła. Wartość domyślna to true.
requiresUniqueEmail Wskazuje, czy wszystkie konta użytkowników w danej partycji aplikacji muszą mieć unikatowy adres e-mail. Wartość domyślna to true.
type Określa typ dostawcy. Ta wartość jest wymagana.

Tabela 2. Ustawienia członkostwa i SqlMembershipProvider konfiguracji

Oprócz AspNetSqlMembershipProviderprogramu inni dostawcy członkostwa mogą być zarejestrowani w oparciu o aplikację przez aplikację, dodając podobne znaczniki do Web.config pliku.

Uwaga

Struktura Role działa w taki sam sposób: w systemie istnieje domyślny zarejestrowany dostawca machine.config roli, a zarejestrowani dostawcy mogą być dostosowywani w oparciu o aplikację w Web.configsystemie . Szczegółowo przeanalizujemy strukturę Role i jej znaczniki konfiguracji w przyszłym samouczku.

DostosowywanieSqlMembershipProviderustawień

Wartość domyślna SqlMembershipProvider (AspNetSqlMembershipProvider) ma jego connectionStringName atrybut ustawiony na LocalSqlServerwartość . AspNetSqlMembershipProvider Podobnie jak dostawca, nazwa LocalSqlServer parametry połączenia jest zdefiniowana w pliku machine.config.

<connectionStrings> 
 <add name="LocalSqlServer" 
 connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" 
 providerName="System.Data.SqlClient"/> 
</connectionStrings>

Jak widać, ta parametry połączenia definiuje bazę danych SQL 2005 Express Edition znajdującą się w lokalizacji |DataDirectory|aspnetdb.mdf". Ciąg |DataDirectory| jest tłumaczony w czasie wykonywania, aby wskazywał ~/App_Data/ katalog, więc ścieżka bazy danych |DataDirectory|aspnetdb.mdf" tłumaczy się na ~/App_Data/aspnet.mdf.

Jeśli w pliku aplikacji Web.config nie określono żadnych informacji o dostawcy członkostwa, aplikacja używa domyślnego zarejestrowanego dostawcy członkostwa. AspNetSqlMembershipProvider ~/App_Data/aspnet.mdf Jeśli baza danych nie istnieje, środowisko uruchomieniowe ASP.NET automatycznie go utworzy i doda schemat usług aplikacji. Nie chcemy jednak używać bazy danych, a raczej chcemy użyć bazy danych utworzonej aspnet.mdfSecurityTutorials.mdf w kroku 2. Tę modyfikację można wykonać na jeden z dwóch sposobów:

  • Określanie wartości dla elementuLocalSqlServerparametry połączenia nazwę wWeb.config.LocalSqlServer Zastępując wartość nazwy parametry połączenia w systemie Web.config, możemy użyć domyślnego zarejestrowanego dostawcy członkostwa (AspNetSqlMembershipProvider) i prawidłowo pracować z bazą SecurityTutorials.mdf danych. Takie podejście jest w porządku, jeśli masz zawartość z ustawieniami konfiguracji określonymi przez AspNetSqlMembershipProviderusługę . Aby uzyskać więcej informacji na temat tej techniki, zobacz wpis w blogu Scott Guthrie, Configuring ASP.NET 2.0 Application Services to Use SQL Server 2000 or SQL Server 2005 (Konfigurowanie usług aplikacji w wersji 2.0 do korzystania z SQL Server 2000 lub SQL Server 2005).
  • Dodawanie nowego zarejestrowanego dostawcy typuSqlMembershipProvideri skonfiguruj jegoconnectionStringNameustawienie , aby wskazaćSecurityTutorials.mdf elementBazy danych. Takie podejście jest przydatne w scenariuszach, w których chcesz dostosować inne właściwości konfiguracji oprócz parametry połączenia bazy danych. W moich własnych projektach zawsze używam tego podejścia ze względu na jego elastyczność i czytelność.

Zanim dodamy nowego zarejestrowanego dostawcę odwołującego SecurityTutorials.mdf się do bazy danych, najpierw musimy dodać odpowiednią wartość parametry połączenia w sekcji w <connectionStrings> sekcji .Web.config Poniższy znacznik dodaje nowy parametry połączenia o nazwieSecurityTutorialsConnectionString, który odwołuje się do bazy danych SQL Server 2005 Express Edition SecurityTutorials.mdf w folderzeApp_Data.

<configuration>
 <connectionStrings>
 <add name="SecurityTutorialsConnectionString" 
 connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\SecurityTutorials.mdf;Integrated Security=True;User Instance=True" 
 providerName="System.Data.SqlClient"/> 
 </connectionStrings> 
 <system.web>
 ... Configuration markup  removed for brevity ... 
 </system.web>
</configuration>

Uwaga

Jeśli używasz alternatywnego pliku bazy danych, zaktualizuj parametry połączenia zgodnie z potrzebami. Aby uzyskać więcej informacji na temat tworzenia poprawnego parametry połączenia, zobacz ConnectionStrings.com.

Następnie dodaj następujący znacznik konfiguracji członkostwa do Web.config pliku. Ten znacznik rejestruje nowego dostawcę o nazwie SecurityTutorialsSqlMembershipProvider.

<configuration> 
 <connectionStrings>
 <add name="SecurityTutorialsConnectionString" 
 connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\SecurityTutorials.mdf;Integrated Security=True;User Instance=True" 
 providerName="System.Data.SqlClient"/>
 </connectionStrings> 
 <system.web>
 <membership defaultProvider="SecurityTutorialsSqlMembershipProvider">
 <providers>
 <!--Add a customized SqlMembershipProvider --> 
 <add name="SecurityTutorialsSqlMembershipProvider" 
 type="System.Web.Security.SqlMembershipProvider"
 connectionStringName="SecurityTutorialsConnectionString"
 enablePasswordRetrieval="false"
 enablePasswordReset="true"
 requiresQuestionAndAnswer="true"
 applicationName="SecurityTutorials"
 requiresUniqueEmail="true"
 passwordFormat="Hashed"
 maxInvalidPasswordAttempts="5"
 minRequiredPasswordLength="7"
 minRequiredNonalphanumericCharacters="1"
 passwordAttemptWindow="10"
 passwordStrengthRegularExpression=""/>
 </providers>
 </membership>
 ... Configuration markup removed for brevity ... 
 </system.web>
</configuration>

Oprócz zarejestrowania dostawcy SecurityTutorialsSqlMembershipProvider powyższe znaczniki definiują SecurityTutorialsSqlMembershipProvider jako dostawcę domyślnego (za pośrednictwem defaultProvider atrybutu <membership> w elemecie). Pamiętaj, że platforma członkostwa może mieć wielu zarejestrowanych dostawców. Ponieważ AspNetSqlMembershipProvider jest zarejestrowany jako pierwszy dostawca w systemie machine.config, służy jako dostawca domyślny, chyba że wskazujemy inaczej.

Obecnie nasza aplikacja ma dwóch zarejestrowanych dostawców: AspNetSqlMembershipProvider i SecurityTutorialsSqlMembershipProvider. Jednak przed zarejestrowaniem SecurityTutorialsSqlMembershipProvider dostawcy mogliśmy wyczyścić wszystkich wcześniej zarejestrowanych dostawców, dodając <clear /> element bezpośrednio przed naszym <add> elementem. Spowoduje to wyczyszczenie AspNetSqlMembershipProvider z listy zarejestrowanych dostawców, co oznacza, że SecurityTutorialsSqlMembershipProvider byłby to jedyny zarejestrowany dostawca członkostwa. Jeśli użyto tego podejścia, nie musimy oznaczać SecurityTutorialsSqlMembershipProvider go jako domyślnego dostawcy, ponieważ byłby to jedyny zarejestrowany dostawca członkostwa. Aby uzyskać więcej informacji na temat korzystania z usługi <clear />, zobacz Using When Adding Providers (Używanie <clear /> podczas dodawania dostawców).

Należy pamiętać, że connectionStringNameSecurityTutorialsSqlMembershipProviderustawienie odwołuje się do właśnie dodanej SecurityTutorialsConnectionString nazwy parametry połączenia i że jego applicationName ustawienie zostało ustawione na wartość SecurityTutorials. requiresUniqueEmail Ponadto ustawienie zostało ustawione na truewartość . Wszystkie inne opcje konfiguracji są identyczne z wartościami w pliku AspNetSqlMembershipProvider. Możesz tutaj wprowadzić wszelkie modyfikacje konfiguracji, jeśli chcesz. Na przykład można zaostrzyć siłę hasła, wymagając dwóch znaków innych niż alfanumeryczne zamiast jednego lub zwiększając długość hasła do ośmiu znaków zamiast siedmiu.

Uwaga

Pamiętaj, że struktura członkostwa umożliwia partycjonowanie jednego magazynu użytkowników w wielu aplikacjach. Ustawienie dostawcy applicationName członkostwa wskazuje aplikację używaną przez dostawcę podczas pracy z magazynem użytkowników. Ważne jest, aby jawnie ustawić wartość ustawienia applicationName konfiguracji, ponieważ jeśli applicationName parametr nie jest jawnie ustawiony, jest przypisany do wirtualnej ścieżki głównej aplikacji internetowej w czasie wykonywania. Działa to prawidłowo, jeśli wirtualna ścieżka główna aplikacji nie ulegnie zmianie, ale jeśli przeniesiesz aplikację do innej ścieżki, applicationName ustawienie również zmieni się. W takim przypadku dostawca członkostwa rozpocznie pracę z inną partycją aplikacji niż wcześniej. Konta użytkowników utworzone przed przeniesieniem będą znajdować się w innej partycji aplikacji, a ci użytkownicy nie będą już mogli logować się do witryny. Aby uzyskać bardziej szczegółową dyskusję na ten temat, zobacz Always Set the applicationName Property When Configuring ASP.NET 2.0 Membership and Other Providers (Zawsze ustawiaj właściwość podczas konfigurowania członkostwa ASP.NET 2.0 i innych dostawców).

Podsumowanie

W tym momencie mamy bazę danych ze skonfigurowanymi usługami aplikacji (SecurityTutorials.mdf) i skonfigurowaliśmy naszą aplikację internetową tak, aby platforma członkostwa korzystała z właśnie zarejestrowanego SecurityTutorialsSqlMembershipProvider dostawcy. Ten zarejestrowany dostawca jest typu SqlMembershipProvider i ma ustawiony connectionStringName odpowiedni parametry połączenia (SecurityTutorialsConnectionString) i jego applicationName wartość jawnie ustawioną.

Teraz jesteśmy gotowi do korzystania z platformy członkostwa z naszej aplikacji. W następnym samouczku sprawdzimy, jak utworzyć nowe konta użytkowników. Następnie zapoznamy się z uwierzytelnianiem użytkowników, wykonywaniem autoryzacji opartej na użytkowniku i przechowywaniem dodatkowych informacji związanych z użytkownikiem w bazie danych.

Szczęśliwe programowanie!

Dalsze informacje

Aby uzyskać więcej informacji na temat tematów omówionych w tym samouczku, zapoznaj się z następującymi zasobami:

Szkolenie wideo dotyczące tematów zawartych w tym samouczku

Informacje o autorze

Scott Mitchell, autor wielu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 2.0 w ciągu 24 godzin. Scott można dotrzeć na mitchell@4guysfromrolla.com lub za pośrednictwem swojego bloga pod adresem http://ScottOnWriting.NET.

Specjalne podziękowania

Ta seria samouczków została sprawdzona przez wielu pomocnych recenzentów. Główny recenzent tego samouczka to Alicja Maziarz. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresem mitchell@4GuysFromRolla.com.