Freigeben über


Nachrichtensicherheit über Message Queuing

Das MessageSecurity-Beispiel veranschaulicht, wie eine Anwendung implementiert wird, die WS-Security mit X.509v3-Zertifikatauthentifizierung für den Client verwendet und die Serverauthentifizierung mithilfe des X.509v3-Zertifikats des Servers über MSMQ erfordert. Die Nachrichtensicherheit ist manchmal wünschenswerter, um sicherzustellen, dass die Nachrichten im MSMQ-Speicher verschlüsselt bleiben und die Anwendung eine eigene Authentifizierung der Nachricht ausführen kann.

Dieses Beispiel basiert auf dem Beispiel Abgewickelte MSMQ-Bindung. Die Nachrichten werden verschlüsselt und signiert.

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. Wenn der Dienst zuerst ausgeführt wird, wird überprüft, ob die Warteschlange vorhanden ist. Wenn die Warteschlange nicht vorhanden ist, erstellt der Dienst eine. Sie können den Dienst zuerst ausführen, um die Warteschlange zu erstellen, oder Sie können einen über den MSMQ-Warteschlangen-Manager erstellen. Führen Sie die folgenden Schritte aus, um eine Warteschlange in Windows 2008 zu erstellen.

    1. Öffnen Sie den Server-Manager in Visual Studio 2012.

    2. Erweitern Sie die Registerkarte Features.

    3. Klicken Sie mit der rechten Maustaste auf Private Meldungswarteschlangen, und klicken Sie anschließend auf Neu und Private Warteschlange.

    4. Aktivieren Sie das Kontrollkästchen Transaktional.

    5. Geben Sie ServiceModelSamplesTransacted als Namen der neuen Warteschlange ein.

  3. Um die C#- oder Visual Basic-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. Stellen Sie sicher, dass der Pfad den Ordner enthält, der Makecert.exe und FindPrivateKey.exeenthält.

  2. Führen Sie Setup.bat aus dem Beispiel-Installationsordner aus. Dadurch werden alle Zertifikate installiert, die für die Ausführung des Beispiels erforderlich sind.

    Anmerkung

    Stellen Sie sicher, dass Sie die Zertifikate entfernen, indem Sie Cleanup.bat ausführen, wenn Sie mit dem Beispiel fertig sind. Andere Sicherheitsbeispiele verwenden dieselben Zertifikate.

  3. Starten Sie Service.exe aus \service\bin.

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

  5. Wenn Client und Dienst nicht kommunizieren können, finden Sie weitere Informationen unter Tipps zur Problembehandlung für WCF-Beispiele.

So führen Sie das Beispiel computerübergreifend aus

  1. Kopieren Sie die Dateien Setup.bat, Cleanup.batund ImportClientCert.bat auf den Dienstcomputer.

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

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

  4. Führen Sie setup.bat serviceauf dem Server aus. Wenn setup.bat mit dem Argument service ausgeführt wird, wird ein Dienstzertifikat mit dem vollqualifizierten Domänennamen des Computers erstellt und das Dienstzertifikat in eine Datei namens Service.cer exportiert.

  5. Bearbeiten Sie die service.exe.config des Dienstes, um den neuen Zertifikatnamen (im findValue-Attribut in <serviceCertificate>) wiederzugeben, der mit dem vollqualifizierten Domänennamen des Computers identisch ist.

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

  7. Führen Sie auf dem Client setup.bat clientaus. Wenn Sie setup.bat mit dem Argument client ausführen, wird ein Clientzertifikat mit dem Namen client.com erstellt und das Clientzertifikat in eine Datei mit dem Namen Client.cer exportiert.

  8. Ä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. Sie müssen auch den Zertifikatnamen des Diensts so ändern, dass er mit dem vollqualifizierten Domänennamen des Dienstcomputers übereinstimmt (im attribut findValue im defaultCertificate-Element von serviceCertificate unter clientCredentials).

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

  10. Führen Sie auf dem Client ImportServiceCert.bataus. Dadurch wird das Dienstzertifikat aus der Service.cer-Datei in den Speicher CurrentUser - TrustedPeople importiert.

  11. Führen Sie auf dem Server ImportClientCert.bataus. Dadurch wird das Clientzertifikat aus der Client.cer-Datei in den LocalMachine - TrustedPeople-Speicher importiert.

  12. Starten Sie auf dem Dienstcomputer Service.exe an einer Eingabeaufforderung.

  13. Starten Sie auf dem Clientcomputer Client.exe an einer Eingabeaufforderung. Wenn Client und Dienst nicht kommunizieren können, finden Sie weitere Informationen unter Tipps zur Problembehandlung 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 über mehrere Computer hinweg verwenden, müssen Sie unbedingt 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.

