Zabezpieczenia komunikatów w ramach kolejkowania komunikatów
W przykładzie MessageSecurity pokazano, jak zaimplementować aplikację korzystającą z usługi 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 jest oparty na przykładzie powiązania transacted MSMQ . Komunikaty są szyfrowane i podpisane.
Aby skonfigurować, skompilować i uruchomić przykład
Upewnij się, że wykonano procedurę instalacji jednorazowej 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żer serwera w programie Visual Studio 2012.
Rozwiń kartę Funkcje .
Kliknij prawym przyciskiem myszy pozycję Kolejki komunikatów prywatnych, a następnie wybierz pozycję Nowa, Prywatna kolejka.
Zaznacz pole Transakcyjne.
Wprowadź
ServiceModelSamplesTransacted
jako nazwę nowej kolejki.
Aby skompilować wersję rozwiązania w języku C# lub Visual Basic .NET, postępuj zgodnie z instrukcjami w temacie Building the Windows Communication Foundation Samples (Tworzenie przykładów programu Windows Communication Foundation).
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. Spowoduje to zainstalowanie wszystkich certyfikatów wymaganych do uruchomienia przykładu.
Uwaga
Upewnij się, że certyfikaty zostały usunięte, uruchamiając Cleanup.bat po zakończeniu pracy z przykładem. 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 Rozwiązywanie problemów Wskazówki dla przykładów programu WCF.
Aby uruchomić przykład na komputerach
Skopiuj pliki Setup.bat, Cleanup.bat i 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.bat i ImportServiceCert.bat do klienta.
Na serwerze uruchom polecenie
setup.bat service
. Uruchomieniesetup.bat
z argumentemservice
powoduje utworzenie certyfikatu usługi z w pełni kwalifikowaną nazwą domeny komputera i eksportuje certyfikat usługi do pliku o nazwie Service.cer.Edytuj plik service.exe.config usługi, aby odzwierciedlić nową nazwę certyfikatu (w atrybucie
findValue
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 polecenie
setup.bat client
. Uruchomieniesetup.bat
z argumentemclient
powoduje utworzenie certyfikatu klienta o nazwie client.com i wyeksportowanie certyfikatu klienta do pliku o nazwie Client.cer.W pliku Client.exe.config na komputerze klienckim zmień wartość adresu punktu końcowego, aby był zgodny z nowym adresem 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 kwalifikowana nazwa domeny komputera usługi (w atrybucie
findValue
wdefaultCertificate
elemencieserviceCertificate
w obszarzeclientCredentials
).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 — Trusted Osoby.Na serwerze uruchom polecenie
ImportClientCert.bat
, spowoduje to zaimportowanie certyfikatu klienta z pliku Client.cer do magazynu LocalMachine — Trusted Osoby.Na komputerze usługi 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 Rozwiązywanie problemów Wskazówki dla przykładów programu WCF.
Aby wyczyścić po próbce
Uruchom Cleanup.bat w folderze samples po zakończeniu uruchamiania przykładu.
Uwaga
Ten skrypt nie usuwa certyfikatów usługi na kliencie podczas uruchamiania tego przykładu na komputerach. Jeśli uruchomiono przykłady programu Windows Communication Foundation (WCF) korzystające z certyfikatów na komputerach, pamiętaj, aby wyczyścić certyfikaty usługi zainstalowane w magazynie CurrentUser — Trusted Osoby. 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.
Demonstracje
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. Jest to zawsze przypadek aplikacji w kolejce, ponieważ usługa i klient nie muszą być uruchomione w tym samym czasie.
opis
Przykładowy kod klienta i usługi jest taki sam jak przykład powiązania transacted 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, plik 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 polegać na ważności 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 serviceCredentials>.findValue
<
<?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 podmiotu utworzonego certyfikatu. Certyfikat jest przechowywany w
My
magazynie wCurrentUser
lokalizacji magazynu.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 Zaufane Osoby serwera, aby serwer mógł podejmować odpowiednie decyzje zaufania lub braku zaufania. Aby certyfikat zainstalowany w magazynie Zaufany Osoby był zaufany przez usługę Windows Communication Foundation (WCF), należy ustawić tryb weryfikacji certyfikatu klienta na
PeerOrChainTrust
wartość lubPeerTrust
wartość. 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 localhostInstalowanie 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ą niejawnie zaufane przez system kliencki. 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
Uwaga
Jeśli używasz spoza USA Angielska wersja systemu Microsoft Windows musisz edytować plik Setup.bat i zastąpić nazwę konta "NT AUTHORITY\NETWORK SERVICE" odpowiednikiem regionalnym.