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
Erstellen Sie eine von der UserNamePasswordValidator-Klasse abgeleitete Klasse.
public class CustomUserNameValidator : UserNamePasswordValidator {
Public Class CustomUserNameValidator Inherits UserNamePasswordValidator
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
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>.
Fügen Sie in der Konfigurationsdatei unter dem Element <system.serviceModel> ein <bindings>-Element hinzu.
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.
Legen Sie das Attribut
mode
der <Sicherheit> oder <Sicherheit> aufMessage
,Transport
oderTransportWithMessageCredential
fest.Legen Sie das Attribut
clientCredentialType
der <Nachricht> oder des <Transports> fest.Legen Sie bei Nutzung von Nachrichtensicherheit das Attribut
clientCredentialType
der <Nachricht> aufUserName
fest.Legen Sie bei Nutzung von Sicherheit auf Transportebene über HTTP(S) das Attribut
clientCredentialType
des <Transports> oder des <Transports> aufBasic
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>
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.
Fügen Sie dem Element <system.serviceModel> ein <behaviors>-Element als untergeordnetes Element hinzu.
Fügen Sie dem Element <behaviors> ein <serviceBehaviors> hinzu.
Fügen Sie ein <behavior>-Element hinzu, und legen Sie das Attribut
name
auf einen geeigneten Wert fest.Fügen Sie dem Element <behavior> ein <serviceCredentials> hinzu.
Fügen Sie dem <serviceCredentials> eine <userNameAuthentication> hinzu.
Legen Sie
userNamePasswordValidationMode
aufCustom
fest.Wichtig
Wenn der Wert
userNamePasswordValidationMode
nicht festgelegt wird, verwendet WCF die Windows-Authentifizierung statt des benutzerdefinierten Benutzernamen- und Kennwort-Validierungssteuerelements.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