Instrukcje: Używanie niestandardowej nazwy użytkownika i modułu weryfikacji hasła

Domyślnie gdy do uwierzytelniania jest używana nazwa użytkownika i hasło, program Windows Communication Foundation (WCF) używa systemu Windows do sprawdzania poprawności nazwy użytkownika i hasła. Jednak program WCF umożliwia używanie niestandardowych schematów uwierzytelniania nazw użytkowników i haseł, nazywanych również modułami sprawdzania poprawności. Aby dołączyć niestandardową nazwę użytkownika i moduł sprawdzania poprawności haseł, utwórz klasę pochodzącą z UserNamePasswordValidator programu , a następnie skonfiguruj ją.

Aby zapoznać się z przykładową aplikacją, zobacz Moduł sprawdzania poprawności hasła nazwy użytkownika.

Aby utworzyć niestandardową nazwę użytkownika i moduł sprawdzania poprawności haseł

  1. Utwórz klasę pochodzącą z klasy UserNamePasswordValidator.

    
    public class CustomUserNameValidator : UserNamePasswordValidator
    {
    
    Public Class CustomUserNameValidator
        Inherits UserNamePasswordValidator
    
  2. Zaimplementuj niestandardowy schemat uwierzytelniania, przesłaniając metodę Validate .

    Nie należy używać kodu w poniższym przykładzie, który zastępuje metodę Validate w środowisku produkcyjnym. Zastąp kod niestandardowym schematem weryfikacji nazwy użytkownika i hasła, który może obejmować pobieranie nazw użytkowników i par haseł z bazy danych.

    Aby zwrócić błędy uwierzytelniania z powrotem do klienta, należy zgłosić FaultException wartość w metodzie Validate .

    // This method validates users. It allows in two users, test1 and test2
    // with passwords 1tset and 2tset respectively.
    // This code is for illustration purposes only and
    // must not be used in a production environment because it is not secure.
    public override void Validate(string userName, string password)
    {
        if (null == userName || null == password)
        {
            throw new ArgumentNullException();
        }
    
        if (!(userName == "test1" && password == "1tset") && !(userName == "test2" && password == "2tset"))
        {
            // This throws an informative fault to the client.
            throw new FaultException("Unknown Username or Incorrect Password");
            // When you do not want to throw an informative fault to the client,
            // throw the following exception.
            // throw new SecurityTokenException("Unknown Username or Incorrect Password");
        }
    }
    
    ' This method validates users. It allows in two users, test1 and test2
    ' with passwords 1tset and 2tset respectively.
    ' This code is for illustration purposes only and
    ' must not be used in a production environment because it is not secure.
    Public Overrides Sub Validate(ByVal userName As String, ByVal password As String)
        If Nothing = userName OrElse Nothing = password Then
            Throw New ArgumentNullException()
        End If
    
        If Not (userName = "test1" AndAlso password = "[PLACEHOLDER]") AndAlso Not (userName = "test2" AndAlso password = "[PLACEHOLDER]") Then
            ' This throws an informative fault to the client.
            Throw New FaultException("Unknown Username or Incorrect Password")
            ' When you do not want to throw an informative fault to the client,
            ' throw the following exception:
            ' Throw New SecurityTokenException("Unknown Username or Incorrect Password")
        End If
    
    End Sub
    

Aby skonfigurować usługę do używania niestandardowej nazwy użytkownika i modułu sprawdzania poprawności hasła

  1. Skonfiguruj powiązanie korzystające z zabezpieczeń komunikatów za pośrednictwem dowolnego zabezpieczeń transportu lub na poziomie transportu za pośrednictwem protokołu HTTP(S).

    W przypadku korzystania z zabezpieczeń komunikatów dodaj jedno z powiązań dostarczanych przez system, takich jak <wsHttpBinding lub <customBinding>>, które obsługuje zabezpieczenia komunikatów i UserName typ poświadczeń.

    W przypadku korzystania z zabezpieczeń na poziomie transportu za pośrednictwem protokołu HTTP(S) dodaj <elementy wsHttpBinding> lub< basicHttpBinding>, <netTcpBinding lub< customBinding>> korzystające z protokołów HTTP(S) i schematu Basic uwierzytelniania.

    Uwaga

    W przypadku korzystania z programu .NET Framework 3.5 lub nowszego można użyć niestandardowego modułu sprawdzania nazwy użytkownika i hasła z zabezpieczeniami komunikatów i transportu. W systemie WinFX niestandardowy moduł sprawdzania nazwy użytkownika i hasła może być używany tylko z zabezpieczeniami komunikatów.

    Napiwek

    Aby uzyskać więcej informacji na temat korzystania z narzędzia <netTcpBinding> w tym kontekście, zobacz< zabezpieczenia>.

    1. W pliku konfiguracji w obszarze elementu system.serviceModel> dodaj <element bindings>.<

    2. Dodaj element <wsHttpBinding> lub <basicHttpBinding> do sekcji powiązań. Aby uzyskać więcej informacji na temat tworzenia elementu powiązania WCF, zobacz How to: Specify a Service Binding in Configuration (Instrukcje: określanie powiązania usługi w konfiguracji).

    3. mode Ustaw atrybut zabezpieczeń <lub< zabezpieczeń>> na Message, Transportlub .TransportWithMessageCredential

    4. clientCredentialType Ustaw atrybut< wiadomości> lub <transportu.>

      W przypadku korzystania z zabezpieczeń komunikatów ustaw clientCredentialType atrybut komunikatu><na UserNamewartość .

      W przypadku korzystania z zabezpieczeń na poziomie transportu za pośrednictwem protokołu HTTP(S) ustaw clientCredentialType atrybut <transportu> lub <transportu> na Basicwartość .

      Uwaga

      Gdy usługa WCF jest hostowana w usługach Internet Information Services (IIS) przy użyciu zabezpieczeń na poziomie transportu, a UserNamePasswordValidationMode właściwość jest ustawiona na Customwartość , niestandardowy schemat uwierzytelniania używa podzestawu uwierzytelniania systemu Windows. Dzieje się tak dlatego, że w tym scenariuszu usługi IIS przeprowadzają uwierzytelnianie systemu Windows przed wywołaniem niestandardowego wystawcy uwierzytelnienia WCF.

    Aby uzyskać więcej informacji na temat tworzenia elementu powiązania WCF, zobacz How to: Specify a Service Binding in Configuration (Instrukcje: określanie powiązania usługi w konfiguracji).

    W poniższym przykładzie pokazano kod konfiguracji powiązania:

    <system.serviceModel>
      <bindings>
      <wsHttpBinding>
          <binding name="Binding1">
            <security mode="Message">
              <message clientCredentialType="UserName" />
            </security>
          </binding>
        </wsHttpBinding>
      </bindings>
    </system.serviceModel>
    
  2. Skonfiguruj zachowanie określające, że niestandardowa nazwa użytkownika i moduł sprawdzania poprawności hasła są używane do weryfikowania nazw użytkowników i par haseł dla przychodzących UserNameSecurityToken tokenów zabezpieczających.

    1. Jako element podrzędny elementu system.serviceModel> dodaj< element behaviors>.<

    2. Dodaj element serviceBehaviors> do <elementu behaviors>.<

    3. <Dodaj element zachowania> i ustaw name atrybut na odpowiednią wartość.

    4. Dodaj element serviceCredentials> do <elementu zachowania>.<

    5. Dodaj element userNameAuthentication> do< elementu serviceCredentials>.<

    6. Ustaw opcję userNamePasswordValidationMode na Custom.

      Ważne

      Jeśli wartość nie jest ustawiona userNamePasswordValidationMode , program WCF używa uwierzytelniania systemu Windows zamiast niestandardowej nazwy użytkownika i modułu sprawdzania poprawności hasła.

    7. customUserNamePasswordValidatorType Ustaw typ reprezentujący niestandardową nazwę użytkownika i moduł sprawdzania poprawności haseł.

    W poniższym przykładzie pokazano <serviceCredentials> fragment do tego punktu:

    <serviceCredentials>
      <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Microsoft.ServiceModel.Samples.CalculatorService.CustomUserNameValidator, service" />
    </serviceCredentials>
    

Przykład

W poniższym przykładzie kodu pokazano, jak utworzyć niestandardową nazwę użytkownika i moduł sprawdzania poprawności hasła. Nie należy używać kodu, który zastępuje metodę Validate w środowisku produkcyjnym. Zastąp kod niestandardowym schematem weryfikacji nazwy użytkownika i hasła, który może obejmować pobieranie nazw użytkowników i par haseł z bazy danych.

using System;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;

using System.Security.Principal;

using System.ServiceModel;
Imports System.IdentityModel.Selectors
Imports System.IdentityModel.Tokens

Imports System.Security.Principal

Imports System.ServiceModel

public class CustomUserNameValidator : UserNamePasswordValidator
{
    // This method validates users. It allows in two users, test1 and test2
    // with passwords 1tset and 2tset respectively.
    // This code is for illustration purposes only and
    // must not be used in a production environment because it is not secure.
    public override void Validate(string userName, string password)
    {
        if (null == userName || null == password)
        {
            throw new ArgumentNullException();
        }

        if (!(userName == "test1" && password == "1tset") && !(userName == "test2" && password == "2tset"))
        {
            // This throws an informative fault to the client.
            throw new FaultException("Unknown Username or Incorrect Password");
            // When you do not want to throw an informative fault to the client,
            // throw the following exception.
            // throw new SecurityTokenException("Unknown Username or Incorrect Password");
        }
    }
}
Public Class CustomUserNameValidator
    Inherits UserNamePasswordValidator
    ' This method validates users. It allows in two users, test1 and test2
    ' with passwords 1tset and 2tset respectively.
    ' This code is for illustration purposes only and
    ' must not be used in a production environment because it is not secure.
    Public Overrides Sub Validate(ByVal userName As String, ByVal password As String)
        If Nothing = userName OrElse Nothing = password Then
            Throw New ArgumentNullException()
        End If

        If Not (userName = "test1" AndAlso password = "[PLACEHOLDER]") AndAlso Not (userName = "test2" AndAlso password = "[PLACEHOLDER]") Then
            ' This throws an informative fault to the client.
            Throw New FaultException("Unknown Username or Incorrect Password")
            ' When you do not want to throw an informative fault to the client,
            ' throw the following exception:
            ' Throw New SecurityTokenException("Unknown Username or Incorrect Password")
        End If

    End Sub
End Class

Zobacz też