Podrobné pokyny: Provádění vlastní ověřování a autorizace (Visual Basic)
Tento návod ukazuje, jak implementovat vlastní ověřování a autorizaci pomocí tříd, které vycházejí z IIdentity a IPrincipal. Tento návod také ukazuje, jak přepsat nastavení výchozí identity vláken aplikace (identity Windows) pomocí nastavení My.User.CurrentPrincipal na instanci třídy, která je odvozena od IPrincipal. Nové uživatelské informace jsou k dispozici ihned pomocí objektu My.User, který vrací informace o aktuální identitě uživatelského vlákna.
Obchodní aplikace často poskytují přístup ke údajům nebo prostředky na základě pověření uživatele. Tyto aplikace obvykle zkontrolují úlohu uživatel a poskytnout přístup k prostředkům na základě této role. Společný běhový jazykový modul poskytuje podporu pro autorizaci založenou na rolích, které vychází z účtů systému Windows nebo vlastních identit. Další informace naleznete v tématu Zabezpečení založené na rolích.
Začínáme
Nejprve vytvořte projekt s hlavním formuláře a formulářem přihlášení a poté jen nastavte k použití vlastního ověřování.
Vytvořit klientskou ukázkovou aplikaci
Vytvořit nový aplikační projekt Visual Basic modelu Windows Forms Další informace naleznete v tématu How to: Create a Windows Application Project.
Výchozí název hlavního formuláře je Form1
V nabídce Project (Projekt) klepněte na příkaz Add New Item (Přidat novou položku).
Vyberte Login Form šablonu a klikněte na tlačítko Přidat.
Výchozí název přihlašovacího formuláře je LoginForm1.
V nabídce Project (Projekt) klepněte na příkaz Add New Item (Přidat novou položku).
Vyberte šablonu Class, změňte název na SampleIIdentity a potom klikněte na položku Přidat.
V nabídce Project (Projekt) klepněte na příkaz Add New Item (Přidat novou položku).
Vyberte šablonu Class, změňte název na SampleIPrincipal a potom klikněte na položku Přidat.
V nabídce Project klikněte na příkaz ApplicationName> Properties.
V návrháři projektu klikněte na kartu Aplikace.
Změňte Režim ověřovánív rozevíracím seznamu na Definované aplikací.
Chcete-li nakonfigurovat hlavní formulář
Přepněte do Form1 v návrháři formulářů.
Přidejte Tlačítko na Form1 z Panelu nástrojů.
Výchozí název tlačítka je Button1.
Změňte text tlačítka na Authenticate.
Z Panelu nástrojů přidejte Label do Form1.
Výchozí název ovládacího prvku Label je Label1.
Změnit text ovládacího prvku Label na prázdný řetězec.
Z Panel nástrojů, přidejte Label na Form1.
Výchozí název ovládacího prvku Label je Label2.
Změnit text ovládacího prvku Label na prázdný řetězec.
Poklepejte na Button1 k vytvoření obslužná rutina události pro událost Click a pak otevřete editor kódu.
Do metody Button1_Click přidejte následující kód:
My.Forms.LoginForm1.ShowDialog() ' Check if the user was authenticated. If My.User.IsAuthenticated Then Me.Label1.Text = "Authenticated " & My.User.Name Else Me.Label1.Text = "User not authenticated" End If If My.User.IsInRole(ApplicationServices.BuiltInRole.Administrator) Then Me.Label2.Text = "User is an Administrator" Else Me.Label2.Text = "User is not an Administrator" End If
Můžete spustit aplikaci, ale protože není k dispozici žádný ověřovací kód, žádný uživatel nebude ověřen. Přidání ověřovacího kódu je popsána v následujícím oddílu.
Vytváření identit
.NET Framework používá rozhraní IIdentity a IPrincipal jako základ pro ověřování a autorizace. Aplikace může použít vlastní uživatelské ověřování implementací těchto rozhraní, jak ukazují tyto postupy.
Vytvořte třídu, která implementuje IIdentity
Vyberte soubor SampleIIdentity.vb v Průzkumník řešení.
Tato třída zapouzdří identitu uživatele.
V řádku po Public Class SampleIIdentity, přidejte následující kód k podědění z IIdentity.
Implements System.Security.Principal.IIdentity
Po přidání tohoto kódu a stiskněte klávesu ENTER, editor kódu vytvoří prázdné vlastnosti, které je nutné implementovat.
Přidejte soukromé pole k uchování uživatelského jména a hodnoty označující, zda byl uživatel ověřen.
Private nameValue As String Private authenticatedValue As Boolean Private roleValue As ApplicationServices.BuiltInRole
Zadejte následující kód do vlastnosti AuthenticationType.
Vlastnost AuthenticationType musí vrátit řetězec, který označuje aktuální ověřovací mechanismus.
V tomto příkladu je použito explicitně zadané ověřování, proto je řetězec "Custom Authentication". Pokud jsou data pro ověřování uživatele uloženy v databázi SQL serveru, může být hodnota "SqlDatabase".
Return "Custom Authentication"
Zadejte následující kód do vlastnosti IsAuthenticated.
Return authenticatedValue
Vlastnost IsAuthenticated musí vrátit hodnotu označující, zda byl uživatel ověřen.
Vlastnost Name musí vrátit název uživatele přidruženého k této identitě.
Zadejte následující kód v Name vlastnost.
Return nameValue
Vytvoří vlastnost, která vrátí role uživatele.
Public ReadOnly Property Role() As ApplicationServices.BuiltInRole Get Return roleValue End Get End Property
Vytvořit metodu Sub New, která inicializuje třídu ověřením uživatele a nastavením uživatelského názvu a role, na základě názvu a hesla.
Tato metoda volá metodu pod názvem IsValidNameAndPassword k určení zda uživatelský název a heslo jsou platné.
Public Sub New(ByVal name As String, ByVal password As String) ' The name is not case sensitive, but the password is. If IsValidNameAndPassword(name, password) Then nameValue = name authenticatedValue = True roleValue = ApplicationServices.BuiltInRole.Administrator Else nameValue = "" authenticatedValue = False roleValue = ApplicationServices.BuiltInRole.Guest End If End Sub
Vytvořte metodu s názvem IsValidNameAndPassword určující, zda je uživatelské jméno a heslo platné.
Poznámka k zabezpečení Ověřovací algoritmus musí pracovat s heslem bezpečně. Například heslo by nemělo být uloženo v polích třídy.
Neměli by jste ukládat uživatelské heslo ve vašem systému, protože pokud by tyto informace byly prozrazeny, není k dispozici žádné další zabezpečení. Může uložit hodnotu hash pro každé uživatelské heslo. (Hash funkce promíchá data tak, že vstupní soubor nemůže být odvozen z výstupu.) Heslo nemůže být určeno přímo z zahashované hodnoty.
Uživatel se zlými úmysly však může časem negenerovat slovník hashových hodnot všech možných hesel a poté vyhledat heslo pro danou hash hodnotu. K ochraně proti tomuto druhu útoku, by jste měli přidat příměs k heslu před jeho zaheshováním k vytvoření hash hodnoty s příměsí. Příměs je údaj navíc, který je jedinečný pro každé heslo, čímž znemožňuje předpočítání slovníku hash hodnot.
K chránění hesel před uživateli se zlými úmysly, by jste měli uložit pouze hash hodnoty s příměsí hesel, pokud možno na zabezpečeném počítači. Pro uživatele se zlými úmysly je velmi obtížné získat heslo z hashe s příměsí. V tomto příkladu jsou použity metody GetHashedPassword a GetSalt k načtení zahashovaného uživatelského hesla a příměsi.
Private Function IsValidNameAndPassword( ByVal username As String, ByVal password As String) As Boolean ' Look up the stored hashed password and salt for the username. Dim storedHashedPW As String = GetHashedPassword(username) Dim salt As String = GetSalt(username) 'Create the salted hash. Dim rawSalted As String = salt & Trim(password) Dim saltedPwBytes() As Byte = System.Text.Encoding.Unicode.GetBytes(rawSalted) Dim sha1 As New System.Security.Cryptography. SHA1CryptoServiceProvider Dim hashedPwBytes() As Byte = sha1.ComputeHash(saltedPwBytes) Dim hashedPw As String = Convert.ToBase64String(hashedPwBytes) ' Compare the hashed password with the stored password. Return hashedPw = storedHashedPW End Function
Vytvořit funkce s názvem GetHashedPassword a GetSalt, které vrací hodnotu zahashovaného hesla a příměs pro zadaného uživatele.
Poznámka k zabezpečení Neměli by jste se vyhnout pevnému kódování hodnoty zahashovaného hesla a příměsi do klientské aplikace z dvou důvodů. První, uživatel se zlými úmysly k nim může mít přístup a poté najít kolize v hash hodnotách. Za druhé nemůžete změnit ani odvolat heslo uživatele. Aplikace by měla získat zahashované hodnoty hesla a příměs pro daného uživatele ze zabezpečeného zdroje, který udržuje správce.
Přestože pro jednoduchost, v tomto příkladu je zahashované heslo a příměs pevně zakódovaná, měli by jste použít bezpečnější přístup v produkčním kódu. Může například ukládat informace o uživateli v databázi SQL serveru a přistupovat k ní pomocí uložených procedur. Další informace naleznete v tématu How to: Connect to Data in a Database.
Poznámka
Heslo odpovídající této napevno zakódované hodnotě zahashovaného hesla je uvedena v oddílu "Testování aplikace".
Private Function GetHashedPassword(ByVal username As String) As String ' Code that gets the user's hashed password goes here. ' This example uses a hard-coded hashed passcode. ' In general, the hashed passcode should be stored ' outside of the application. If Trim(username).ToLower = "testuser" Then Return "ZFFzgfsGjgtmExzWBRmZI5S4w6o=" Else Return "" End If End Function Private Function GetSalt(ByVal username As String) As String ' Code that gets the user's salt goes here. ' This example uses a hard-coded salt. ' In general, the salt should be stored ' outside of the application. If Trim(username).ToLower = "testuser" Then Return "Should be a different random value for each user" Else Return "" End If End Function
Soubor SampleIIdentity.vb by měl nyní obsahovat následující kód:
Public Class SampleIIdentity
Implements System.Security.Principal.IIdentity
Private nameValue As String
Private authenticatedValue As Boolean
Private roleValue As ApplicationServices.BuiltInRole
Public ReadOnly Property AuthenticationType() As String Implements System.Security.Principal.IIdentity.AuthenticationType
Get
Return "Custom Authentication"
End Get
End Property
Public ReadOnly Property IsAuthenticated() As Boolean Implements System.Security.Principal.IIdentity.IsAuthenticated
Get
Return authenticatedValue
End Get
End Property
Public ReadOnly Property Name() As String Implements System.Security.Principal.IIdentity.Name
Get
Return nameValue
End Get
End Property
Public ReadOnly Property Role() As ApplicationServices.BuiltInRole
Get
Return roleValue
End Get
End Property
Public Sub New(ByVal name As String, ByVal password As String)
' The name is not case sensitive, but the password is.
If IsValidNameAndPassword(name, password) Then
nameValue = name
authenticatedValue = True
roleValue = ApplicationServices.BuiltInRole.Administrator
Else
nameValue = ""
authenticatedValue = False
roleValue = ApplicationServices.BuiltInRole.Guest
End If
End Sub
Private Function IsValidNameAndPassword(
ByVal username As String,
ByVal password As String) As Boolean
' Look up the stored hashed password and salt for the username.
Dim storedHashedPW As String = GetHashedPassword(username)
Dim salt As String = GetSalt(username)
'Create the salted hash.
Dim rawSalted As String = salt & Trim(password)
Dim saltedPwBytes() As Byte =
System.Text.Encoding.Unicode.GetBytes(rawSalted)
Dim sha1 As New System.Security.Cryptography.
SHA1CryptoServiceProvider
Dim hashedPwBytes() As Byte = sha1.ComputeHash(saltedPwBytes)
Dim hashedPw As String = Convert.ToBase64String(hashedPwBytes)
' Compare the hashed password with the stored password.
Return hashedPw = storedHashedPW
End Function
Private Function GetHashedPassword(ByVal username As String) As String
' Code that gets the user's hashed password goes here.
' This example uses a hard-coded hashed passcode.
' In general, the hashed passcode should be stored
' outside of the application.
If Trim(username).ToLower = "testuser" Then
Return "ZFFzgfsGjgtmExzWBRmZI5S4w6o="
Else
Return ""
End If
End Function
Private Function GetSalt(ByVal username As String) As String
' Code that gets the user's salt goes here.
' This example uses a hard-coded salt.
' In general, the salt should be stored
' outside of the application.
If Trim(username).ToLower = "testuser" Then
Return "Should be a different random value for each user"
Else
Return ""
End If
End Function
End Class
Vytváření objektů zabezpečení
Dále je nutné implementovat třídu, která pochází z IPrincipal a s její pomocí vrátit instanci třídy SampleIIdentity.
Chcete-li vytvořit třídu, která implementuje IPrincipal
Vyberte soubor SampleIPrincipal.vb v Průzkumník řešení.
Tato třída zapouzdří identitu uživatele. Můžete použít objekt My.User k připojení tohoto objektu k aktuálnímu vláknu a k přístupu do uživatelské identity.
V řádku po Public Class SampleIPrincipal, přidejte následující kód k podědění z IPrincipal.
Implements System.Security.Principal.IPrincipal
Po přidání tohoto kódu a stiskněte klávesu ENTER, editor kódu vytvoří prázdné vlastnosti a metody, které musíte implementovat.
Přidejte soukromé pole k uložení přidružené identity k tomuto objektu zabezpečení.
Private identityValue As SampleIIdentity
Zadejte následující kód do vlastnosti Identity.
Return identityValue
Vlastnost Identity musí vrátit uživatelskou identitu pro aktuální objekt zabezpečení.
Zadejte následující kód do metody IsInRole.
Metoda IsInRole určuje, zda aktuální objekt zabezpečení patří do zadané role.
Return role = identityValue.Role.ToString
Vytvořte metodu Sub New, která inicializuje třída s novou instance SampleIIdentity s názvem a heslem zadaným uživatelem.
Public Sub New(ByVal name As String, ByVal password As String) identityValue = New SampleIIdentity(name, password) End Sub
Tento kód nastaví identitu uživatel pro třídu SampleIPrincipal.
Soubor SampleIIdentity.vb by měl nyní obsahovat následující kód:
Public Class SampleIPrincipal
Implements System.Security.Principal.IPrincipal
Private identityValue As SampleIIdentity
Public ReadOnly Property Identity() As System.Security.Principal.IIdentity Implements System.Security.Principal.IPrincipal.Identity
Get
Return identityValue
End Get
End Property
Public Function IsInRole(ByVal role As String) As Boolean Implements System.Security.Principal.IPrincipal.IsInRole
Return role = identityValue.Role.ToString
End Function
Public Sub New(ByVal name As String, ByVal password As String)
identityValue = New SampleIIdentity(name, password)
End Sub
End Class
Připojení formuláře pro přihlášení
Aplikace mohou být použity pomocí formuláře přihlášení k získání uživatelského jména a hesla. Může použít tyto informace k inicializaci instance třídy SampleIPrincipal a použít objekt My.User k nastavení identita aktuálního vlákna na tuto instanci.
Chcete-li nakonfigurovat formulář přihlášení
Vyberte LoginForm1 v návrháři.
Poklepejte na tlačítko OK k otevření editoru kódu pro událost Click.
Nahraďte kód ve metodě OK_Click následujícím kódem:
Dim samplePrincipal As New SampleIPrincipal( Me.UsernameTextBox.Text, Me.PasswordTextBox.Text) Me.PasswordTextBox.Text = "" If (Not samplePrincipal.Identity.IsAuthenticated) Then ' The user is still not validated. MsgBox("The username and password pair is incorrect") Else ' Update the current principal. My.User.CurrentPrincipal = samplePrincipal Me.Close() End If
Testování aplikace
Nyní, když má aplikace ověřovací kód, můžete spustit aplikaci a pokusit se o ověření uživatele.
Testování aplikace
Spuštění aplikace.
Klikněte na tlačítko Authenticate.
Otevře formulář pro přihlášení.
Zadejte TestUser do pole User name a BadPassword do pole Password a pak klikněte na tlačítko Ok.
Otevře se okno se zprávou informující uživatele, že zadané uživatelské jméno a heslo je nesprávné.
Klikněte na tlačítko OK k zavření okna se zprávou.
Klikněte na tlačítko Storno k zavření přihlašovacího formuláře.
Popisky na hlavní formulář jsou nyní ve stavu Uživatel nebyl ověřen a Uživatel není správce.
Klikněte na tlačítko Authenticate.
Otevře formulář pro přihlášení.
Zadejte TestUser do pole User name a Password do pole Password a pak klikněte na tlačítko Ok. Přesvědčte se, že heslo je zadáno se správně velkými písmeny.
Popisky v hlavní formuláři jsou nyní ve stavu Ověřený TestUser and Uživatel je správcem.
Viz také
Úkoly
How to: Connect to Data in a Database
Odkaz
Koncepty
Přístup k datům uživatele (Visual Basic)
Další zdroje
Ověřování a autorizace v rozhraní .NET Framework s jazykem Visual Basic