Freigeben über


Nachrichtensicherheitszertifikat

Das MessageSecurity-Beispiel veranschaulicht, wie eine Anwendung implementiert wird, die WS-Security mit X.509 v3-Zertifikatauthentifizierung für den Client verwendet und die Serverauthentifizierung mithilfe des X.509 v3-Zertifikats des Servers erfordert. In diesem Beispiel werden Standardeinstellungen verwendet, sodass alle Anwendungsmeldungen zwischen Client und Server signiert und verschlüsselt sind. Dieses Beispiel basiert auf dem WSHttpBinding- und besteht aus einem Clientkonsolenprogramm und einer Dienstbibliothek, die von Internetinformationsdienste (INTERNET Information Services, IIS) gehostet wird. Der Dienst implementiert einen Vertrag, der ein Kommunikationsmuster für die Anforderungsantwort definiert.

Anmerkung

Die Setupprozedur und die Buildanweisungen für dieses Beispiel befinden sich am Ende dieses Themas.

Das Beispiel veranschaulicht das Steuern der Authentifizierung mithilfe der Konfiguration und das Abrufen der Identität des Aufrufers aus dem Sicherheitskontext, wie im folgenden Beispielcode gezeigt.

public class CalculatorService : ICalculator
{
    public string GetCallerIdentity()
    {
        // The client certificate is not mapped to a Windows identity by default.
        // ServiceSecurityContext.PrimaryIdentity is populated based on the information
        // in the certificate that the client used to authenticate itself to the service.
        return ServiceSecurityContext.Current.PrimaryIdentity.Name;
    }
    ...
}

Der Dienst macht einen Endpunkt für die Kommunikation mit dem Dienst und einen Endpunkt verfügbar, um das WSDL-Dokument des Diensts mithilfe des WS-MetadataExchange-Protokolls verfügbar zu machen, das mithilfe der Konfigurationsdatei (Web.config) definiert wird. Der Endpunkt besteht aus einer Adresse, einer Bindung und einem Vertrag. Die Bindung ist mit einem standardmäßigen <wsHttpBinding> Element konfiguriert, das standardmäßig die Nachrichtensicherheit verwendet. In diesem Beispiel wird das attribut clientCredentialType auf "Certificate" festgelegt, damit die Clientauthentifizierung erforderlich ist.

<system.serviceModel>
    <protocolMapping>
      <add scheme="http" binding="wsHttpBinding"/>
    </protocolMapping>
    <bindings>
      <wsHttpBinding>
        <!--
        This configuration defines the security mode as Message and
        the clientCredentialType as Certificate.
        -->
        <binding>
          <security mode ="Message">
            <message clientCredentialType="Certificate" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <!--For debugging purposes set the includeExceptionDetailInFaults attribute to true-->
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="False" />
          <!--
        The serviceCredentials behavior allows one to define a service certificate.
        A service certificate is used by the service to authenticate itself to its clients and to provide message protection.
        This configuration references the "localhost" certificate installed during the setup instructions.
        -->
          <serviceCredentials>
            <serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
            <clientCertificate>
              <!--
            Setting the certificateValidationMode to PeerOrChainTrust means that if the certificate
            is in the user's Trusted People store, then it will be 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" />
            </clientCertificate>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

Das Verhalten gibt die Anmeldeinformationen des Diensts an, die verwendet werden, wenn der Client den Dienst authentifiziert. Der Subjektname des Serverzertifikats wird im Attribut findValue im <serviceCredentials>-Element angegeben.

<!--For debugging purposes, set the includeExceptionDetailInFaults attribute to true.-->
<behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="False" />
          <!--
        The serviceCredentials behavior allows one to define a service certificate.
        A service certificate is used by the service to authenticate itself to its clients and to provide message protection.
        This configuration references the "localhost" certificate installed during the setup instructions.
        -->
          <serviceCredentials>
            <serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
            <clientCertificate>
              <!--
            Setting the certificateValidationMode to PeerOrChainTrust means that if the certificate
            is in the user's Trusted People store, then it will be 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" />
            </clientCertificate>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>

