Zabezpieczenia komunikatów za pośrednictwem kolejkowania komunikatów
Przykładowy MessageSecurity pokazuje, jak zaimplementować aplikację korzystającą z WS-Security z uwierzytelnianiem certyfikatu X.509v3 dla klienta i wymaga uwierzytelniania serwera przy użyciu certyfikatu X.509v3 serwera za pośrednictwem msMQ. Bezpieczeństwo komunikatów jest czasami bardziej pożądane, aby upewnić się, że komunikaty w magazynie MSMQ pozostają zaszyfrowane, a aplikacja może wykonywać własne uwierzytelnianie komunikatu.
Ten przykład opiera się na przykładzie transakcyjnego wiązania MSMQ. Komunikaty są szyfrowane i podpisane.
Aby skonfigurować, skompilować i uruchomić próbkę
Upewnij się, że wykonano procedurę instalacji One-Time dla przykładów programu Windows Communication Foundation.
Jeśli usługa jest uruchomiona jako pierwsza, sprawdzi, czy kolejka jest obecna. Jeśli kolejka nie jest obecna, usługa utworzy je. Możesz najpierw uruchomić usługę, aby utworzyć kolejkę, lub utworzyć jedną za pośrednictwem menedżera kolejki MSMQ. Wykonaj następujące kroki, aby utworzyć kolejkę w systemie Windows 2008.
Otwórz Menedżera serwera w programie Visual Studio 2012.
Rozwiń kartę Funkcje .
Kliknij prawym przyciskiem myszy Prywatne Kolejki Wiadomościi wybierz Nowa, Prywatna Kolejka.
Zaznacz pole Transakcyjne.
Wprowadź
ServiceModelSamplesTransacted
jako nazwę nowej kolejki.
Aby utworzyć wersję języka C# lub Visual Basic rozwiązania, postępuj zgodnie z instrukcjami w Building the Windows Communication Foundation Samples.
Aby uruchomić przykład na tym samym komputerze
Upewnij się, że ścieżka zawiera folder zawierający Makecert.exe i FindPrivateKey.exe.
Uruchom Setup.bat z folderu instalacji przykładowej. To instaluje wszystkie certyfikaty wymagane do uruchomienia próbki.
Notatka
Upewnij się, że certyfikaty zostały usunięte, uruchamiając Cleanup.bat po zakończeniu pracy z próbką. Inne przykłady zabezpieczeń używają tych samych certyfikatów.
Uruchom Service.exe z \service\bin.
Uruchom Client.exe z \client\bin. Działanie klienta jest wyświetlane w aplikacji konsolowej klienta.
Jeśli klient i usługa nie mogą się komunikować, zobacz Wskazówki dotyczące rozwiązywania problemów z przykładów WCF.
Aby uruchomić przykład na różnych komputerach
Skopiuj pliki Setup.bat, Cleanup.bati ImportClientCert.bat na komputer usługi.
Utwórz katalog na komputerze klienckim dla plików binarnych klienta.
Skopiuj pliki programu klienckiego do katalogu klienta na komputerze klienckim. Skopiuj również pliki Setup.bat, Cleanup.bati ImportServiceCert.bat do klienta.
Na serwerze uruchom polecenie
setup.bat service
. Uruchomieniesetup.bat
z argumentemservice
tworzy certyfikat usługi z w pełni kwalifikowaną nazwą domeny komputera i eksportuje certyfikat usługi do pliku o nazwie Service.cer.Edytuj service.exe.config usługi, aby odzwierciedlić nową nazwę certyfikatu (w atrybucie
findValue
w <serviceCertificate>), która jest taka sama jak w pełni kwalifikowana nazwa domeny komputera.Skopiuj plik Service.cer z katalogu usługi do katalogu klienta na komputerze klienckim.
Na kliencie uruchom
setup.bat client
. Uruchomieniesetup.bat
z argumentemclient
tworzy certyfikat klienta o nazwie client.com i eksportuje certyfikat klienta do pliku o nazwie Client.cer.W pliku Client.exe.config na komputerze klienckim zmień wartość adresu punktu końcowego, aby odpowiadała nowemu adresowi usługi. W tym celu należy zastąpić hosta lokalnego w pełni kwalifikowaną nazwą domeny serwera. Należy również zmienić nazwę certyfikatu usługi na taką samą jak w pełni kwalifikowaną nazwę domeny komputera usługi (w atrybucie
findValue
w elemenciedefaultCertificate
serviceCertificate
pod obszaremclientCredentials
).Skopiuj plik Client.cer z katalogu klienta do katalogu usługi na serwerze.
Na kliencie uruchom polecenie
ImportServiceCert.bat
. Spowoduje to zaimportowanie certyfikatu usługi z pliku Service.cer do magazynu CurrentUser — TrustedPeople.Na serwerze uruchom polecenie
ImportClientCert.bat
. Spowoduje to zaimportowanie certyfikatu klienta z pliku Client.cer do magazynu LocalMachine — TrustedPeople.Na komputerze obsługowym uruchom Service.exe z wiersza polecenia.
Na komputerze klienckim uruchom Client.exe z wiersza polecenia. Jeśli klient i usługa nie mogą się komunikować, zobacz Wskazówki dotyczące rozwiązywania problemów z przykładami WCF.
Aby wyczyścić po próbce
Uruchom Cleanup.bat w folderze próbek po zakończeniu uruchamiania próbki.
Notatka
Ten skrypt nie usuwa certyfikatów usługi na kliencie podczas uruchamiania tego przykładu na komputerach. Jeśli uruchomiłeś przykłady programu Windows Communication Foundation (WCF), które korzystają z certyfikatów na różnych komputerach, pamiętaj, aby wyczyścić certyfikaty usługi, które zostały zainstalowane w magazynie CurrentUser – TrustedPeople. W tym celu użyj następującego polecenia:
certmgr -del -r CurrentUser -s TrustedPeople -c -n <Fully Qualified Server Machine Name>
Na przykład:certmgr -del -r CurrentUser -s TrustedPeople -c -n server1.contoso.com
.
Wymagania
Ten przykład wymaga zainstalowania i uruchomienia narzędzia MSMQ.
Pokazuje
Klient szyfruje komunikat przy użyciu klucza publicznego usługi i podpisuje komunikat przy użyciu własnego certyfikatu. Usługa odczytując komunikat z kolejki uwierzytelnia certyfikat klienta przy użyciu certyfikatu w magazynie zaufanych osób. Następnie odszyfrowuje komunikat i wysyła komunikat do operacji usługi.
Ponieważ komunikat programu Windows Communication Foundation (WCF) jest przenoszony jako ładunek w treści komunikatu MSMQ, treść pozostaje zaszyfrowana w magazynie MSMQ. Spowoduje to zabezpieczenie wiadomości przed niechcianym ujawnieniem wiadomości. Należy pamiętać, że sam protokół MSMQ nie jest świadomy, czy komunikat, który nosi, jest zaszyfrowany.
W przykładzie pokazano, jak wzajemne uwierzytelnianie na poziomie komunikatu może być używane z usługą MSMQ. Certyfikaty są wymieniane poza pasmem. Tak właśnie jest w przypadku aplikacji przetwarzanych w kolejce, ponieważ usługa i klient nie muszą działać jednocześnie.
Opis
Przykładowy kod klienta i usługi jest taki sam jak w przykładzie wiązania transakcyjnego MSMQ, z jedną różnicą. Kontrakt operacji jest oznaczony adnotacją z poziomem ochrony, co sugeruje, że komunikat musi być podpisany i zaszyfrowany.
// Define a service contract.
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface IOrderProcessor
{
[OperationContract(IsOneWay = true, ProtectionLevel=ProtectionLevel.EncryptAndSign)]
void SubmitPurchaseOrder(PurchaseOrder po);
}
Aby upewnić się, że komunikat jest zabezpieczony przy użyciu tokenu wymaganego do zidentyfikowania usługi i klienta, App.config zawiera informacje o poświadczeniach.
Konfiguracja klienta określa certyfikat usługi do uwierzytelniania usługi. Używa swojego magazynu LocalMachine jako zaufanego magazynu, aby potwierdzić ważność usługi. Określa również certyfikat klienta dołączony do komunikatu na potrzeby uwierzytelniania usługi klienta.
<?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>
Należy pamiętać, że tryb zabezpieczeń jest ustawiony na Wartość Komunikat, a właściwość ClientCredentialType jest ustawiona na Wartość Certyfikat.
Konfiguracja usługi obejmuje zachowanie usługi, które określa poświadczenia usługi, które są używane podczas uwierzytelniania usługi przez klienta. Nazwa podmiotu certyfikatu serwera jest określona w atrybucie findValue
w <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>
W przykładzie pokazano kontrolowanie uwierzytelniania przy użyciu konfiguracji oraz sposób uzyskiwania tożsamości obiektu wywołującego z kontekstu zabezpieczeń, jak pokazano w poniższym przykładowym kodzie:
// 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);
}
//…
}
Po uruchomieniu kod usługi wyświetla identyfikację klienta. Poniżej przedstawiono przykładowe dane wyjściowe z kodu usługi:
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
Komentarze
Tworzenie certyfikatu klienta.
Poniższy wiersz w pliku wsadowym tworzy certyfikat klienta. Określona nazwa klienta jest używana w nazwie przedmiotu utworzonego certyfikatu. Certyfikat jest przechowywany w magazynie
My
w lokalizacji magazynuCurrentUser
.echo ************ echo making client cert echo ************ makecert.exe -sr CurrentUser -ss MY -a sha1 -n CN=%CLIENT_NAME% -sky exchange -pe
Instalowanie certyfikatu klienta w magazynie zaufanych certyfikatów serwera.
Poniższy wiersz w pliku wsadowym kopiuje certyfikat klienta do magazynu TrustedPeople serwera, aby serwer mógł podejmować odpowiednie decyzje dotyczące zaufania lub braku zaufania. Aby certyfikat zainstalowany w magazynie TrustedPeople był zaufany przez usługę Windows Communication Foundation (WCF), należy ustawić tryb weryfikacji certyfikatu klienta na wartość
PeerOrChainTrust
lubPeerTrust
. Zapoznaj się z poprzednim przykładem konfiguracji usługi, aby dowiedzieć się, jak można to zrobić przy użyciu pliku konfiguracji.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
Tworzenie certyfikatu serwera.
Następujące wiersze z pliku wsadowego Setup.bat tworzą certyfikat serwera do użycia:
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
Zmienna %SERVER_NAME% określa nazwę serwera. Certyfikat jest przechowywany w magazynie LocalMachine. Jeśli plik wsadowy instalatora jest uruchamiany z argumentem usługi (na przykład
setup.bat service
), %SERVER_NAME% zawiera w pełni kwalifikowaną nazwę domeny komputera. W przeciwnym razie wartość domyślna to localhost.Instalowanie certyfikatu serwera w magazynie zaufanych certyfikatów klienta.
Poniższy wiersz kopiuje certyfikat serwera do magazynu zaufanych osób klienta. Ten krok jest wymagany, ponieważ certyfikaty generowane przez Makecert.exe nie są automatycznie uznawane za zaufane przez system klienta. Jeśli masz już certyfikat, który jest zakorzeniony w zaufanym certyfikacie głównym klienta — na przykład certyfikat wystawiony przez firmę Microsoft — ten krok wypełniania magazynu certyfikatów klienta przy użyciu certyfikatu serwera nie jest wymagany.
certmgr.exe -add -r LocalMachine -s My -c -n %SERVER_NAME% -r CurrentUser -s TrustedPeople
Notatka
Jeśli używasz wersji językowej systemu Microsoft Windows innej niż U.S. English, musisz edytować plik Setup.bat i zastąpić nazwę konta "NT AUTHORITY\NETWORK SERVICE" odpowiednikiem regionalnym.