Niezawodny dostawca wystawionych tokenów
Przykład DurableIssuedTokenProvider pokazuje, jak zaimplementować niestandardowego dostawcę tokenu wystawionego przez klienta.
Dyskusja
Dostawca tokenów w programie Windows Communication Foundation (WCF) służy do dostarczania poświadczeń do infrastruktury zabezpieczeń. Dostawca tokenu ogólnie sprawdza cel i wystawia odpowiednie poświadczenia, aby infrastruktura zabezpieczeń mogła zabezpieczyć komunikat. Program WCF jest dostarczany z dostawcą tokenów CardSpace. Niestandardowi dostawcy tokenów są przydatni w następujących przypadkach:
Jeśli masz magazyn poświadczeń, z którym nie może działać wbudowany dostawca tokenów.
Jeśli chcesz podać własny mechanizm niestandardowy do przekształcania poświadczeń z punktu, gdy użytkownik podaje szczegóły, kiedy klient programu WCF używa poświadczeń.
Jeśli tworzysz token niestandardowy.
W tym przykładzie pokazano, jak utworzyć niestandardowego dostawcę tokenów, który buforuje tokeny wystawione przez usługę tokenu zabezpieczającego (STS).
Podsumowując, w tym przykładzie przedstawiono następujące kwestie:
Jak można skonfigurować klienta za pomocą niestandardowego dostawcy tokenów.
Jak wystawione tokeny można buforować i dostarczać do klienta programu WCF.
Sposób uwierzytelniania serwera przez klienta przy użyciu certyfikatu X.509 serwera.
Ten przykład składa się z programu konsolowego klienta (Client.exe), programu konsoli usługi tokenu zabezpieczającego (Securitytokenservice.exe) i programu konsoli usługi (Service.exe). Usługa implementuje kontrakt, który definiuje wzorzec komunikacji typu żądanie-odpowiedź. Kontrakt jest definiowany przez ICalculator
interfejs, który uwidacznia operacje matematyczne (dodawanie, odejmowanie, mnożenie i dzielenie). Klient pobiera token zabezpieczający z usługi tokenu zabezpieczającego (STS) i wykonuje synchroniczne żądania do usługi dla danej operacji matematycznej, a usługa odpowiada z wynikiem. Działanie klienta jest widoczne w oknie konsoli.
Uwaga
Procedura konfiguracji i instrukcje kompilacji dla tego przykładu znajdują się na końcu tego tematu.
Ten przykład uwidacznia kontrakt ICalculator przy użyciu elementu wsHttpBinding>.< Konfiguracja tego powiązania na kliencie jest wyświetlana w poniższym kodzie.
<bindings>
<wsFederationHttpBinding>
<binding name="ServiceFed">
<security mode="Message">
<message issuedKeyType="SymmetricKey"
issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1">
<issuer address="http://localhost:8000/sts/windows"
binding="wsHttpBinding" />
</message>
</security>
</binding>
</wsFederationHttpBinding>
</bindings>
W elemekcie security
wsFederationHttpBinding
mode
wartość konfiguruje, który tryb zabezpieczeń ma być używany. W tym przykładzie używane są zabezpieczenia komunikatów, dlatego message
element elementu wsFederationHttpBinding
jest określony wewnątrz security
elementu .wsFederationHttpBinding
Element issuer
wsFederationHttpBinding
wewnątrz message
elementu wsFederationHttpBinding
elementu określa adres i powiązanie dla usługi tokenu zabezpieczającego, który wystawia token zabezpieczający klientowi, aby klient mógł uwierzytelnić się w usłudze Kalkulator.
Konfiguracja tego powiązania w usłudze jest wyświetlana w poniższym kodzie.
<bindings>
<wsFederationHttpBinding>
<binding name="ServiceFed">
<security mode="Message">
<message issuedKeyType="SymmetricKey"
issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1">
<issuerMetadata address="http://localhost:8000/sts/mex">
<identity>
<certificateReference storeLocation="CurrentUser"
storeName="TrustedPeople"
x509FindType="FindBySubjectDistinguishedName"
findValue="CN=STS" />
</identity>
</issuerMetadata>
</message>
</security>
</binding>
</wsFederationHttpBinding>
</bindings>
W elemekcie security
wsFederationHttpBinding
mode
wartość konfiguruje, który tryb zabezpieczeń ma być używany. W tym przykładzie używane są zabezpieczenia komunikatów, dlatego message
element elementu wsFederationHttpBinding
jest określony wewnątrz security
elementu .wsFederationHttpBinding
Element issuerMetadata
wsFederationHttpBinding
wewnątrz message
elementu elementu wsFederationHttpBinding
określa adres i tożsamość punktu końcowego, który może służyć do pobierania metadanych dla usługi tokenu zabezpieczającego.
Zachowanie usługi jest wyświetlane w poniższym kodzie.
<behavior name="ServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="true" />
<serviceCredentials>
<issuedTokenAuthentication>
<knownCertificates>
<add storeLocation="LocalMachine"
storeName="TrustedPeople"
x509FindType="FindBySubjectDistinguishedName"
findValue="CN=STS" />
</knownCertificates>
</issuedTokenAuthentication>
<serviceCertificate storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectDistinguishedName"
findValue="CN=localhost" />
</serviceCredentials>
</behavior>
Element issuedTokenAuthentication
wewnątrz serviceCredentials
elementu umożliwia usłudze określanie ograniczeń dotyczących tokenów, które umożliwiają klientom prezentowanie podczas uwierzytelniania. Ta konfiguracja określa, że tokeny podpisane przez certyfikat, którego nazwa podmiotu jest CN=STS są akceptowane przez usługę.
Usługa tokenu zabezpieczającego uwidacznia pojedynczy punkt końcowy przy użyciu standardowego rozwiązania wsHttpBinding. Usługa tokenu zabezpieczającego odpowiada na żądanie od klientów dla tokenów i pod warunkiem, że klient uwierzytelnia się przy użyciu konta systemu Windows, wystawia token zawierający nazwę użytkownika klienta jako oświadczenie w wystawionym tokenie. W ramach tworzenia tokenu usługa tokenu zabezpieczającego podpisuje token przy użyciu klucza prywatnego skojarzonego z certyfikatem CN=STS. Ponadto tworzy klucz symetryczny i szyfruje go przy użyciu klucza publicznego skojarzonego z certyfikatem CN=localhost. W przypadku zwracania tokenu do klienta usługa tokenu zabezpieczającego zwraca również klucz symetryczny. Klient przedstawia wystawiony token do usługi Kalkulator i potwierdza, że zna klucz symetryczny, podpisując komunikat za pomocą tego klucza.
Niestandardowe poświadczenia klienta i dostawca tokenów
W poniższych krokach pokazano, jak utworzyć niestandardowego dostawcę tokenów, który buforuje wystawione tokeny i integruje go z usługą WCF: zabezpieczenia.
Aby opracować niestandardowego dostawcę tokenów
Napisz niestandardowego dostawcę tokenów.
Przykład implementuje niestandardowego dostawcę tokenów, który zwraca token zabezpieczający pobrany z pamięci podręcznej.
Aby wykonać to zadanie, niestandardowy dostawca tokenu uzyskuje klasę SecurityTokenProvider i zastępuje metodę GetTokenCore . Ta metoda próbuje uzyskać token z pamięci podręcznej lub jeśli nie można odnaleźć tokenu w pamięci podręcznej, pobiera token od dostawcy bazowego, a następnie buforuje ten token. W obu przypadkach metoda zwraca
SecurityToken
wartość .protected override SecurityToken GetTokenCore(TimeSpan timeout) { GenericXmlSecurityToken token; if (!this.cache.TryGetToken(target, issuer, out token)) { token = (GenericXmlSecurityToken) this.innerTokenProvider.GetToken(timeout); this.cache.AddToken(token, target, issuer); } return token; }
Pisanie niestandardowego menedżera tokenów zabezpieczających.
Element SecurityTokenManager służy do tworzenia SecurityTokenProvider elementu dla określonego SecurityTokenRequirement elementu, który jest przekazywany do niego w metodzie
CreateSecurityTokenProvider
. Menedżer tokenów zabezpieczających służy również do tworzenia wystawców uwierzytelnień tokenów i serializatorów tokenów, ale nie są one objęte tym przykładem. W tym przykładzie niestandardowy menedżer tokenów zabezpieczających dziedziczy z ClientCredentialsSecurityTokenManager klasy i zastępujeCreateSecurityTokenProvider
metodę, aby zwrócić niestandardowego dostawcę tokenu, gdy przekazane wymagania tokenu wskazują, że zażądano wystawionego tokenu.class DurableIssuedTokenClientCredentialsTokenManager : ClientCredentialsSecurityTokenManager { IssuedTokenCache cache; public DurableIssuedTokenClientCredentialsTokenManager ( DurableIssuedTokenClientCredentials creds ): base(creds) { this.cache = creds.IssuedTokenCache; } public override SecurityTokenProvider CreateSecurityTokenProvider ( SecurityTokenRequirement tokenRequirement ) { if (IsIssuedSecurityTokenRequirement(tokenRequirement)) { return new DurableIssuedSecurityTokenProvider ((IssuedSecurityTokenProvider)base.CreateSecurityTokenProvider( tokenRequirement), this.cache); } else { return base.CreateSecurityTokenProvider(tokenRequirement); } } }
Napisz niestandardowe poświadczenia klienta.
Klasa poświadczeń klienta służy do reprezentowania poświadczeń skonfigurowanych dla serwera proxy klienta i tworzy menedżera tokenów zabezpieczających używany do uzyskiwania wystawców uwierzytelnień tokenów, dostawców tokenów i serializatorów tokenów.
public class DurableIssuedTokenClientCredentials : ClientCredentials { IssuedTokenCache cache; public DurableIssuedTokenClientCredentials() : base() { } DurableIssuedTokenClientCredentials ( DurableIssuedTokenClientCredentials other) : base(other) { this.cache = other.cache; } public IssuedTokenCache IssuedTokenCache { get { return this.cache; } set { this.cache = value; } } protected override ClientCredentials CloneCore() { return new DurableIssuedTokenClientCredentials(this); } public override SecurityTokenManager CreateSecurityTokenManager() { return new DurableIssuedTokenClientCredentialsTokenManager ((DurableIssuedTokenClientCredentials)this.Clone()); } }
Zaimplementuj pamięć podręczną tokenu. Przykładowa implementacja używa abstrakcyjnej klasy bazowej, za pomocą której konsumenci danej pamięci podręcznej tokenu wchodzą w interakcję z pamięcią podręczną.
public abstract class IssuedTokenCache { public abstract void AddToken ( GenericXmlSecurityToken token, EndpointAddress target, EndpointAddress issuer); public abstract bool TryGetToken(EndpointAddress target, EndpointAddress issuer, out GenericXmlSecurityToken cachedToken); } // Configure the client to use the custom client credential.
Aby klient używał niestandardowych poświadczeń klienta, przykład usuwa domyślną klasę poświadczeń klienta i dostarcza nową klasę poświadczeń klienta.
clientFactory.Endpoint.Behaviors.Remove<ClientCredentials>(); DurableIssuedTokenClientCredentials durableCreds = new DurableIssuedTokenClientCredentials(); durableCreds.IssuedTokenCache = cache; durableCreds.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.PeerOrChainTrust; clientFactory.Endpoint.Behaviors.Add(durableCreds);
Uruchamianie przykładowej aplikacji
Zapoznaj się z poniższymi instrukcjami, aby uruchomić przykład. Po uruchomieniu przykładu żądanie tokenu zabezpieczającego jest wyświetlane w oknie konsoli usługi tokenu zabezpieczającego. Żądania operacji i odpowiedzi są wyświetlane w oknach konsoli klienta i usługi. Naciśnij klawisz ENTER w dowolnym z okien konsoli, aby zamknąć aplikację.
Plik wsadowy Setup.cmd
Plik wsadowy Setup.cmd dołączony do tego przykładu umożliwia skonfigurowanie serwera i usługi tokenu zabezpieczającego przy użyciu odpowiednich certyfikatów w celu uruchomienia aplikacji hostowanej samodzielnie. Plik wsadowy tworzy dwa certyfikaty w magazynie certyfikatów CurrentUser/Trusted Osoby. Pierwszy certyfikat ma nazwę podmiotu CN=STS i jest używany przez usługę tokenu zabezpieczającego do podpisywania tokenów zabezpieczających, które wystawia klientowi. Drugi certyfikat ma nazwę podmiotu CN=localhost i jest używany przez usługę tokenu zabezpieczającego do szyfrowania wpisu tajnego, aby usługa mogła ją odszyfrować.
Aby skonfigurować, skompilować i uruchomić przykład
Uruchom plik Setup.cmd, aby utworzyć wymagane certyfikaty.
Aby skompilować rozwiązanie, postępuj zgodnie z instrukcjami w temacie Building the Windows Communication Foundation Samples (Tworzenie przykładów programu Windows Communication Foundation). Upewnij się, że wszystkie projekty w rozwiązaniu zostały skompilowane (Udostępnione, RSTRSTR, Usługa, SecurityTokenService i Klient).
Upewnij się, że Service.exe i SecurityTokenService.exe są uruchomione z uprawnieniami administratora.
Uruchom Client.exe.
Aby wyczyścić po próbce
Uruchom Cleanup.cmd w folderze samples po zakończeniu uruchamiania przykładu.