Sdílet prostřednictvím


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

  1. 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

  2. V nabídce Project (Projekt) klepněte na příkaz Add New Item (Přidat novou položku).

  3. Vyberte Login Form šablonu a klikněte na tlačítko Přidat.

    Výchozí název přihlašovacího formuláře je LoginForm1.

  4. V nabídce Project (Projekt) klepněte na příkaz Add New Item (Přidat novou položku).

  5. Vyberte šablonu Class, změňte název na SampleIIdentity a potom klikněte na položku Přidat.

  6. V nabídce Project (Projekt) klepněte na příkaz Add New Item (Přidat novou položku).

  7. Vyberte šablonu Class, změňte název na SampleIPrincipal a potom klikněte na položku Přidat.

  8. V nabídce Project klikněte na příkaz ApplicationName> Properties.

  9. V návrháři projektu klikněte na kartu Aplikace.

  10. Změňte Režim ověřovánív rozevíracím seznamu na Definované aplikací.

Chcete-li nakonfigurovat hlavní formulář

  1. Přepněte do Form1 v návrháři formulářů.

  2. Přidejte Tlačítko na Form1 z Panelu nástrojů.

    Výchozí název tlačítka je Button1.

  3. Změňte text tlačítka na Authenticate.

  4. Z Panelu nástrojů přidejte Label do Form1.

    Výchozí název ovládacího prvku Label je Label1.

  5. Změnit text ovládacího prvku Label na prázdný řetězec.

  6. Z Panel nástrojů, přidejte Label na Form1.

    Výchozí název ovládacího prvku Label je Label2.

  7. Změnit text ovládacího prvku Label na prázdný řetězec.

  8. Poklepejte na Button1 k vytvoření obslužná rutina události pro událost Click a pak otevřete editor kódu.

  9. 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

  1. Vyberte soubor SampleIIdentity.vb v Průzkumník řešení.

    Tato třída zapouzdří identitu uživatele.

  2. 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.

  3. 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
    
  4. 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"
    
  5. 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.

  6. 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
    
  7. Vytvoří vlastnost, která vrátí role uživatele.

    Public ReadOnly Property Role() As ApplicationServices.BuiltInRole
        Get
            Return roleValue
        End Get
    End Property
    
  8. 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
    
  9. Vytvořte metodu s názvem IsValidNameAndPassword určující, zda je uživatelské jméno a heslo platné.

    Poznámka k zabezpečení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
    
  10. 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í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

  1. 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.

  2. 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.

  3. Přidejte soukromé pole k uložení přidružené identity k tomuto objektu zabezpečení.

    Private identityValue As SampleIIdentity
    
  4. 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í.

  5. 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
    
  6. 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í

  1. Vyberte LoginForm1 v návrháři.

  2. Poklepejte na tlačítko OK k otevření editoru kódu pro událost Click.

  3. 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

  1. Spuštění aplikace.

  2. Klikněte na tlačítko Authenticate.

    Otevře formulář pro přihlášení.

  3. 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é.

  4. Klikněte na tlačítko OK k zavření okna se zprávou.

  5. 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.

  6. Klikněte na tlačítko Authenticate.

    Otevře formulář pro přihlášení.

  7. 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

User

IIdentity

IPrincipal

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