Dela via


Meddelandesäkerhet över Meddelandeköer

Exemplet MessageSecurity visar hur du implementerar ett program som använder WS-Security med X.509v3-certifikatautentisering för klienten och kräver serverautentisering med hjälp av serverns X.509v3-certifikat via MSMQ. Meddelandesäkerhet är ibland mer önskvärt för att säkerställa att meddelandena i MSMQ-arkivet förblir krypterade och att programmet kan utföra sin egen autentisering av meddelandet.

Det här exemplet baseras på transacted MSMQ-bindningsexemplet . Meddelandena krypteras och signeras.

Så här konfigurerar du, skapar och kör exemplet

  1. Kontrollera att du har utfört engångsinstallationsproceduren för Windows Communication Foundation-exempel.

  2. Om tjänsten körs först kontrollerar den att kön finns. Om kön inte finns skapar tjänsten en. Du kan köra tjänsten först för att skapa kön, eller så kan du skapa en via MSMQ Queue Manager. Följ de här stegen för att skapa en kö i Windows 2008.

    1. Öppna Serverhanteraren i Visual Studio 2012.

    2. Expandera fliken Funktioner .

    3. Högerklicka på Privata meddelandeköer och välj Ny privat .

    4. Markera rutan Transaktionell .

    5. Ange ServiceModelSamplesTransacted som namnet på den nya kön.

  3. Om du vill skapa C# eller Visual Basic .NET-versionen av lösningen följer du anvisningarna i Skapa Windows Communication Foundation-exempel.

Så här kör du exemplet på samma dator

  1. Kontrollera att sökvägen innehåller mappen som innehåller Makecert.exe och FindPrivateKey.exe.

  2. Kör Setup.bat från exempelinstallationsmappen. Detta installerar alla certifikat som krävs för att köra exemplet.

    Kommentar

    Se till att du tar bort certifikaten genom att köra Cleanup.bat när du är klar med exemplet. Andra säkerhetsexempel använder samma certifikat.

  3. Starta Service.exe från \service\bin.

  4. Starta Client.exe från \client\bin. Klientaktiviteten visas i klientkonsolprogrammet.

  5. Om klienten och tjänsten inte kan kommunicera kan du läsa Felsökningstips för WCF-exempel.

Så här kör du exemplet mellan datorer

  1. Kopiera filerna Setup.bat, Cleanup.bat och ImportClientCert.bat till tjänstdatorn.

  2. Skapa en katalog på klientdatorn för klient binärfilerna.

  3. Kopiera klientprogramfilerna till klientkatalogen på klientdatorn. Kopiera även filerna Setup.bat, Cleanup.bat och ImportServiceCert.bat till klienten.

  4. Kör på servern setup.bat service. När du service kör setup.bat med argumentet skapas ett tjänstcertifikat med datorns fullständigt kvalificerade domännamn och tjänstcertifikatet exporteras till en fil med namnet Service.cer.

  5. Redigera tjänstens service.exe.config för att återspegla det nya certifikatnamnet (i findValue attributet i <serviceCertificate>) som är samma som datorns fullständigt kvalificerade domännamn.

  6. Kopiera Service.cer-filen från tjänstkatalogen till klientkatalogen på klientdatorn.

  7. Kör på klienten setup.bat client. När du kör setup.bat med client argumentet skapas ett klientcertifikat med namnet client.com och klientcertifikatet exporteras till en fil med namnet Client.cer.

  8. I filen Client.exe.config på klientdatorn ändrar du slutpunktens adressvärde så att det matchar tjänstens nya adress. Gör detta genom att ersätta localhost med serverns fullständigt kvalificerade domännamn. Du måste också ändra certifikatnamnet för tjänsten så att det är samma som det fullständigt kvalificerade domännamnet för tjänstdatorn (i findValue attributet i elementet defaultCertificateserviceCertificate under clientCredentials).

  9. Kopiera Client.cer-filen från klientkatalogen till tjänstkatalogen på servern.

  10. Kör på klienten ImportServiceCert.bat. Detta importerar tjänstcertifikatet från filen Service.cer till arkivet CurrentUser – Trusted Personer.

  11. Kör på servern ImportClientCert.batoch importerar klientcertifikatet från Client.cer-filen till arkivet LocalMachine – Trusted Personer.

  12. Starta Service.exe från kommandotolken på tjänstdatorn.

  13. Starta Client.exe från kommandotolken på klientdatorn. Om klienten och tjänsten inte kan kommunicera kan du läsa Felsökningstips för WCF-exempel.

Rensa efter exemplet

  • Kör Cleanup.bat i exempelmappen när du har kört exemplet.

    Kommentar

    Det här skriptet tar inte bort tjänstcertifikat på en klient när du kör det här exemplet på flera datorer. Om du har kört WCF-exempel (Windows Communication Foundation) som använder certifikat mellan datorer måste du rensa de tjänstcertifikat som har installerats i arkivet CurrentUser – Trusted Personer. Det gör du genom att använda följande kommando: certmgr -del -r CurrentUser -s TrustedPeople -c -n <Fully Qualified Server Machine Name> Till exempel: certmgr -del -r CurrentUser -s TrustedPeople -c -n server1.contoso.com.