Die Clientendpunktkonfiguration besteht aus einer absoluten Adresse für den Dienstendpunkt, die Bindung und den Vertrag. Die Clientbindung ist mit dem entsprechenden Sicherheitsmodus und Authentifizierungsmodus konfiguriert. Stellen Sie bei der Ausführung in einem computerübergreifenden Szenario sicher, dass die Adresse des Dienstendpunkts entsprechend geändert wird.

<system.serviceModel>
    <client>
      <!-- Use a behavior to configure the client certificate to present to the service. -->
      <endpoint address="http://localhost/servicemodelsamples/service.svc" binding="wsHttpBinding" bindingConfiguration="Binding1" behaviorConfiguration="ClientCertificateBehavior" contract="Microsoft.Samples.Certificate.ICalculator"/>
    </client>

    <bindings>
      <wsHttpBinding>
        <!--
        This configuration defines the security mode as Message and
        the clientCredentialType as Certificate.
        -->
        <binding name="Binding1">
          <security mode="Message">
            <message clientCredentialType="Certificate"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
...
</system.serviceModel>

Die Clientimplementierung kann das zu verwendende Zertifikat entweder über die Konfigurationsdatei oder über Code festlegen. Das folgende Beispiel zeigt, wie das Zertifikat in der Konfigurationsdatei festgelegt wird.

<system.serviceModel>
  ...

<behaviors>
      <endpointBehaviors>
        <behavior name="ClientCertificateBehavior">
          <!--
        The clientCredentials behavior allows one to define a certificate to present to a service.
        A certificate is used by a client to authenticate itself to the service and provide message integrity.
        This configuration references the "client.com" certificate installed during the setup instructions.
        -->
          <clientCredentials>
            <clientCertificate findValue="client.com" storeLocation="CurrentUser" storeName="My" x509FindType="FindBySubjectName"/>
            <serviceCertificate>
              <!--
            Setting the certificateValidationMode to PeerOrChainTrust means that if the certificate
            is in the user's Trusted People store, then it will be 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 certificate 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>

Das folgende Beispiel zeigt, wie Sie den Dienst in Ihrem Programm aufrufen.

// Create a client.
CalculatorClient client = new CalculatorClient();

// Call the GetCallerIdentity service operation.
Console.WriteLine(client.GetCallerIdentity());
...
//Closing the client gracefully closes the connection and cleans up resources.
client.Close();

Wenn Sie das Beispiel ausführen, werden die Vorgangsanforderungen und -antworten im Clientkonsolenfenster angezeigt. Drücken Sie im Clientfenster die EINGABETASTE, um den Client zu schließen.

CN=client.com
Add(100,15.99) = 115.99
Subtract(145,76.54) = 68.46
Multiply(9,81.25) = 731.25
Divide(22,7) = 3.14285714285714
Press <ENTER> to terminate client.

