ClientCredentialsSecurityTokenManager.cs 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel
  5. {
  6. using System.Collections.Generic;
  7. using System.IdentityModel.Selectors;
  8. using System.IdentityModel.Tokens;
  9. using System.Net;
  10. using System.Security.Authentication.ExtendedProtection;
  11. using System.Security.Cryptography.X509Certificates;
  12. using System.ServiceModel.Channels;
  13. using System.ServiceModel.Description;
  14. using System.ServiceModel.Security;
  15. using System.ServiceModel.Security.Tokens;
  16. using System.Xml;
  17. using System.IdentityModel.Protocols.WSTrust;
  18. using SafeFreeCredentials = System.IdentityModel.SafeFreeCredentials;
  19. public class ClientCredentialsSecurityTokenManager : SecurityTokenManager
  20. {
  21. ClientCredentials parent;
  22. public ClientCredentialsSecurityTokenManager(ClientCredentials clientCredentials)
  23. {
  24. if (clientCredentials == null)
  25. {
  26. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("clientCredentials");
  27. }
  28. this.parent = clientCredentials;
  29. }
  30. public ClientCredentials ClientCredentials
  31. {
  32. get { return this.parent; }
  33. }
  34. string GetServicePrincipalName(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement)
  35. {
  36. EndpointAddress targetAddress = initiatorRequirement.TargetAddress;
  37. if (targetAddress == null)
  38. {
  39. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenRequirementDoesNotSpecifyTargetAddress, initiatorRequirement));
  40. }
  41. IdentityVerifier identityVerifier;
  42. SecurityBindingElement securityBindingElement = initiatorRequirement.SecurityBindingElement;
  43. if (securityBindingElement != null)
  44. {
  45. identityVerifier = securityBindingElement.LocalClientSettings.IdentityVerifier;
  46. }
  47. else
  48. {
  49. identityVerifier = IdentityVerifier.CreateDefault();
  50. }
  51. EndpointIdentity identity;
  52. identityVerifier.TryGetIdentity(targetAddress, out identity);
  53. return SecurityUtils.GetSpnFromIdentity(identity, targetAddress);
  54. }
  55. SspiSecurityToken GetSpnegoClientCredential(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement)
  56. {
  57. InitiatorServiceModelSecurityTokenRequirement sspiCredentialRequirement = new InitiatorServiceModelSecurityTokenRequirement();
  58. sspiCredentialRequirement.TargetAddress = initiatorRequirement.TargetAddress;
  59. sspiCredentialRequirement.TokenType = ServiceModelSecurityTokenTypes.SspiCredential;
  60. sspiCredentialRequirement.Via = initiatorRequirement.Via;
  61. sspiCredentialRequirement.RequireCryptographicToken = false;
  62. sspiCredentialRequirement.SecurityBindingElement = initiatorRequirement.SecurityBindingElement;
  63. sspiCredentialRequirement.MessageSecurityVersion = initiatorRequirement.MessageSecurityVersion;
  64. ChannelParameterCollection parameters;
  65. if (initiatorRequirement.TryGetProperty<ChannelParameterCollection>(ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty, out parameters))
  66. {
  67. sspiCredentialRequirement.Properties[ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty] = parameters;
  68. }
  69. SecurityTokenProvider sspiTokenProvider = this.CreateSecurityTokenProvider(sspiCredentialRequirement);
  70. SecurityUtils.OpenTokenProviderIfRequired(sspiTokenProvider, TimeSpan.Zero);
  71. SspiSecurityToken sspiToken = (SspiSecurityToken) sspiTokenProvider.GetToken(TimeSpan.Zero);
  72. SecurityUtils.AbortTokenProviderIfRequired(sspiTokenProvider);
  73. return sspiToken;
  74. }
  75. SecurityTokenProvider CreateSpnegoTokenProvider(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement)
  76. {
  77. EndpointAddress targetAddress = initiatorRequirement.TargetAddress;
  78. if (targetAddress == null)
  79. {
  80. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenRequirementDoesNotSpecifyTargetAddress, initiatorRequirement));
  81. }
  82. SecurityBindingElement securityBindingElement = initiatorRequirement.SecurityBindingElement;
  83. if (securityBindingElement == null)
  84. {
  85. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenProviderRequiresSecurityBindingElement, initiatorRequirement));
  86. }
  87. SspiIssuanceChannelParameter sspiChannelParameter = GetSspiIssuanceChannelParameter(initiatorRequirement);
  88. bool negotiateTokenOnOpen = (sspiChannelParameter == null ? true : sspiChannelParameter.GetTokenOnOpen);
  89. LocalClientSecuritySettings localClientSettings = securityBindingElement.LocalClientSettings;
  90. BindingContext issuerBindingContext = initiatorRequirement.GetProperty<BindingContext>(ServiceModelSecurityTokenRequirement.IssuerBindingContextProperty);
  91. SpnegoTokenProvider spnegoTokenProvider = new SpnegoTokenProvider(sspiChannelParameter != null ? sspiChannelParameter.CredentialsHandle : null, securityBindingElement);
  92. SspiSecurityToken clientSspiToken = GetSpnegoClientCredential(initiatorRequirement);
  93. spnegoTokenProvider.ClientCredential = clientSspiToken.NetworkCredential;
  94. spnegoTokenProvider.IssuerAddress = initiatorRequirement.IssuerAddress;
  95. spnegoTokenProvider.AllowedImpersonationLevel = parent.Windows.AllowedImpersonationLevel;
  96. spnegoTokenProvider.AllowNtlm = clientSspiToken.AllowNtlm;
  97. spnegoTokenProvider.IdentityVerifier = localClientSettings.IdentityVerifier;
  98. spnegoTokenProvider.SecurityAlgorithmSuite = initiatorRequirement.SecurityAlgorithmSuite;
  99. // if this is not a supporting token, authenticate the server
  100. spnegoTokenProvider.AuthenticateServer = !initiatorRequirement.Properties.ContainsKey(ServiceModelSecurityTokenRequirement.SupportingTokenAttachmentModeProperty);
  101. spnegoTokenProvider.NegotiateTokenOnOpen = negotiateTokenOnOpen;
  102. spnegoTokenProvider.CacheServiceTokens = negotiateTokenOnOpen || localClientSettings.CacheCookies;
  103. spnegoTokenProvider.IssuerBindingContext = issuerBindingContext;
  104. spnegoTokenProvider.MaxServiceTokenCachingTime = localClientSettings.MaxCookieCachingTime;
  105. spnegoTokenProvider.ServiceTokenValidityThresholdPercentage = localClientSettings.CookieRenewalThresholdPercentage;
  106. spnegoTokenProvider.StandardsManager = SecurityUtils.CreateSecurityStandardsManager(initiatorRequirement, this);
  107. spnegoTokenProvider.TargetAddress = targetAddress;
  108. spnegoTokenProvider.Via = initiatorRequirement.GetPropertyOrDefault<Uri>(InitiatorServiceModelSecurityTokenRequirement.ViaProperty, null);
  109. spnegoTokenProvider.ApplicationProtectionRequirements = (issuerBindingContext != null) ? issuerBindingContext.BindingParameters.Find<ChannelProtectionRequirements>() : null;
  110. spnegoTokenProvider.InteractiveNegoExLogonEnabled = this.ClientCredentials.SupportInteractive;
  111. return spnegoTokenProvider;
  112. }
  113. SecurityTokenProvider CreateTlsnegoClientX509TokenProvider(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement)
  114. {
  115. InitiatorServiceModelSecurityTokenRequirement clientX509Requirement = new InitiatorServiceModelSecurityTokenRequirement();
  116. clientX509Requirement.TokenType = SecurityTokenTypes.X509Certificate;
  117. clientX509Requirement.TargetAddress = initiatorRequirement.TargetAddress;
  118. clientX509Requirement.SecurityBindingElement = initiatorRequirement.SecurityBindingElement;
  119. clientX509Requirement.SecurityAlgorithmSuite = initiatorRequirement.SecurityAlgorithmSuite;
  120. clientX509Requirement.RequireCryptographicToken = true;
  121. clientX509Requirement.MessageSecurityVersion = initiatorRequirement.MessageSecurityVersion;
  122. clientX509Requirement.KeyUsage = SecurityKeyUsage.Signature;
  123. clientX509Requirement.KeyType = SecurityKeyType.AsymmetricKey;
  124. clientX509Requirement.Properties[ServiceModelSecurityTokenRequirement.MessageDirectionProperty] = MessageDirection.Output;
  125. ChannelParameterCollection parameters;
  126. if (initiatorRequirement.TryGetProperty<ChannelParameterCollection>(ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty, out parameters))
  127. {
  128. clientX509Requirement.Properties[ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty] = parameters;
  129. }
  130. return this.CreateSecurityTokenProvider(clientX509Requirement);
  131. }
  132. SecurityTokenAuthenticator CreateTlsnegoServerX509TokenAuthenticator(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement)
  133. {
  134. InitiatorServiceModelSecurityTokenRequirement serverX509Requirement = new InitiatorServiceModelSecurityTokenRequirement();
  135. serverX509Requirement.TokenType = SecurityTokenTypes.X509Certificate;
  136. serverX509Requirement.RequireCryptographicToken = true;
  137. serverX509Requirement.SecurityBindingElement = initiatorRequirement.SecurityBindingElement;
  138. serverX509Requirement.MessageSecurityVersion = initiatorRequirement.MessageSecurityVersion;
  139. serverX509Requirement.KeyUsage = SecurityKeyUsage.Exchange;
  140. serverX509Requirement.KeyType = SecurityKeyType.AsymmetricKey;
  141. serverX509Requirement.Properties[ServiceModelSecurityTokenRequirement.MessageDirectionProperty] = MessageDirection.Input;
  142. ChannelParameterCollection parameters;
  143. if (initiatorRequirement.TryGetProperty<ChannelParameterCollection>(ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty, out parameters))
  144. {
  145. serverX509Requirement.Properties[ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty] = parameters;
  146. }
  147. SecurityTokenResolver dummy;
  148. return this.CreateSecurityTokenAuthenticator(serverX509Requirement, out dummy);
  149. }
  150. SspiIssuanceChannelParameter GetSspiIssuanceChannelParameter(SecurityTokenRequirement initiatorRequirement)
  151. {
  152. ChannelParameterCollection channelParameters;
  153. if (initiatorRequirement.TryGetProperty<ChannelParameterCollection>(ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty, out channelParameters))
  154. {
  155. if (channelParameters != null)
  156. {
  157. for (int i = 0; i < channelParameters.Count; ++i)
  158. {
  159. if (channelParameters[i] is SspiIssuanceChannelParameter)
  160. {
  161. return (SspiIssuanceChannelParameter)channelParameters[i];
  162. }
  163. }
  164. }
  165. }
  166. return null;
  167. }
  168. SecurityTokenProvider CreateTlsnegoTokenProvider(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement, bool requireClientCertificate)
  169. {
  170. EndpointAddress targetAddress = initiatorRequirement.TargetAddress;
  171. if (targetAddress == null)
  172. {
  173. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenRequirementDoesNotSpecifyTargetAddress, initiatorRequirement));
  174. }
  175. SecurityBindingElement securityBindingElement = initiatorRequirement.SecurityBindingElement;
  176. if (securityBindingElement == null)
  177. {
  178. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenProviderRequiresSecurityBindingElement, initiatorRequirement));
  179. }
  180. SspiIssuanceChannelParameter sspiChannelParameter = GetSspiIssuanceChannelParameter(initiatorRequirement);
  181. bool negotiateTokenOnOpen = sspiChannelParameter != null && sspiChannelParameter.GetTokenOnOpen;
  182. LocalClientSecuritySettings localClientSettings = securityBindingElement.LocalClientSettings;
  183. BindingContext issuerBindingContext = initiatorRequirement.GetProperty<BindingContext>(ServiceModelSecurityTokenRequirement.IssuerBindingContextProperty);
  184. TlsnegoTokenProvider tlsnegoTokenProvider = new TlsnegoTokenProvider();
  185. tlsnegoTokenProvider.IssuerAddress = initiatorRequirement.IssuerAddress;
  186. tlsnegoTokenProvider.NegotiateTokenOnOpen = negotiateTokenOnOpen;
  187. tlsnegoTokenProvider.CacheServiceTokens = negotiateTokenOnOpen || localClientSettings.CacheCookies;
  188. if (requireClientCertificate)
  189. {
  190. tlsnegoTokenProvider.ClientTokenProvider = this.CreateTlsnegoClientX509TokenProvider(initiatorRequirement);
  191. }
  192. tlsnegoTokenProvider.IssuerBindingContext = issuerBindingContext;
  193. tlsnegoTokenProvider.ApplicationProtectionRequirements = (issuerBindingContext != null) ? issuerBindingContext.BindingParameters.Find<ChannelProtectionRequirements>() : null;
  194. tlsnegoTokenProvider.MaxServiceTokenCachingTime = localClientSettings.MaxCookieCachingTime;
  195. tlsnegoTokenProvider.SecurityAlgorithmSuite = initiatorRequirement.SecurityAlgorithmSuite;
  196. tlsnegoTokenProvider.ServerTokenAuthenticator = this.CreateTlsnegoServerX509TokenAuthenticator(initiatorRequirement);
  197. tlsnegoTokenProvider.ServiceTokenValidityThresholdPercentage = localClientSettings.CookieRenewalThresholdPercentage;
  198. tlsnegoTokenProvider.StandardsManager = SecurityUtils.CreateSecurityStandardsManager(initiatorRequirement, this);
  199. tlsnegoTokenProvider.TargetAddress = initiatorRequirement.TargetAddress;
  200. tlsnegoTokenProvider.Via = initiatorRequirement.GetPropertyOrDefault<Uri>(InitiatorServiceModelSecurityTokenRequirement.ViaProperty, null);
  201. return tlsnegoTokenProvider;
  202. }
  203. SecurityTokenProvider CreateSecureConversationSecurityTokenProvider(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement)
  204. {
  205. EndpointAddress targetAddress = initiatorRequirement.TargetAddress;
  206. if (targetAddress == null)
  207. {
  208. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenRequirementDoesNotSpecifyTargetAddress, initiatorRequirement));
  209. }
  210. SecurityBindingElement securityBindingElement = initiatorRequirement.SecurityBindingElement;
  211. if (securityBindingElement == null)
  212. {
  213. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenProviderRequiresSecurityBindingElement, initiatorRequirement));
  214. }
  215. LocalClientSecuritySettings localClientSettings = securityBindingElement.LocalClientSettings;
  216. BindingContext issuerBindingContext = initiatorRequirement.GetProperty<BindingContext>(ServiceModelSecurityTokenRequirement.IssuerBindingContextProperty);
  217. ChannelParameterCollection channelParameters = initiatorRequirement.GetPropertyOrDefault<ChannelParameterCollection>(ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty, null);
  218. bool isSessionMode = initiatorRequirement.SupportSecurityContextCancellation;
  219. if (isSessionMode)
  220. {
  221. SecuritySessionSecurityTokenProvider sessionTokenProvider = new SecuritySessionSecurityTokenProvider(GetCredentialsHandle(initiatorRequirement));
  222. sessionTokenProvider.BootstrapSecurityBindingElement = SecurityUtils.GetIssuerSecurityBindingElement(initiatorRequirement);
  223. sessionTokenProvider.IssuedSecurityTokenParameters = initiatorRequirement.GetProperty<SecurityTokenParameters>(ServiceModelSecurityTokenRequirement.IssuedSecurityTokenParametersProperty);
  224. sessionTokenProvider.IssuerBindingContext = issuerBindingContext;
  225. sessionTokenProvider.KeyEntropyMode = securityBindingElement.KeyEntropyMode;
  226. sessionTokenProvider.SecurityAlgorithmSuite = initiatorRequirement.SecurityAlgorithmSuite;
  227. sessionTokenProvider.StandardsManager = SecurityUtils.CreateSecurityStandardsManager(initiatorRequirement, this);
  228. sessionTokenProvider.TargetAddress = targetAddress;
  229. sessionTokenProvider.Via = initiatorRequirement.GetPropertyOrDefault<Uri>(InitiatorServiceModelSecurityTokenRequirement.ViaProperty, null);
  230. Uri privacyNoticeUri;
  231. if (initiatorRequirement.TryGetProperty<Uri>(ServiceModelSecurityTokenRequirement.PrivacyNoticeUriProperty, out privacyNoticeUri))
  232. {
  233. sessionTokenProvider.PrivacyNoticeUri = privacyNoticeUri;
  234. }
  235. int privacyNoticeVersion;
  236. if (initiatorRequirement.TryGetProperty<int>(ServiceModelSecurityTokenRequirement.PrivacyNoticeVersionProperty, out privacyNoticeVersion))
  237. {
  238. sessionTokenProvider.PrivacyNoticeVersion = privacyNoticeVersion;
  239. }
  240. EndpointAddress localAddress;
  241. if (initiatorRequirement.TryGetProperty<EndpointAddress>(ServiceModelSecurityTokenRequirement.DuplexClientLocalAddressProperty, out localAddress))
  242. {
  243. sessionTokenProvider.LocalAddress = localAddress;
  244. }
  245. sessionTokenProvider.ChannelParameters = channelParameters;
  246. sessionTokenProvider.WebHeaders = initiatorRequirement.WebHeaders;
  247. return sessionTokenProvider;
  248. }
  249. else
  250. {
  251. AcceleratedTokenProvider acceleratedTokenProvider = new AcceleratedTokenProvider(GetCredentialsHandle(initiatorRequirement));
  252. acceleratedTokenProvider.IssuerAddress = initiatorRequirement.IssuerAddress;
  253. acceleratedTokenProvider.BootstrapSecurityBindingElement = SecurityUtils.GetIssuerSecurityBindingElement(initiatorRequirement);
  254. acceleratedTokenProvider.CacheServiceTokens = localClientSettings.CacheCookies;
  255. acceleratedTokenProvider.IssuerBindingContext = issuerBindingContext;
  256. acceleratedTokenProvider.KeyEntropyMode = securityBindingElement.KeyEntropyMode;
  257. acceleratedTokenProvider.MaxServiceTokenCachingTime = localClientSettings.MaxCookieCachingTime;
  258. acceleratedTokenProvider.SecurityAlgorithmSuite = initiatorRequirement.SecurityAlgorithmSuite;
  259. acceleratedTokenProvider.ServiceTokenValidityThresholdPercentage = localClientSettings.CookieRenewalThresholdPercentage;
  260. acceleratedTokenProvider.StandardsManager = SecurityUtils.CreateSecurityStandardsManager(initiatorRequirement, this);
  261. acceleratedTokenProvider.TargetAddress = targetAddress;
  262. acceleratedTokenProvider.Via = initiatorRequirement.GetPropertyOrDefault<Uri>(InitiatorServiceModelSecurityTokenRequirement.ViaProperty, null);
  263. Uri privacyNoticeUri;
  264. if (initiatorRequirement.TryGetProperty<Uri>(ServiceModelSecurityTokenRequirement.PrivacyNoticeUriProperty, out privacyNoticeUri))
  265. {
  266. acceleratedTokenProvider.PrivacyNoticeUri = privacyNoticeUri;
  267. }
  268. acceleratedTokenProvider.ChannelParameters = channelParameters;
  269. int privacyNoticeVersion;
  270. if (initiatorRequirement.TryGetProperty<int>(ServiceModelSecurityTokenRequirement.PrivacyNoticeVersionProperty, out privacyNoticeVersion))
  271. {
  272. acceleratedTokenProvider.PrivacyNoticeVersion = privacyNoticeVersion;
  273. }
  274. return acceleratedTokenProvider;
  275. }
  276. }
  277. SecurityTokenProvider CreateServerX509TokenProvider(EndpointAddress targetAddress)
  278. {
  279. X509Certificate2 targetServerCertificate = null;
  280. if (targetAddress != null)
  281. {
  282. parent.ServiceCertificate.ScopedCertificates.TryGetValue(targetAddress.Uri, out targetServerCertificate);
  283. }
  284. if (targetServerCertificate == null)
  285. {
  286. targetServerCertificate = parent.ServiceCertificate.DefaultCertificate;
  287. }
  288. if ((targetServerCertificate == null) && (targetAddress.Identity != null) && (targetAddress.Identity.GetType() == typeof(X509CertificateEndpointIdentity)))
  289. {
  290. targetServerCertificate = ((X509CertificateEndpointIdentity)targetAddress.Identity).Certificates[0];
  291. }
  292. if (targetServerCertificate != null)
  293. {
  294. return new X509SecurityTokenProvider(targetServerCertificate);
  295. }
  296. else
  297. {
  298. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ServiceCertificateNotProvidedOnClientCredentials, targetAddress.Uri)));
  299. }
  300. }
  301. X509SecurityTokenAuthenticator CreateServerX509TokenAuthenticator()
  302. {
  303. return new X509SecurityTokenAuthenticator(parent.ServiceCertificate.Authentication.GetCertificateValidator(), false);
  304. }
  305. X509SecurityTokenAuthenticator CreateServerSslX509TokenAuthenticator()
  306. {
  307. if (parent.ServiceCertificate.SslCertificateAuthentication != null)
  308. {
  309. return new X509SecurityTokenAuthenticator(parent.ServiceCertificate.SslCertificateAuthentication.GetCertificateValidator(), false);
  310. }
  311. return CreateServerX509TokenAuthenticator();
  312. }
  313. bool IsDigestAuthenticationScheme(SecurityTokenRequirement requirement)
  314. {
  315. if (requirement.Properties.ContainsKey(ServiceModelSecurityTokenRequirement.HttpAuthenticationSchemeProperty))
  316. {
  317. AuthenticationSchemes authScheme = (AuthenticationSchemes)requirement.Properties[ServiceModelSecurityTokenRequirement.HttpAuthenticationSchemeProperty];
  318. if (!authScheme.IsSingleton())
  319. {
  320. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("value", SR.GetString(SR.HttpRequiresSingleAuthScheme, authScheme));
  321. }
  322. return (authScheme == AuthenticationSchemes.Digest);
  323. }
  324. else
  325. {
  326. return false;
  327. }
  328. }
  329. internal protected bool IsIssuedSecurityTokenRequirement(SecurityTokenRequirement requirement)
  330. {
  331. if (requirement != null && requirement.Properties.ContainsKey(ServiceModelSecurityTokenRequirement.IssuerAddressProperty))
  332. {
  333. // handle all issued token requirements except for spnego, tlsnego and secure conversation
  334. if (requirement.TokenType == ServiceModelSecurityTokenTypes.AnonymousSslnego || requirement.TokenType == ServiceModelSecurityTokenTypes.MutualSslnego
  335. || requirement.TokenType == ServiceModelSecurityTokenTypes.SecureConversation || requirement.TokenType == ServiceModelSecurityTokenTypes.Spnego)
  336. {
  337. return false;
  338. }
  339. else
  340. {
  341. return true;
  342. }
  343. }
  344. return false;
  345. }
  346. void CopyIssuerChannelBehaviorsAndAddSecurityCredentials(IssuedSecurityTokenProvider federationTokenProvider, KeyedByTypeCollection<IEndpointBehavior> issuerChannelBehaviors, EndpointAddress issuerAddress)
  347. {
  348. if (issuerChannelBehaviors != null)
  349. {
  350. foreach (IEndpointBehavior behavior in issuerChannelBehaviors)
  351. {
  352. if (behavior is SecurityCredentialsManager)
  353. {
  354. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.IssuerChannelBehaviorsCannotContainSecurityCredentialsManager, issuerAddress, typeof(SecurityCredentialsManager))));
  355. }
  356. federationTokenProvider.IssuerChannelBehaviors.Add(behavior);
  357. }
  358. }
  359. federationTokenProvider.IssuerChannelBehaviors.Add(parent);
  360. }
  361. SecurityKeyEntropyMode GetIssuerBindingKeyEntropyModeOrDefault(Binding issuerBinding)
  362. {
  363. BindingElementCollection bindingElements = issuerBinding.CreateBindingElements();
  364. SecurityBindingElement securityBindingElement = bindingElements.Find<SecurityBindingElement>();
  365. if (securityBindingElement != null)
  366. {
  367. return securityBindingElement.KeyEntropyMode;
  368. }
  369. else
  370. {
  371. return parent.IssuedToken.DefaultKeyEntropyMode;
  372. }
  373. }
  374. void GetIssuerBindingSecurityVersion(Binding issuerBinding, MessageSecurityVersion issuedTokenParametersDefaultMessageSecurityVersion, SecurityBindingElement outerSecurityBindingElement, out MessageSecurityVersion messageSecurityVersion, out SecurityTokenSerializer tokenSerializer)
  375. {
  376. // Logic for setting version is:
  377. // 1. use issuer SBE
  378. // 2. use ITSP
  379. // 3. use outer SBE
  380. //
  381. messageSecurityVersion = null;
  382. if (issuerBinding != null)
  383. {
  384. BindingElementCollection bindingElements = issuerBinding.CreateBindingElements();
  385. SecurityBindingElement securityBindingElement = bindingElements.Find<SecurityBindingElement>();
  386. if (securityBindingElement != null)
  387. {
  388. messageSecurityVersion = securityBindingElement.MessageSecurityVersion;
  389. }
  390. }
  391. if (messageSecurityVersion == null)
  392. {
  393. if (issuedTokenParametersDefaultMessageSecurityVersion != null)
  394. {
  395. messageSecurityVersion = issuedTokenParametersDefaultMessageSecurityVersion;
  396. }
  397. else if (outerSecurityBindingElement != null)
  398. {
  399. messageSecurityVersion = outerSecurityBindingElement.MessageSecurityVersion;
  400. }
  401. }
  402. if (messageSecurityVersion == null)
  403. {
  404. messageSecurityVersion = MessageSecurityVersion.Default;
  405. }
  406. tokenSerializer = this.CreateSecurityTokenSerializer(messageSecurityVersion.SecurityTokenVersion);
  407. }
  408. IssuedSecurityTokenProvider CreateIssuedSecurityTokenProvider(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement, FederatedClientCredentialsParameters actAsOnBehalfOfParameters)
  409. {
  410. if (initiatorRequirement.TargetAddress == null)
  411. {
  412. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenRequirementDoesNotSpecifyTargetAddress, initiatorRequirement));
  413. }
  414. SecurityBindingElement securityBindingElement = initiatorRequirement.SecurityBindingElement;
  415. if (securityBindingElement == null)
  416. {
  417. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.TokenProviderRequiresSecurityBindingElement, initiatorRequirement));
  418. }
  419. EndpointAddress issuerAddress = initiatorRequirement.IssuerAddress;
  420. Binding issuerBinding = initiatorRequirement.IssuerBinding;
  421. //
  422. // If the issuer address is indeed anonymous or null, we will try the local issuer
  423. //
  424. bool isLocalIssuer = (issuerAddress == null || issuerAddress.Equals(EndpointAddress.AnonymousAddress));
  425. if (isLocalIssuer)
  426. {
  427. issuerAddress = parent.IssuedToken.LocalIssuerAddress;
  428. issuerBinding = parent.IssuedToken.LocalIssuerBinding;
  429. }
  430. if (issuerAddress == null)
  431. {
  432. // if issuer address is still null then the user forgot to specify the local issuer
  433. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.StsAddressNotSet, initiatorRequirement.TargetAddress)));
  434. }
  435. if (issuerBinding == null)
  436. {
  437. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.StsBindingNotSet, issuerAddress)));
  438. }
  439. Uri issuerUri = issuerAddress.Uri;
  440. KeyedByTypeCollection<IEndpointBehavior> issuerChannelBehaviors;
  441. if (!parent.IssuedToken.IssuerChannelBehaviors.TryGetValue(issuerAddress.Uri, out issuerChannelBehaviors) && isLocalIssuer)
  442. {
  443. issuerChannelBehaviors = parent.IssuedToken.LocalIssuerChannelBehaviors;
  444. }
  445. IssuedSecurityTokenProvider federationTokenProvider = new IssuedSecurityTokenProvider(GetCredentialsHandle(initiatorRequirement));
  446. federationTokenProvider.TokenHandlerCollectionManager = this.parent.SecurityTokenHandlerCollectionManager;
  447. federationTokenProvider.TargetAddress = initiatorRequirement.TargetAddress;
  448. CopyIssuerChannelBehaviorsAndAddSecurityCredentials(federationTokenProvider, issuerChannelBehaviors, issuerAddress);
  449. federationTokenProvider.CacheIssuedTokens = parent.IssuedToken.CacheIssuedTokens;
  450. federationTokenProvider.IdentityVerifier = securityBindingElement.LocalClientSettings.IdentityVerifier;
  451. federationTokenProvider.IssuerAddress = issuerAddress;
  452. federationTokenProvider.IssuerBinding = issuerBinding;
  453. federationTokenProvider.KeyEntropyMode = GetIssuerBindingKeyEntropyModeOrDefault(issuerBinding);
  454. federationTokenProvider.MaxIssuedTokenCachingTime = parent.IssuedToken.MaxIssuedTokenCachingTime;
  455. federationTokenProvider.SecurityAlgorithmSuite = initiatorRequirement.SecurityAlgorithmSuite;
  456. MessageSecurityVersion issuerSecurityVersion;
  457. SecurityTokenSerializer issuerSecurityTokenSerializer;
  458. IssuedSecurityTokenParameters issuedTokenParameters = initiatorRequirement.GetProperty<IssuedSecurityTokenParameters>(ServiceModelSecurityTokenRequirement.IssuedSecurityTokenParametersProperty);
  459. GetIssuerBindingSecurityVersion(issuerBinding, issuedTokenParameters.DefaultMessageSecurityVersion, initiatorRequirement.SecurityBindingElement, out issuerSecurityVersion, out issuerSecurityTokenSerializer);
  460. federationTokenProvider.MessageSecurityVersion = issuerSecurityVersion;
  461. federationTokenProvider.SecurityTokenSerializer = issuerSecurityTokenSerializer;
  462. federationTokenProvider.IssuedTokenRenewalThresholdPercentage = parent.IssuedToken.IssuedTokenRenewalThresholdPercentage;
  463. IEnumerable<XmlElement> tokenRequestParameters = issuedTokenParameters.CreateRequestParameters(issuerSecurityVersion, issuerSecurityTokenSerializer);
  464. if (tokenRequestParameters != null)
  465. {
  466. foreach (XmlElement requestParameter in tokenRequestParameters)
  467. {
  468. federationTokenProvider.TokenRequestParameters.Add(requestParameter);
  469. }
  470. }
  471. ChannelParameterCollection channelParameters;
  472. if (initiatorRequirement.TryGetProperty<ChannelParameterCollection>(ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty, out channelParameters))
  473. {
  474. federationTokenProvider.ChannelParameters = channelParameters;
  475. }
  476. federationTokenProvider.SetupActAsOnBehalfOfParameters(actAsOnBehalfOfParameters);
  477. return federationTokenProvider;
  478. }
  479. public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement)
  480. {
  481. return this.CreateSecurityTokenProvider(tokenRequirement, false);
  482. }
  483. internal SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement, bool disableInfoCard)
  484. {
  485. if (tokenRequirement == null)
  486. {
  487. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokenRequirement");
  488. }
  489. SecurityTokenProvider result = null;
  490. if (disableInfoCard || !CardSpaceTryCreateSecurityTokenProviderStub(tokenRequirement, this, out result))
  491. {
  492. if (tokenRequirement is RecipientServiceModelSecurityTokenRequirement && tokenRequirement.TokenType == SecurityTokenTypes.X509Certificate && tokenRequirement.KeyUsage == SecurityKeyUsage.Exchange)
  493. {
  494. // this is the uncorrelated duplex case
  495. if (parent.ClientCertificate.Certificate == null)
  496. {
  497. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ClientCertificateNotProvidedOnClientCredentials)));
  498. }
  499. result = new X509SecurityTokenProvider(parent.ClientCertificate.Certificate);
  500. }
  501. else if (tokenRequirement is InitiatorServiceModelSecurityTokenRequirement)
  502. {
  503. InitiatorServiceModelSecurityTokenRequirement initiatorRequirement = tokenRequirement as InitiatorServiceModelSecurityTokenRequirement;
  504. #pragma warning suppress 56506 // initiatorRequirement will never be null due to the preceding 'is' validation.
  505. string tokenType = initiatorRequirement.TokenType;
  506. if (IsIssuedSecurityTokenRequirement(initiatorRequirement))
  507. {
  508. FederatedClientCredentialsParameters additionalParameters = this.FindFederatedChannelParameters(tokenRequirement);
  509. if (additionalParameters != null && additionalParameters.IssuedSecurityToken != null)
  510. {
  511. return new SimpleSecurityTokenProvider(additionalParameters.IssuedSecurityToken, tokenRequirement);
  512. }
  513. result = CreateIssuedSecurityTokenProvider(initiatorRequirement, additionalParameters);
  514. }
  515. else if (tokenType == SecurityTokenTypes.X509Certificate)
  516. {
  517. if (initiatorRequirement.Properties.ContainsKey(SecurityTokenRequirement.KeyUsageProperty) && initiatorRequirement.KeyUsage == SecurityKeyUsage.Exchange)
  518. {
  519. result = CreateServerX509TokenProvider(initiatorRequirement.TargetAddress);
  520. }
  521. else
  522. {
  523. if (parent.ClientCertificate.Certificate == null)
  524. {
  525. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ClientCertificateNotProvidedOnClientCredentials)));
  526. }
  527. result = new X509SecurityTokenProvider(parent.ClientCertificate.Certificate);
  528. }
  529. }
  530. else if (tokenType == SecurityTokenTypes.Kerberos)
  531. {
  532. string spn = GetServicePrincipalName(initiatorRequirement);
  533. result = new KerberosSecurityTokenProviderWrapper(
  534. new KerberosSecurityTokenProvider(spn, parent.Windows.AllowedImpersonationLevel, SecurityUtils.GetNetworkCredentialOrDefault(parent.Windows.ClientCredential)),
  535. GetCredentialsHandle(initiatorRequirement));
  536. }
  537. else if (tokenType == SecurityTokenTypes.UserName)
  538. {
  539. if (parent.UserName.UserName == null )
  540. {
  541. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UserNamePasswordNotProvidedOnClientCredentials)));
  542. }
  543. result = new UserNameSecurityTokenProvider(parent.UserName.UserName, parent.UserName.Password);
  544. }
  545. else if (tokenType == ServiceModelSecurityTokenTypes.SspiCredential)
  546. {
  547. if (IsDigestAuthenticationScheme(initiatorRequirement))
  548. {
  549. result = new SspiSecurityTokenProvider(SecurityUtils.GetNetworkCredentialOrDefault(parent.HttpDigest.ClientCredential), true, parent.HttpDigest.AllowedImpersonationLevel);
  550. }
  551. else
  552. {
  553. #pragma warning disable 618 // to disable AllowNtlm obsolete wanring.
  554. result = new SspiSecurityTokenProvider(SecurityUtils.GetNetworkCredentialOrDefault(parent.Windows.ClientCredential),
  555. parent.Windows.AllowNtlm,
  556. parent.Windows.AllowedImpersonationLevel);
  557. #pragma warning restore 618
  558. }
  559. }
  560. else if (tokenType == ServiceModelSecurityTokenTypes.Spnego)
  561. {
  562. result = CreateSpnegoTokenProvider(initiatorRequirement);
  563. }
  564. else if (tokenType == ServiceModelSecurityTokenTypes.MutualSslnego)
  565. {
  566. result = CreateTlsnegoTokenProvider(initiatorRequirement, true);
  567. }
  568. else if (tokenType == ServiceModelSecurityTokenTypes.AnonymousSslnego)
  569. {
  570. result = CreateTlsnegoTokenProvider(initiatorRequirement, false);
  571. }
  572. else if (tokenType == ServiceModelSecurityTokenTypes.SecureConversation)
  573. {
  574. result = CreateSecureConversationSecurityTokenProvider(initiatorRequirement);
  575. }
  576. }
  577. }
  578. if ((result == null) && !tokenRequirement.IsOptionalToken)
  579. {
  580. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SecurityTokenManagerCannotCreateProviderForRequirement, tokenRequirement)));
  581. }
  582. return result;
  583. }
  584. bool CardSpaceTryCreateSecurityTokenProviderStub(SecurityTokenRequirement tokenRequirement, ClientCredentialsSecurityTokenManager clientCredentialsTokenManager, out SecurityTokenProvider provider)
  585. {
  586. return InfoCardHelper.TryCreateSecurityTokenProvider(tokenRequirement, clientCredentialsTokenManager, out provider);
  587. }
  588. protected SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityVersion version)
  589. {
  590. if (version == null)
  591. {
  592. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("version"));
  593. }
  594. return this.CreateSecurityTokenSerializer(MessageSecurityTokenVersion.GetSecurityTokenVersion(version, true));
  595. }
  596. public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version)
  597. {
  598. if (version == null)
  599. {
  600. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("version");
  601. }
  602. if (this.parent != null && this.parent.UseIdentityConfiguration)
  603. {
  604. return this.WrapTokenHandlersAsSecurityTokenSerializer(version);
  605. }
  606. MessageSecurityTokenVersion wsVersion = version as MessageSecurityTokenVersion;
  607. if (wsVersion != null)
  608. {
  609. return new WSSecurityTokenSerializer(wsVersion.SecurityVersion, wsVersion.TrustVersion, wsVersion.SecureConversationVersion, wsVersion.EmitBspRequiredAttributes, null, null, null);
  610. }
  611. else
  612. {
  613. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SecurityTokenManagerCannotCreateSerializerForVersion, version)));
  614. }
  615. }
  616. private SecurityTokenSerializer WrapTokenHandlersAsSecurityTokenSerializer(SecurityTokenVersion version)
  617. {
  618. TrustVersion trustVersion = TrustVersion.WSTrust13;
  619. SecureConversationVersion scVersion = SecureConversationVersion.WSSecureConversation13;
  620. SecurityVersion securityVersion = SecurityVersion.WSSecurity11;
  621. foreach (string securitySpecification in version.GetSecuritySpecifications())
  622. {
  623. if (StringComparer.Ordinal.Equals(securitySpecification, WSTrustFeb2005Constants.NamespaceURI))
  624. {
  625. trustVersion = TrustVersion.WSTrustFeb2005;
  626. }
  627. else if (StringComparer.Ordinal.Equals(securitySpecification, WSTrust13Constants.NamespaceURI))
  628. {
  629. trustVersion = TrustVersion.WSTrust13;
  630. }
  631. else if (StringComparer.Ordinal.Equals(securitySpecification, System.IdentityModel.WSSecureConversationFeb2005Constants.Namespace))
  632. {
  633. scVersion = SecureConversationVersion.WSSecureConversationFeb2005;
  634. }
  635. else if (StringComparer.Ordinal.Equals(securitySpecification, System.IdentityModel.WSSecureConversation13Constants.Namespace))
  636. {
  637. scVersion = SecureConversationVersion.WSSecureConversation13;
  638. }
  639. }
  640. securityVersion = FederatedSecurityTokenManager.GetSecurityVersion(version);
  641. //
  642. //
  643. SecurityTokenHandlerCollectionManager sthcm = this.parent.SecurityTokenHandlerCollectionManager;
  644. WsSecurityTokenSerializerAdapter adapter = new WsSecurityTokenSerializerAdapter(sthcm[SecurityTokenHandlerCollectionManager.Usage.Default], securityVersion, trustVersion, scVersion, false, null, null, null);
  645. return adapter;
  646. }
  647. public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver)
  648. {
  649. if (tokenRequirement == null)
  650. {
  651. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokenRequirement");
  652. }
  653. outOfBandTokenResolver = null;
  654. SecurityTokenAuthenticator result = null;
  655. InitiatorServiceModelSecurityTokenRequirement initiatorRequirement = tokenRequirement as InitiatorServiceModelSecurityTokenRequirement;
  656. if (initiatorRequirement != null)
  657. {
  658. string tokenType = initiatorRequirement.TokenType;
  659. if (IsIssuedSecurityTokenRequirement(initiatorRequirement))
  660. {
  661. return new GenericXmlSecurityTokenAuthenticator();
  662. }
  663. else if (tokenType == SecurityTokenTypes.X509Certificate)
  664. {
  665. if (initiatorRequirement.IsOutOfBandToken)
  666. {
  667. // when the client side soap security asks for a token authenticator, its for doing
  668. // identity checks on the out of band server certificate
  669. result = new X509SecurityTokenAuthenticator(X509CertificateValidator.None);
  670. }
  671. else if (initiatorRequirement.PreferSslCertificateAuthenticator)
  672. {
  673. result = CreateServerSslX509TokenAuthenticator();
  674. }
  675. else
  676. {
  677. result = CreateServerX509TokenAuthenticator();
  678. }
  679. }
  680. else if (tokenType == SecurityTokenTypes.Rsa)
  681. {
  682. result = new RsaSecurityTokenAuthenticator();
  683. }
  684. else if (tokenType == SecurityTokenTypes.Kerberos)
  685. {
  686. result = new KerberosRequestorSecurityTokenAuthenticator();
  687. }
  688. else if (tokenType == ServiceModelSecurityTokenTypes.SecureConversation
  689. || tokenType == ServiceModelSecurityTokenTypes.MutualSslnego
  690. || tokenType == ServiceModelSecurityTokenTypes.AnonymousSslnego
  691. || tokenType == ServiceModelSecurityTokenTypes.Spnego)
  692. {
  693. result = new GenericXmlSecurityTokenAuthenticator();
  694. }
  695. }
  696. else if ((tokenRequirement is RecipientServiceModelSecurityTokenRequirement) && tokenRequirement.TokenType == SecurityTokenTypes.X509Certificate)
  697. {
  698. // uncorrelated duplex case
  699. result = CreateServerX509TokenAuthenticator();
  700. }
  701. if (result == null)
  702. {
  703. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SecurityTokenManagerCannotCreateAuthenticatorForRequirement, tokenRequirement)));
  704. }
  705. return result;
  706. }
  707. SafeFreeCredentials GetCredentialsHandle(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement)
  708. {
  709. SspiIssuanceChannelParameter sspiChannelParameter = GetSspiIssuanceChannelParameter(initiatorRequirement);
  710. return sspiChannelParameter != null ? sspiChannelParameter.CredentialsHandle : null;
  711. }
  712. /// <summary>
  713. /// Looks for the first FederatedClientCredentialsParameters object in the ChannelParameterCollection
  714. /// property on the tokenRequirement.
  715. /// </summary>
  716. internal FederatedClientCredentialsParameters FindFederatedChannelParameters(SecurityTokenRequirement tokenRequirement)
  717. {
  718. FederatedClientCredentialsParameters issuedTokenClientCredentialsParameters = null;
  719. ChannelParameterCollection channelParameterCollection = null;
  720. if (tokenRequirement.TryGetProperty<ChannelParameterCollection>(
  721. ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty,
  722. out channelParameterCollection))
  723. {
  724. if (channelParameterCollection != null)
  725. {
  726. foreach (object obj in channelParameterCollection)
  727. {
  728. issuedTokenClientCredentialsParameters = obj as FederatedClientCredentialsParameters;
  729. if (issuedTokenClientCredentialsParameters != null)
  730. {
  731. break;
  732. }
  733. }
  734. }
  735. }
  736. return issuedTokenClientCredentialsParameters;
  737. }
  738. internal class KerberosSecurityTokenProviderWrapper : CommunicationObjectSecurityTokenProvider
  739. {
  740. KerberosSecurityTokenProvider innerProvider;
  741. SafeFreeCredentials credentialsHandle;
  742. bool ownCredentialsHandle = false;
  743. public KerberosSecurityTokenProviderWrapper(KerberosSecurityTokenProvider innerProvider, SafeFreeCredentials credentialsHandle)
  744. {
  745. this.innerProvider = innerProvider;
  746. this.credentialsHandle = credentialsHandle;
  747. }
  748. public override void OnOpening()
  749. {
  750. base.OnOpening();
  751. if (this.credentialsHandle == null)
  752. {
  753. this.credentialsHandle = SecurityUtils.GetCredentialsHandle("Kerberos", this.innerProvider.NetworkCredential, false);
  754. this.ownCredentialsHandle = true;
  755. }
  756. }
  757. public override void OnClose(TimeSpan timeout)
  758. {
  759. base.OnClose(timeout);
  760. FreeCredentialsHandle();
  761. }
  762. public override void OnAbort()
  763. {
  764. base.OnAbort();
  765. FreeCredentialsHandle();
  766. }
  767. void FreeCredentialsHandle()
  768. {
  769. if (this.credentialsHandle != null)
  770. {
  771. if (this.ownCredentialsHandle)
  772. {
  773. this.credentialsHandle.Close();
  774. }
  775. this.credentialsHandle = null;
  776. }
  777. }
  778. internal SecurityToken GetToken(TimeSpan timeout, ChannelBinding channelbinding)
  779. {
  780. return new KerberosRequestorSecurityToken(this.innerProvider.ServicePrincipalName,
  781. this.innerProvider.TokenImpersonationLevel, this.innerProvider.NetworkCredential,
  782. SecurityUniqueId.Create().Value, this.credentialsHandle, channelbinding);
  783. }
  784. protected override SecurityToken GetTokenCore(TimeSpan timeout)
  785. {
  786. return this.GetToken(timeout, null);
  787. }
  788. }
  789. }
  790. }