Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Beispiel wird veranschaulicht, wie ein benutzerdefinierter X.509-Zertifikat validator implementiert wird. Dies ist in Fällen hilfreich, in denen keiner der integrierten X.509-Zertifikatüberprüfungsmodi für die Anforderungen der Anwendung geeignet ist. Dieses Beispiel zeigt einen Dienst mit einem benutzerdefinierten Validator, der selbst ausgestellte Zertifikate akzeptiert. Der Client verwendet ein solches Zertifikat, um sich beim Dienst zu authentifizieren.
Hinweis: Da jeder ein selbst ausgestelltes Zertifikat erstellen kann, ist der vom Dienst verwendete benutzerdefinierte Validator weniger sicher als das Standardverhalten, das von ChainTrust X509CertificateValidationMode bereitgestellt wird. Die Sicherheitsauswirkungen sollten sorgfältig berücksichtigt werden, bevor Sie diese Validierungslogik im Produktionscode verwenden.
In der Zusammenfassung dieses Beispiels wird gezeigt, wie:
Der Client kann mit einem X.509-Zertifikat authentifiziert werden.
Der Server überprüft die Clientanmeldeinformationen mithilfe eines benutzerdefinierten X509CertificateValidator.
Der Server wird mithilfe des X.509-Zertifikats des Servers authentifiziert.
Der Dienst macht einen einzelnen Endpunkt für die Kommunikation mit dem Dienst verfügbar, der mithilfe der Konfigurationsdatei App.configdefiniert wird. Der Endpunkt besteht aus einer Adresse, einer Bindung und einem Vertrag. Die Bindung ist mit einem Standard wsHttpBinding
konfiguriert, der standardmäßig WSSecurity
und die Authentifizierung mit Clientzertifikaten verwendet. Das Dienstverhalten gibt den benutzerdefinierten Modus für die Überprüfung von Client X.509-Zertifikaten zusammen mit dem Typ der Validatorklasse an. Das Verhalten gibt auch das Serverzertifikat mithilfe des serviceCertificate-Elements an. Das Serverzertifikat muss denselben Wert für SubjectName
wie findValue
im <serviceCertificate> enthalten.
<system.serviceModel>
<services>
<service name="Microsoft.ServiceModel.Samples.CalculatorService"
behaviorConfiguration="CalculatorServiceBehavior">
<!-- use host/baseAddresses to configure base address -->
<!-- provided by host -->
<host>
<baseAddresses>
<add baseAddress =
"http://localhost:8001/servicemodelsamples/service" />
</baseAddresses>
</host>
<!-- use base address specified above, provide one endpoint -->
<endpoint address="certificate"
binding="wsHttpBinding"
bindingConfiguration="Binding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
</service>
</services>
<bindings>
<wsHttpBinding>
<!-- X509 certificate binding -->
<binding name="Binding">
<security mode="Message">
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceDebug includeExceptionDetailInFaults ="true"/>
<serviceCredentials>
<!-- The serviceCredentials behavior allows one -->
<!-- to specify authentication constraints on -->
<!-- client certificates. -->
<clientCertificate>
<!-- Setting the certificateValidationMode to -->
<!-- Custom means that if the custom -->
<!-- X509CertificateValidator does NOT throw -->
<!-- an exception, then the provided certificate -->
<!-- will be trusted without performing any -->
<!-- validation beyond that performed by the custom -->
<!-- validator. The security implications of this -->
<!-- setting should be carefully considered before -->
<!-- using Custom in production code. -->
<authentication
certificateValidationMode="Custom"
customCertificateValidatorType =
"Microsoft.ServiceModel.Samples.CustomX509CertificateValidator, service" />
</clientCertificate>
<!-- The serviceCredentials behavior allows one to -->
<!-- define a service certificate. -->
<!-- A service certificate is used by a client to -->
<!-- authenticate the service and provide message -->
<!-- protection. This configuration references the -->
<!-- "localhost" certificate installed during the setup -->
<!-- instructions. -->
<serviceCertificate findValue="localhost"
storeLocation="LocalMachine"
storeName="My" x509FindType="FindBySubjectName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Die Clientendpunktkonfiguration besteht aus einem Konfigurationsnamen, einer absoluten Adresse für den Dienstendpunkt, der Bindung und dem Vertrag. Die Clientbindung ist mit dem entsprechenden Modus und der entsprechenden Nachricht clientCredentialType
konfiguriert.
<system.serviceModel>
<client>
<!-- X509 certificate based endpoint -->
<endpoint name="Certificate"
address=
"http://localhost:8001/servicemodelsamples/service/certificate"
binding="wsHttpBinding"
bindingConfiguration="Binding"
behaviorConfiguration="ClientCertificateBehavior"
contract="Microsoft.ServiceModel.Samples.ICalculator">
</endpoint>
</client>
<bindings>
<wsHttpBinding>
<!-- X509 certificate binding -->
<binding name="Binding">
<security mode="Message">
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="ClientCertificateBehavior">
<clientCredentials>
<serviceCertificate>
<!-- Setting the certificateValidationMode to -->
<!-- PeerOrChainTrust means that if the certificate -->
<!-- is in the user's Trusted People store, then it -->
<!-- is trusted without performing a validation of -->
<!-- the certificate's issuer chain. -->
<!-- This setting is used here for convenience so -->
<!-- that the sample can be run without having to -->
<!-- have certificates issued by a certification -->
<!-- authority (CA). This setting is less secure -->
<!-- than the default, ChainTrust. The security -->
<!-- implications of this setting should be -->
<!-- carefully considered before using -->
<!-- PeerOrChainTrust in production code.-->
<authentication
certificateValidationMode="PeerOrChainTrust" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
Die Clientimplementierung legt das zu verwendende Clientzertifikat fest.
// Create a client with Certificate endpoint configuration
CalculatorClient client = new CalculatorClient("Certificate");
try
{
client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindBySubjectName, "test1");
// Call the Add service operation.
double value1 = 100.00D;
double value2 = 15.99D;
double result = client.Add(value1, value2);
Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);
// Call the Subtract service operation.
value1 = 145.00D;
value2 = 76.54D;
result = client.Subtract(value1, value2);
Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);
// Call the Multiply service operation.
value1 = 9.00D;
value2 = 81.25D;
result = client.Multiply(value1, value2);
Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);
// Call the Divide service operation.
value1 = 22.00D;
value2 = 7.00D;
result = client.Divide(value1, value2);
Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);
client.Close();
}
catch (TimeoutException e)
{
Console.WriteLine("Call timed out : {0}", e.Message);
client.Abort();
}
catch (CommunicationException e)
{
Console.WriteLine("Call failed : {0}", e.Message);
client.Abort();
}
catch (Exception e)
{
Console.WriteLine("Call failed : {0}", e.Message);
client.Abort();
}
In diesem Beispiel wird ein benutzerdefiniertes X509CertificateValidator zum Überprüfen von Zertifikaten verwendet. Das Beispiel implementiert CustomX509CertificateValidator, abgeleitet von X509CertificateValidator. Sehen Sie die Dokumentation über X509CertificateValidator für weitere Informationen. In diesem speziellen benutzerdefinierten Validatorbeispiel wird die Validate-Methode implementiert, um jedes X.509-Zertifikat zu akzeptieren, das selbst ausgestellt ist, wie im folgenden Code gezeigt.
public class CustomX509CertificateValidator : X509CertificateValidator
{
public override void Validate ( X509Certificate2 certificate )
{
// Only accept self-issued certificates
if (certificate.Subject != certificate.Issuer)
throw new Exception("Certificate is not self-issued");
}
}
Sobald der Validator im Dienstcode implementiert ist, muss der Diensthost über die zu verwendende Validatorinstanz informiert werden. Dazu wird der folgende Code verwendet.
serviceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.Custom;
serviceHost.Credentials.ClientCertificate.Authentication.CustomCertificateValidator = new CustomX509CertificateValidator();
Alternativ können Sie dies auch in der Konfiguration wie folgt tun.
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
...
<serviceCredentials>
<!--The serviceCredentials behavior allows one to specify -->
<!--authentication constraints on client certificates.-->
<clientCertificate>
<!-- Setting the certificateValidationMode to Custom means -->
<!--that if the custom X509CertificateValidator does NOT -->
<!--throw an exception, then the provided certificate will -->
<!--be trusted without performing any validation beyond that -->
<!--performed by the custom validator. The security -->
<!--implications of this setting should be carefully -->
<!--considered before using Custom in production code. -->
<authentication certificateValidationMode="Custom"
customCertificateValidatorType =
"Microsoft.ServiceModel.Samples. CustomX509CertificateValidator, service" />
</clientCertificate>
</serviceCredentials>
...
</behavior>
</serviceBehaviors>
</behaviors>
Wenn Sie das Beispiel ausführen, werden die Vorgangsanforderungen und -antworten im Clientkonsolenfenster angezeigt. Der Client sollte alle Methoden erfolgreich aufrufen. Drücken Sie im Clientfenster die EINGABETASTE, um den Client zu schließen.
Batchdatei einrichten
Mit der in diesem Beispiel enthaltenen Setup.bat Batchdatei können Sie den Server mit relevanten Zertifikaten konfigurieren, um eine selbst gehostete Anwendung auszuführen, die serverzertifikatbasierte Sicherheit erfordert. Diese Batchdatei muss so geändert werden, dass sie auf Computern oder in einem nicht gehosteten Fall funktioniert.
Im Folgenden finden Sie eine kurze Übersicht über die verschiedenen Abschnitte der Batchdateien, um sie entsprechend zu konfigurieren und auszuführen.
Erstellen des Serverzertifikats:
Die folgenden Zeilen aus der Setup.bat Batchdatei erstellen das zu verwendende Serverzertifikat. Die variable %SERVER_NAME% gibt den Servernamen an. Ändern Sie diese Variable, um Ihren eigenen Servernamen anzugeben. Der Standardwert ist localhost.
echo ************ echo Server cert setup starting echo %SERVER_NAME% echo ************ echo making server cert echo ************ makecert.exe -sr LocalMachine -ss MY -a sha1 -n CN=%SERVER_NAME% -sky exchange -pe
Installieren des Serverzertifikats im vertrauenswürdigen Zertifikatspeicher des Clients:
Die folgenden Zeilen in der Setup.bat Batchdatei kopieren das Serverzertifikat in den Clientspeicher für vertrauenswürdige Personen. Dieser Schritt ist erforderlich, da von Makecert.exe generierte Zertifikate nicht implizit vom Clientsystem vertrauenswürdig sind. Wenn Sie bereits über ein Zertifikat verfügen, das in einem vertrauenswürdigen Stammzertifikat des Clients verwurzelt ist, z. B. ein von Microsoft ausgestelltes Zertifikat, ist dieser Schritt zum Auffüllen des Clientzertifikatspeichers mit dem Serverzertifikat nicht erforderlich.
certmgr.exe -add -r LocalMachine -s My -c -n %SERVER_NAME% -r CurrentUser -s TrustedPeople
Erstellen des Clientzertifikats:
Die folgenden Zeilen aus der Setup.bat Batchdatei erstellen das zu verwendende Clientzertifikat. Die variable %USER_NAME% gibt den Clientnamen an. Dieser Wert ist auf "test1" festgelegt, da dies der Name ist, nach dem der Clientcode sucht. Wenn Sie den Wert von %USER_NAME% ändern, müssen Sie den entsprechenden Wert in der Client.cs Quelldatei ändern und den Client neu erstellen.
Das Zertifikat wird im persönlichen Speicher unterhalb von CurrentUser gespeichert.
echo ************ echo Client cert setup starting echo %USER_NAME% echo ************ echo making client cert echo ************ makecert.exe -sr CurrentUser -ss MY -a sha1 -n CN=%USER_NAME% -sky exchange -pe
Installieren des Clientzertifikats im vertrauenswürdigen Zertifikatspeicher des Servers:
Die folgenden Zeilen in der Setup.bat Batchdatei kopieren das Clientzertifikat in den Speicher für vertrauenswürdige Personen. Dieser Schritt ist erforderlich, da von Makecert.exe generierte Zertifikate nicht implizit vom Serversystem vertrauenswürdig sind. Wenn Sie bereits über ein Zertifikat verfügen, das in einem vertrauenswürdigen Stammzertifikat verwurzelt ist, z. B. ein von Microsoft ausgestelltes Zertifikat, ist dieser Schritt zum Auffüllen des Serverzertifikatspeichers mit dem Clientzertifikat nicht erforderlich.
certmgr.exe -add -r CurrentUser -s My -c -n %USER_NAME% -r LocalMachine -s TrustedPeople
So richten Sie das Beispiel ein und erstellen es
Befolgen Sie zum Erstellen der Lösung die Anweisungen im Erstellen der Windows Communication Foundation-Beispiele.
Verwenden Sie die folgenden Anweisungen, um das Beispiel in einer Konfiguration mit einem einzigen oder computerübergreifenden Computer auszuführen.
So führen Sie das Beispiel auf demselben Computer aus
Führen Sie Setup.bat aus dem Beispielinstallationsordner in einer Visual Studio-Eingabeaufforderung aus, die mit Administratorrechten geöffnet wurde. Dadurch werden alle Zertifikate installiert, die für die Ausführung des Beispiels erforderlich sind.
Von Bedeutung
Die Setup.bat Batchdatei ist so konzipiert, dass sie über eine Visual Studio-Eingabeaufforderung ausgeführt werden kann. Die PATH-Umgebungsvariable, die in der Visual Studio-Eingabeaufforderung festgelegt ist, verweist auf das Verzeichnis, das ausführbare Dateien enthält, die vom skript Setup.bat benötigt werden.
Starten Sie Service.exe von "service\bin".
Starten Sie Client.exe aus \client\bin. Clientaktivität wird in der Clientkonsolenanwendung angezeigt.
Wenn der Client und der Dienst nicht kommunizieren können, schauen Sie sich Tipps zur Problembehandlung für WCF-Samplesan.
So führen Sie das Beispiel computerübergreifend aus
Erstellen Sie ein Verzeichnis auf dem Dienstcomputer.
Kopieren Sie die Dienstprogrammdateien aus \service\bin in das virtuelle Verzeichnis auf dem Dienstcomputer. Kopieren Sie außerdem die dateien Setup.bat, Cleanup.bat, GetComputerName.vbs und ImportClientCert.bat auf den Dienstcomputer.
Erstellen Sie ein Verzeichnis auf dem Clientcomputer für die Client-Binärdateien.
Kopieren Sie die Clientprogrammdateien in das Clientverzeichnis auf dem Clientcomputer. Kopieren Sie außerdem die Dateien Setup.bat, Cleanup.batund ImportServiceCert.bat auf den Client.
Führen Sie
setup.bat service
auf dem Server in einer Entwickler-Eingabeaufforderung für Visual Studio aus, die mit Administratorrechten geöffnet wurde. Wennsetup.bat
mit dem Argumentservice
ausgeführt wird, wird ein Dienstzertifikat mit dem vollqualifizierten Domänennamen des Computers erstellt und das Dienstzertifikat in eine Datei namens Service.cer exportiert.Bearbeiten Sie Service.exe.config, um den neuen Zertifikatnamen (im
findValue
Attribut in serviceCertificate<>) widerzuspiegeln, der dem vollqualifizierten Domänennamen des Computers entspricht. Ändern Sie außerdem den Computernamen im Element "service</>baseAddresses<" von "localhost" in >den vollqualifizierten Namen Ihres Dienstcomputers.Kopieren Sie die datei Service.cer aus dem Dienstverzeichnis in das Clientverzeichnis auf dem Clientcomputer.
Führen Sie
setup.bat client
auf dem Client in einer Entwickler-Eingabeaufforderung für Visual Studio aus, die mit Administratorrechten geöffnet wurde. Wenn Siesetup.bat
mit dem Argumentclient
ausführen, wird ein Clientzertifikat mit dem Namen client.com erstellt und das Clientzertifikat in eine Datei mit dem Namen Client.cer exportiert.Ändern Sie in der datei Client.exe.config auf dem Clientcomputer den Adresswert des Endpunkts so, dass er mit der neuen Adresse Ihres Diensts übereinstimmt. Ersetzen Sie dazu localhost durch den vollqualifizierten Domänennamen des Servers.
Kopieren Sie die Client.cer Datei aus dem Clientverzeichnis in das Dienstverzeichnis auf dem Server.
Führen Sie auf dem Client ImportServiceCert.bat in einer Entwickler-Eingabeaufforderung für Visual Studio aus, die mit Administratorrechten geöffnet wurde. Dadurch wird das Dienstzertifikat aus der Service.cer-Datei in den Speicher CurrentUser - TrustedPeople importiert.
Führen Sie auf dem Server ImportClientCert.bat in einer Entwickler-Eingabeaufforderung für Visual Studio aus, die mit Administratorrechten geöffnet wurde. Dadurch wird das Clientzertifikat aus der Client.cer Datei in den LocalMachine - TrustedPeople-Speicher importiert.
Starten Sie auf dem Servercomputer Service.exe vom Eingabeaufforderungsfenster aus.
Starten Sie auf dem Clientcomputer Client.exe über ein Eingabeaufforderungsfenster. Wenn der Client und der Dienst nicht kommunizieren können, schauen Sie sich Tipps zur Problembehandlung für WCF-Samplesan.
So stellen Sie den Zustand vor Ausführung des Beispiels wieder her
- Führen Sie Cleanup.bat im Beispielordner aus, nachdem Sie die Ausführung des Beispiels abgeschlossen haben. Dadurch werden die Server- und Clientzertifikate aus dem Zertifikatspeicher entfernt.
Hinweis
Dieses Skript entfernt keine Dienstzertifikate auf einem Client, wenn dieses Beispiel auf computernübergreifend ausgeführt wird. Wenn Sie Beispiele für Windows Communication Foundation (WCF) ausgeführt haben, die Zertifikate auf mehreren Computern verwenden, sollten Sie die Dienstzertifikate löschen, die im CurrentUser-TrustedPeople-Speicher installiert wurden. Verwenden Sie dazu den folgenden Befehl: certmgr -del -r CurrentUser -s TrustedPeople -c -n <Fully Qualified Server Machine Name>
Beispiel: certmgr -del -r CurrentUser -s TrustedPeople -c -n server1.contoso.com
.