Mit der Setup.bat Batchdatei, die in den Beispielen für Nachrichtensicherheit enthalten ist, können Sie den Client und den Server mit relevanten Zertifikaten konfigurieren, um eine gehostete Anwendung auszuführen, die zertifikatbasierte Sicherheit erfordert. Die Batchdatei kann in drei Modi ausgeführt werden. Um im Einzelcomputermodus auszuführen, geben Sie setup.bat in einer Entwickler-Eingabeaufforderung für Visual Studio ein; für den Dienstmodus, geben Sie setup.bat Dienstein; und für den Clientmodus, geben Sie setup.bat Clientein. Verwenden Sie den Client- und Servermodus, wenn Sie das Beispiel auf mehreren Computern ausführen. Ausführliche Informationen finden Sie im Einrichtungsverfahren am Ende dieses Themas. Im Folgenden finden Sie eine kurze Übersicht über die verschiedenen Abschnitte der Batchdateien, sodass sie so geändert werden können, dass sie in geeigneter Konfiguration ausgeführt werden können:

  • Erstellen des Clientzertifikats.

    Die folgende Zeile in der Batchdatei erstellt das Clientzertifikat. Der angegebene Clientname wird im Betreffsnamen des erstellten Zertifikats verwendet. Das Zertifikat wird im My-Speicher am Speicherort CurrentUser gespeichert.

    echo ************
    echo making client cert
    echo ************
    makecert.exe -sr CurrentUser -ss MY -a sha1 -n CN=%CLIENT_NAME% -sky exchange -pe
    
  • Installieren des Clientzertifikats im vertrauenswürdigen Zertifikatspeicher des Servers.

    Die folgende Zeile in der Batchdatei kopiert das Clientzertifikat in den TrustedPeople-Speicher des Servers, damit der Server die relevanten Vertrauens- oder Nicht-Vertrauensentscheidungen treffen kann. Damit ein im TrustedPeople-Speicher installiertes Zertifikat von einem Windows Communication Foundation (WCF)-Dienst als vertrauenswürdig eingestuft wird, muss der Clientzertifikatüberprüfungsmodus auf PeerOrChainTrust oder PeerTrustfestgelegt werden. Im vorherigen Dienstkonfigurationsbeispiel erfahren Sie, wie dies mithilfe einer Konfigurationsdatei geschehen kann.

    echo ************
    echo copying client cert to server's LocalMachine store
    echo ************
    certmgr.exe -add -r CurrentUser -s My -c -n %CLIENT_NAME% -r LocalMachine -s TrustedPeople
    
  • Erstellen des Serverzertifikats.

    Die folgenden Zeilen aus der Setup.bat Batchdatei erstellen das zu verwendende Serverzertifikat.

    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
    

    Die variable %SERVER_NAME% gibt den Servernamen an. Das Zertifikat wird im LocalMachine-Speicher gespeichert. Wenn die Setup.bat Batchdatei mit einem Dienstargument (z. B. setup.bat Dienst) ausgeführt wird, enthält die %SERVER_NAME% den vollqualifizierten Domänennamen des Computers. Andernfalls wird "localhost" standardmäßig verwendet.

  • Installieren des Serverzertifikats im vertrauenswürdigen Zertifikatspeicher des Clients.

    In der folgenden Zeile wird das Serverzertifikat in den Clientspeicher für vertrauenswürdige Personen kopiert. 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
    
  • Erteilen von Berechtigungen für den privaten Schlüssel des Zertifikats.

    Die folgenden Zeilen in der datei Setup.bat machen das im LocalMachine-Speicher gespeicherte Serverzertifikat für das ASP.NET-Arbeitsprozesskonto zugänglich.

    echo ************
    echo setting privileges on server certificates
    echo ************
    for /F "delims=" %%i in ('"%ProgramFiles%\ServiceModelSampleTools\FindPrivateKey.exe" My LocalMachine -n CN^=%SERVER_NAME% -a') do set PRIVATE_KEY_FILE=%%i
    set WP_ACCOUNT=NT AUTHORITY\NETWORK SERVICE
    (ver | findstr /C:"5.1") && set WP_ACCOUNT=%COMPUTERNAME%\ASPNET
    echo Y|cacls.exe "%PRIVATE_KEY_FILE%" /E /G "%WP_ACCOUNT%":R
    iisreset
    

    Anmerkung

    Wenn Sie eine nicht-amerikanische englische Edition von Windows verwenden, müssen Sie die Setup.bat-Datei bearbeiten und den Kontonamen "NT AUTHORITY\NETWORK SERVICE" durch das für Ihre Region entsprechende Äquivalent ersetzen.

Anmerkung

Die in dieser Batchdatei verwendeten Tools befinden sich entweder in C:\Program Files\Microsoft Visual Studio 8\Common7\tools oder C:\Program Files\Microsoft SDKs\Windows\v6.0\bin. Eines dieser Verzeichnisse muss sich in Ihrem Systempfad befinden. Wenn Sie Visual Studio installiert haben, besteht die einfachste Möglichkeit zum Abrufen dieses Verzeichnisses in Ihrem Pfad darin, die Entwickler-Eingabeaufforderung für Visual Studio zu öffnen. Klicken Sie auf Start, und wählen Sie dann Alle Programme, Visual Studio 2012, Toolsaus. Bei dieser Eingabeaufforderung sind die entsprechenden Pfade bereits konfiguriert. Andernfalls müssen Sie das entsprechende Verzeichnis manuell zu Ihrem Pfad hinzufügen.