Anforderungen

Dieses Beispiel erfordert, dass MSMQ installiert und ausgeführt wird.

Veranschaulichung

Der Client verschlüsselt die Nachricht mithilfe des öffentlichen Schlüssels des Diensts und signiert die Nachricht mithilfe eines eigenen Zertifikats. Der Dienst, der die Nachricht aus der Warteschlange liest, authentifiziert das Clientzertifikat mit dem Zertifikat in seinem Speicher für vertrauenswürdige Personen. Anschließend entschlüsselt er die Nachricht und leitet sie an den Dienstvorgang weiter.

Da die WCF-Nachricht als Nutzlast im Text der MSMQ-Nachricht enthalten ist, bleibt der Text im MSMQ-Speicher verschlüsselt. Dadurch wird die Nachricht vor unerwünschter Offenlegung der Nachricht geschützt. Beachten Sie, dass MSMQ selbst nicht weiß, ob die nachricht, die sie trägt, verschlüsselt ist.

Das Beispiel zeigt, wie die gegenseitige Authentifizierung auf Nachrichtenebene mit MSMQ verwendet werden kann. Die Zertifikate werden "Out-of-Band" ausgetauscht. Dies ist immer der Fall bei der in die Warteschlange gestellten Anwendung, da der Dienst und der Client nicht gleichzeitig ausgeführt werden müssen.

Beschreibung

Der Beispielclient- und Dienstcode sind bis auf einen Unterschied mit dem Code aus dem Beispiel Abgewickelte MSMQ-Bindung identisch. Der Vertrag für den Vorgang ist mit dem Schutzniveau versehen, was darauf hinweist, dass die Nachricht signiert und verschlüsselt werden muss.

// Define a service contract.
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface IOrderProcessor
{
    [OperationContract(IsOneWay = true, ProtectionLevel=ProtectionLevel.EncryptAndSign)]
    void SubmitPurchaseOrder(PurchaseOrder po);
}

Um sicherzustellen, dass die Nachricht mit dem erforderlichen Token gesichert ist, um den Dienst und den Client zu identifizieren, enthält die App.config Anmeldeinformationen.

Die Clientkonfiguration gibt das Dienstzertifikat an, um den Dienst zu authentifizieren. Er verwendet seinen LocalMachine-Speicher als vertrauenswürdigen Speicher, um auf die Gültigkeit des Diensts zu vertrauen. Außerdem wird das Clientzertifikat angegeben, das mit der Nachricht für die Dienstauthentifizierung des Clients verbunden ist.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <system.serviceModel>

    <client>
      <!-- Define NetMsmqEndpoint -->
      <endpoint address="net.msmq://localhost/private/ServiceModelSamplesMessageSecurity"
                binding="netMsmqBinding"
                bindingConfiguration="messageSecurityBinding"
                contract="Microsoft.ServiceModel.Samples.IOrderProcessor"
                behaviorConfiguration="ClientCertificateBehavior" />
    </client>

    <bindings>
        <netMsmqBinding>
            <binding name="messageSecurityBinding">
                <security mode="Message">
                    <message clientCredentialType="Certificate"/>
                </security>
            </binding>
        </netMsmqBinding>
    </bindings>

    <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>
                <defaultCertificate findValue="localhost" storeLocation="CurrentUser" storeName="TrustedPeople" x509FindType="FindBySubjectName"/>
              <!--
            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>