Behov

Det här exemplet kräver att MSMQ är installerat och körs.

Demonstrationer

Klienten krypterar meddelandet med hjälp av tjänstens offentliga nyckel och signerar meddelandet med sitt eget certifikat. Tjänsten som läser meddelandet från kön autentiserar klientcertifikatet med certifikatet i lagringen betrodda personer. Det dekrypterar sedan meddelandet och skickar meddelandet till tjänståtgärden.

Eftersom WCF-meddelandet (Windows Communication Foundation) bärs som en nyttolast i MSMQ-meddelandets brödtext förblir brödtexten krypterad i MSMQ-arkivet. Detta skyddar meddelandet från oönskat avslöjande av meddelandet. Observera att MSMQ själv inte vet om meddelandet som det bär är krypterat.

Exemplet visar hur ömsesidig autentisering på meddelandenivå kan användas med MSMQ. Certifikaten utbyts out-of-band. Detta är alltid fallet med köat program eftersom tjänsten och klienten inte behöver vara igång samtidigt.

beskrivning

Exempelklienten och tjänstkoden är samma som transacted MSMQ-bindningsexemplet med en skillnad. Åtgärdskontraktet kommenteras med skyddsnivå, vilket tyder på att meddelandet måste signeras och krypteras.

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

För att säkerställa att meddelandet skyddas med hjälp av den token som krävs för att identifiera tjänsten och klienten innehåller App.config information om autentiseringsuppgifter.

Klientkonfigurationen anger tjänstcertifikatet för att autentisera tjänsten. Den använder sitt LocalMachine-arkiv som det betrodda arkivet för att förlita sig på tjänstens giltighet. Den anger också det klientcertifikat som är kopplat till meddelandet för tjänstautentisering av klienten.

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

Observera att säkerhetsläget är inställt på Meddelande och att ClientCredentialType är inställt på Certifikat.

Tjänstkonfigurationen innehåller ett tjänstbeteende som anger tjänstens autentiseringsuppgifter som används när klienten autentiserar tjänsten. Servercertifikatets ämnesnamn anges i findValue attributet i <serviceCredentials>.

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

Exemplet visar hur du styr autentiseringen med hjälp av konfigurationen och hur du hämtar anroparens identitet från säkerhetskontexten, enligt följande exempelkod:

// 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);
    }
  //…
}

Vid körning visar tjänstkoden klientidentifieringen. Följande är ett exempel på utdata från tjänstkoden:

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

Kommentarer

  • Skapa klientcertifikatet.

    Följande rad i batchfilen skapar klientcertifikatet. Det angivna klientnamnet används i certifikatets ämnesnamn som skapats. Certifikatet lagras i My arkivet CurrentUser på lagringsplatsen.

    echo ************
    echo making client cert
    echo ************
    makecert.exe -sr CurrentUser -ss MY -a sha1 -n CN=%CLIENT_NAME% -sky exchange -pe
    
  • Installera klientcertifikatet i serverns betrodda certifikatarkiv.

    Följande rad i batchfilen kopierar klientcertifikatet till serverns betrodda Personer arkiv så att servern kan fatta relevanta förtroende- eller förtroendebeslut. För att ett certifikat som är installerat i det betrodda Personer arkivet ska vara betrott av en WCF-tjänst (Windows Communication Foundation) måste valideringsläget för klientcertifikatet vara inställt på PeerOrChainTrust eller PeerTrust värdet. Se det tidigare tjänstkonfigurationsexemplet för att lära dig hur detta kan göras med hjälp av en konfigurationsfil.

    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
    
  • Skapa servercertifikatet.

    Följande rader från Setup.bat batchfil skapar det servercertifikat som ska användas:

    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
    

    Variabeln %SERVER_NAME% anger servernamnet. Certifikatet lagras i LocalMachine-arkivet. Om batchfilen för installation körs med ett tjänstargument (till exempel setup.bat service) innehåller %SERVER_NAME% datorns fullständigt kvalificerade domännamn. Annars är den som standard localhost

  • Installera servercertifikatet i klientens betrodda certifikatarkiv.

    Följande rad kopierar servercertifikatet till det betrodda klientarkivet. Det här steget krävs eftersom certifikat som genereras av Makecert.exe inte är implicit betrodda av klientsystemet. Om du redan har ett certifikat som är rotat i ett klientbetrott rotcertifikat, till exempel ett Microsoft-utfärdat certifikat, krävs inte det här steget för att fylla i klientcertifikatarkivet med servercertifikatet.

    certmgr.exe -add -r LocalMachine -s My -c -n %SERVER_NAME% -r CurrentUser -s TrustedPeople
    

    Kommentar

    Om du använder en icke-AMERIKANSK Den engelska versionen av Microsoft Windows måste du redigera Setup.bat-filen och ersätta kontonamnet "NT AUTHORITY\NETWORK SERVICE" med din regionala motsvarighet.