So können Sie das Beispiel einrichten, erstellen und ausführen

  1. Stellen Sie sicher, dass Sie das One-Time Setup-Verfahren für die Windows Communication Foundation-Beispieleausgeführt haben.

  2. Um die C#- oder Visual Basic .NET-Edition der Lösung zu erstellen, befolgen Sie die Anweisungen in Building the Windows Communication Foundation Samples.

So führen Sie das Beispiel auf demselben Computer aus

  1. Öffnen Sie eine Entwickler-Eingabeaufforderung für Visual Studio mit Administratorrechten, und führen Sie Setup.bat aus dem Beispielinstallationsordner aus. Dadurch werden alle Zertifikate installiert, die für die Ausführung des Beispiels erforderlich sind.

    Anmerkung

    Die Setup.bat Batchdatei soll über eine Entwickler-Eingabeaufforderung für Visual Studio ausgeführt werden. Die Pfadumgebungsvariable verweist auf das Verzeichnis, in dem das SDK installiert ist. Diese Umgebungsvariable wird automatisch in einer Entwickler-Eingabeaufforderung für Visual Studio (2010) festgelegt.

  2. Überprüfen Sie den Zugriff auf den Dienst mithilfe eines Browsers, indem Sie die Adresse http://localhost/servicemodelsamples/service.svceingeben.

  3. Starten Sie Client.exe aus \client\bin. Clientaktivität wird in der Clientkonsolenanwendung angezeigt.

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

  1. Erstellen Sie ein Verzeichnis auf dem Dienstcomputer. Erstellen Sie eine virtuelle Anwendung namens servicemodelsamples für dieses Verzeichnis mithilfe des IIS-Verwaltungstools (Internet Information Services).

  2. Kopieren Sie die Dienstprogrammdateien aus "\inetpub\wwwroot\servicemodelsamples" in das virtuelle Verzeichnis auf dem Dienstcomputer. Stellen Sie sicher, dass Sie die Dateien im Unterverzeichnis \bin kopieren. Kopieren Sie außerdem die Dateien Setup.bat, Cleanup.batund ImportClientCert.bat auf den Dienstcomputer.

  3. Erstellen Sie ein Verzeichnis auf dem Clientcomputer für die Client-Binärdateien.

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

  5. Führen Sie auf dem Server setup.bat Dienst in einer Entwickler-Eingabeaufforderung für Visual Studio mit Administratorrechten aus. Wenn setup.bat mit dem Argument Dienst ausgeführt wird, wird ein Dienstzertifikat mit dem vollqualifizierten Domänennamen des Computers erstellt und das Dienstzertifikat in eine Datei namens Service.cer exportiert.

  6. Bearbeiten Sie Web.config, um den neuen Zertifikatnamen (im attribut findValue im <serviceCertificate>) widerzuspiegeln, der dem vollqualifizierten Domänennamen des Computers entspricht.

  7. Kopieren Sie die datei Service.cer aus dem Dienstverzeichnis in das Clientverzeichnis auf dem Clientcomputer.

  8. Führen Sie auf dem Client setup.bat client an einer Developer-Eingabeaufforderung für Visual Studio mit Administratorrechten aus. Wenn setup.bat mit dem Argument Client ausgeführt wird, wird ein Clientzertifikat mit dem Namen client.com erstellt und das Clientzertifikat in eine Datei namens Client.cer exportiert.

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

  10. Kopieren Sie die Client.cer Datei aus dem Clientverzeichnis in das Dienstverzeichnis auf dem Server.

  11. Führen Sie auf dem Client ImportServiceCert.bat in einer Entwickler-Eingabeaufforderung für Visual Studio mit Administratorrechten aus. Dadurch wird das Dienstzertifikat aus der Service.cer-Datei in den Speicher CurrentUser - TrustedPeople importiert.

  12. Führen Sie auf dem Server ImportClientCert.bat in einer Entwickler-Eingabeaufforderung für Visual Studio mit Administratorrechten aus. Dadurch wird das Clientzertifikat aus der Client.cer Datei in den LocalMachine - TrustedPeople-Speicher importiert.

  13. Starten Sie auf dem Clientcomputer Client.exe über ein Eingabeaufforderungsfenster. Falls der Client und der Dienst nicht kommunizieren können, lesen Sie Tipps zur Fehlerbehebung für WCF-Beispiele.

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.

    Anmerkung

    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.