</configuration>

Beachten Sie, dass der Sicherheitsmodus auf "Message" festgelegt ist und der ClientCredentialType auf "Certificate" festgelegt ist.

Die Dienstkonfiguration enthält ein Dienstverhalten, das die Anmeldeinformationen des Diensts angibt, die verwendet werden, wenn der Client den Dienst authentifiziert. Der Subjektname des Serverzertifikats wird im Attribut findValue im <serviceCredentials>angegeben.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <appSettings>
    <!-- Use appSetting to configure MSMQ queue name. -->
    <add key="queueName" value=".\private$\ServiceModelSamplesMessageSecurity" />
  </appSettings>

  <system.serviceModel>
    <services>
      <service
          name="Microsoft.ServiceModel.Samples.OrderProcessorService"
          behaviorConfiguration="PurchaseOrderServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8000/ServiceModelSamples/service"/>
          </baseAddresses>
        </host>
        <!-- Define NetMsmqEndpoint -->
        <endpoint address="net.msmq://localhost/private/ServiceModelSamplesMessageSecurity"
                  binding="netMsmqBinding"
                  bindingConfiguration="messageSecurityBinding"
                  contract="Microsoft.ServiceModel.Samples.IOrderProcessor" />
        <!-- The mex endpoint is exposed at http://localhost:8000/ServiceModelSamples/service/mex. -->
        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange" />
      </service>
    </services>

    <bindings>
        <netMsmqBinding>
            <binding name="messageSecurityBinding">
                <security mode="Message">
                    <message clientCredentialType="Certificate" />
                </security>
            </binding>
        </netMsmqBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors>
        <behavior name="PurchaseOrderServiceBehavior">
          <serviceMetadata httpGetEnabled="True"/>
          <!--
               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>
                <certificate findValue="client.com" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName"/>
              <!--
            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" />
            </clientCertificate>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>

  </system.serviceModel>

</configuration>

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

// Service class which implements the service contract.
// Added code to write output to the console window.
public class OrderProcessorService : IOrderProcessor
{
    private 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;
    }

    [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
    public void SubmitPurchaseOrder(PurchaseOrder po)
    {
        Console.WriteLine("Client's Identity {0} ", GetCallerIdentity());
        Orders.Add(po);
        Console.WriteLine("Processing {0} ", po);
    }
  //…
}

Beim Ausführen zeigt der Dienstcode die Clientidentifikation an. Es folgt eine Beispielausgabe aus dem Dienstcode:

The service is ready.
Press <ENTER> to terminate service.

Client's Identity CN=client.com; ECA6629A3C695D01832D77EEE836E04891DE9D3C
Processing Purchase Order: 6536e097-da96-4773-9da3-77bab4345b5d
        Customer: somecustomer.com
        OrderDetails
                Order LineItem: 54 of Blue Widget @unit price: $29.99
                Order LineItem: 890 of Red Widget @unit price: $45.89
        Total cost of this order: $42461.56
        Order status: Pending

Kommentare

  • Erstellen des Clientzertifikats.

    Die folgende Zeile in der Batchdatei erstellt das Clientzertifikat. Der angegebene Clientname wird im Betreffnamen 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, sodass der Server die relevanten Vertrauens- oder Misstrauensentscheidungen 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 PeerTrust Wert festgelegt werden. Sehen Sie sich das vorherige Beispiel für die Dienstkonfiguration an, um zu erfahren, 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 Setupbatchdatei mit einem Dienstargument (z. B. setup.bat service) ausgeführt wird, enthält die %SERVER_NAME% den vollqualifizierten Domänennamen des Computers. Andernfalls wird "localhost" standardmäßig verwendet.

  • Installieren des Serverzertifikats im Clientspeicher für vertrauenswürdige Zertifikate:

    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
    

    Anmerkung

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