Freigeben über


Vorgehensweise: Verwenden eines benutzerdefinierten Benutzernamens und eines Kennwort-Validierungssteuerelements

Wenn ein Benutzername und ein Kennwort für die Authentifizierung verwendet werden, verwendet Windows Communication Foundation (WCF) standardmäßig Windows zum Überprüfen des Benutzernamens und Kennworts. WCF ermöglicht jedoch benutzerdefinierte Schemas für Benutzernamen- und Kennwortauthentifizierung, die auch als Validierungssteuerelemente bezeichnet werden. Zum Verwenden eines benutzerdefinierten Benutzernamen- und Kennwort-Validierungssteuerelements erstellen und konfigurieren Sie eine Klasse, die sich von UserNamePasswordValidator ableitet.

Eine Beispielanwendung finden Sie unter Benutzername- und Kennwort-Validierungssteuerelement.

So erstellen Sie ein benutzerdefiniertes Benutzernamen- und Kennwort-Validierungssteuerelement

  1. Erstellen Sie eine von der UserNamePasswordValidator-Klasse abgeleitete Klasse.

    
    public class CustomUserNameValidator : UserNamePasswordValidator
    {
    
    Public Class CustomUserNameValidator
        Inherits UserNamePasswordValidator
    
  2. Implementieren Sie ein benutzerdefiniertes Authentifizierungsschema, indem Sie die Validate-Methode außer Kraft setzen.

    Verwenden Sie nicht den Code des folgenden Beispiels, der die Validate-Methode in einer Produktionsumgebung außer Kraft setzt. Ersetzen Sie den Code mit dem benutzerdefinierten Benutzernamen- und Kennwort-Validierungsschema. Möglicherweise müssen der Benutzername und das zugehörige Kennwort aus einer Datenbank abgerufen werden.

    Um dem Client Authentifizierungsfehler zurückzugeben, lösen Sie in der FaultException-Methode eine Validate aus.

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

So konfigurieren Sie einen Dienst für das Verwenden eines benutzerdefinierten Benutzernamen- und Kennwort-Validierungssteuerelements

  1. Konfigurieren Sie eine Bindung, die Nachrichtensicherheit über jedes beliebige Transportprotokoll oder Sicherheit auf Transportebene über HTTP(S) verwendet.

    Fügen Sie bei Nutzung von Nachrichtensicherheit eine der vom System bereitgestellten Bindungen hinzu, beispielsweise <wsHttpBinding> oder eine <customBinding>, die Nachrichtensicherheit und den Anmeldeinformationstyp UserName unterstützt.

    Fügen Sie bei Nutzung der Sicherheit auf Transportebene über HTTP(S) entweder wsHttpBinding<> oder <basicHttpBinding>, eine <netTcpBinding> oder <customBinding> hinzu, die HTTP(S) und das Authentifizierungsschema Basic verwendet.

    Hinweis

    Wenn Sie .NET Framework 3.5 oder höhere Versionen verwenden, können Sie ein benutzerdefiniertes Benutzernamen- und Kennwort-Validierungssteuerelement mit Nachrichten- und Transportsicherheit verwenden. Bei WinFX kann ein benutzerdefiniertes Benutzername- und Kennwort-Validierungssteuerelement nur mit Nachrichtensicherheit verwendet werden.

    Tipp

    Weitere Informationen zur Verwendung von <netTcpBinding> in diesem Kontext finden Sie unter <Sicherheit>.

    1. Fügen Sie in der Konfigurationsdatei unter dem Element <system.serviceModel> ein <bindings>-Element hinzu.

    2. Fügen Sie dem Abschnitt „Bindungen“ ein <wsHttpBinding>- oder <basicHttpBinding>-Element hinzu. Weitere Informationen zum Erstellen eines WCF-Bindungselements finden Sie unter Vorgehensweise: Angeben einer Dienstbindung in der Konfiguration.

    3. Legen Sie das Attribut mode der <Sicherheit> oder <Sicherheit> auf Message, Transportoder TransportWithMessageCredential fest.

    4. Legen Sie das Attribut clientCredentialType der <Nachricht> oder des <Transports> fest.

      Legen Sie bei Nutzung von Nachrichtensicherheit das Attribut clientCredentialType der <Nachricht> auf UserName fest.

      Legen Sie bei Nutzung von Sicherheit auf Transportebene über HTTP(S) das Attribut clientCredentialType des <Transports> oder des <Transports> auf Basic fest.

      Hinweis

      Wenn ein WCF-Dienst in Internet Information Services (IIS) unter Nutzung der Sicherheit auf Transportebene gehostet wird und die Eigenschaft UserNamePasswordValidationMode auf Custom festgelegt wurde, verwendet das benutzerdefinierte Authentifizierungsschema eine Teilmenge der Windows-Authentifizierung. Der Grund dafür: IIS führt in diesem Szenario die Windows-Authentifizierung aus, bevor WCF den benutzerdefinierten Authentifikator aufruft.

    Weitere Informationen zum Erstellen eines WCF-Bindungselements finden Sie unter Vorgehensweise: Angeben einer Dienstbindung in der Konfiguration.

    Das folgende Beispiel zeigt den Konfigurationscode für die Bindung:

    <system.serviceModel>
      <bindings>
      <wsHttpBinding>
          <binding name="Binding1">
            <security mode="Message">
              <message clientCredentialType="UserName" />
            </security>
          </binding>
        </wsHttpBinding>
      </bindings>
    </system.serviceModel>
    
  2. Konfigurieren Sie ein Verhalten, das angibt, dass ein benutzerdefiniertes Benutzername- und Kennwort-Validierungssteuerelement verwendet wird, um Benutzernamen/Kennwort-Paare für eingehende UserNameSecurityToken-Sicherheitstoken zu überprüfen.

    1. Fügen Sie dem Element <system.serviceModel> ein <behaviors>-Element als untergeordnetes Element hinzu.

    2. Fügen Sie dem Element <behaviors> ein <serviceBehaviors> hinzu.

    3. Fügen Sie ein <behavior>-Element hinzu, und legen Sie das Attribut name auf einen geeigneten Wert fest.

    4. Fügen Sie dem Element <behavior> ein <serviceCredentials> hinzu.

    5. Fügen Sie dem <serviceCredentials> eine <userNameAuthentication> hinzu.

    6. Legen Sie userNamePasswordValidationMode auf Custom fest.

      Wichtig

      Wenn der Wert userNamePasswordValidationMode nicht festgelegt wird, verwendet WCF die Windows-Authentifizierung statt des benutzerdefinierten Benutzernamen- und Kennwort-Validierungssteuerelements.

    7. Legen Sie den customUserNamePasswordValidatorType auf den Typ fest, der das benutzerdefinierte Benutzernamen- und Kennwort-Validierungssteuerelement darstellt.

    Im folgenden Beispiel wird das Fragment <serviceCredentials>bis zu diesem Punkt gezeigt:

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

Beispiel

Im folgenden Codebeispiel wird veranschaulicht, wie ein benutzerdefiniertes Benutzernamen- und Kennwort-Validierungssteuerelement erstellt wird. Verwenden Sie nicht den Code, der die Validate-Methode in einer Produktionsumgebung außer Kraft setzt. Ersetzen Sie den Code mit dem benutzerdefinierten Benutzernamen- und Kennwort-Validierungsschema. Möglicherweise müssen der Benutzername und das zugehörige Kennwort aus einer Datenbank abgerufen werden.

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

Weitere Informationen