PageRenderTime 48ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/mcs/class/referencesource/System.ServiceModel/System/ServiceModel/Security/Tokens/IssuedSecurityTokenProvider.cs

https://github.com/pruiz/mono
C# | 1127 lines | 989 code | 113 blank | 25 comment | 144 complexity | af855b4a48ae89613c639efd7a1befee MD5 | raw file
Possible License(s): LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel.Security.Tokens
  5. {
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Collections.ObjectModel;
  9. using System.ComponentModel;
  10. using System.IdentityModel.Claims;
  11. using System.IdentityModel.Policy;
  12. using System.IdentityModel.Selectors;
  13. using System.IdentityModel.Tokens;
  14. using System.Runtime;
  15. using System.Runtime.InteropServices;
  16. using System.Security.Cryptography;
  17. using System.Security.Principal;
  18. using System.ServiceModel;
  19. using System.ServiceModel.Channels;
  20. using System.ServiceModel.Description;
  21. using System.ServiceModel.Diagnostics;
  22. using System.ServiceModel.Dispatcher;
  23. using System.ServiceModel.Security;
  24. using System.Xml;
  25. using SafeCloseHandle = System.IdentityModel.SafeCloseHandle;
  26. using SafeFreeCredentials = System.IdentityModel.SafeFreeCredentials;
  27. using SafeNativeMethods = System.ServiceModel.ComIntegration.SafeNativeMethods;
  28. using Win32Error = System.ServiceModel.ComIntegration.Win32Error;
  29. using WSTrustFeb2005Constants = System.IdentityModel.Protocols.WSTrust.WSTrustFeb2005Constants;
  30. using WSTrust13Constants = System.IdentityModel.Protocols.WSTrust.WSTrust13Constants;
  31. using WSTrust14Constants = System.IdentityModel.Protocols.WSTrust.WSTrust14Constants;
  32. using System.IO;
  33. using System.Text;
  34. public class IssuedSecurityTokenProvider : SecurityTokenProvider, ICommunicationObject
  35. {
  36. CoreFederatedTokenProvider federatedTokenProvider;
  37. MessageSecurityVersion messageSecurityVersion;
  38. SecurityTokenSerializer securityTokenSerializer;
  39. SecurityTokenHandlerCollectionManager tokenHandlerCollectionManager = null;
  40. public IssuedSecurityTokenProvider()
  41. : this(null)
  42. {
  43. }
  44. internal IssuedSecurityTokenProvider(SafeFreeCredentials credentialsHandle)
  45. {
  46. this.federatedTokenProvider = new CoreFederatedTokenProvider(credentialsHandle);
  47. this.messageSecurityVersion = MessageSecurityVersion.Default;
  48. }
  49. public event EventHandler Closed
  50. {
  51. add { this.federatedTokenProvider.Closed += value; }
  52. remove { this.federatedTokenProvider.Closed -= value; }
  53. }
  54. public event EventHandler Closing
  55. {
  56. add { this.federatedTokenProvider.Closing += value; }
  57. remove { this.federatedTokenProvider.Closing -= value; }
  58. }
  59. public event EventHandler Faulted
  60. {
  61. add { this.federatedTokenProvider.Faulted += value; }
  62. remove { this.federatedTokenProvider.Faulted -= value; }
  63. }
  64. public event EventHandler Opened
  65. {
  66. add { this.federatedTokenProvider.Opened += value; }
  67. remove { this.federatedTokenProvider.Opened -= value; }
  68. }
  69. public event EventHandler Opening
  70. {
  71. add { this.federatedTokenProvider.Opening += value; }
  72. remove { this.federatedTokenProvider.Opening -= value; }
  73. }
  74. public Binding IssuerBinding
  75. {
  76. get
  77. {
  78. return this.federatedTokenProvider.IssuerBinding;
  79. }
  80. set
  81. {
  82. this.federatedTokenProvider.IssuerBinding = value;
  83. }
  84. }
  85. public KeyedByTypeCollection<IEndpointBehavior> IssuerChannelBehaviors
  86. {
  87. get
  88. {
  89. return this.federatedTokenProvider.IssuerChannelBehaviors;
  90. }
  91. }
  92. public Collection<XmlElement> TokenRequestParameters
  93. {
  94. get
  95. {
  96. return this.federatedTokenProvider.RequestProperties;
  97. }
  98. }
  99. public EndpointAddress IssuerAddress
  100. {
  101. get
  102. {
  103. return this.federatedTokenProvider.IssuerAddress;
  104. }
  105. set
  106. {
  107. this.federatedTokenProvider.IssuerAddress = value;
  108. }
  109. }
  110. public EndpointAddress TargetAddress
  111. {
  112. get
  113. {
  114. return this.federatedTokenProvider.TargetAddress;
  115. }
  116. set
  117. {
  118. this.federatedTokenProvider.TargetAddress = value;
  119. }
  120. }
  121. public SecurityKeyEntropyMode KeyEntropyMode
  122. {
  123. get
  124. {
  125. return this.federatedTokenProvider.KeyEntropyMode;
  126. }
  127. set
  128. {
  129. this.federatedTokenProvider.KeyEntropyMode = value;
  130. }
  131. }
  132. public IdentityVerifier IdentityVerifier
  133. {
  134. get
  135. {
  136. return this.federatedTokenProvider.IdentityVerifier;
  137. }
  138. set
  139. {
  140. this.federatedTokenProvider.IdentityVerifier = value;
  141. }
  142. }
  143. public bool CacheIssuedTokens
  144. {
  145. get
  146. {
  147. return this.federatedTokenProvider.CacheServiceTokens;
  148. }
  149. set
  150. {
  151. this.federatedTokenProvider.CacheServiceTokens = value;
  152. }
  153. }
  154. public TimeSpan MaxIssuedTokenCachingTime
  155. {
  156. get
  157. {
  158. return this.federatedTokenProvider.MaxServiceTokenCachingTime;
  159. }
  160. set
  161. {
  162. this.federatedTokenProvider.MaxServiceTokenCachingTime = value;
  163. }
  164. }
  165. public MessageSecurityVersion MessageSecurityVersion
  166. {
  167. get
  168. {
  169. return this.messageSecurityVersion;
  170. }
  171. set
  172. {
  173. if (value == null)
  174. {
  175. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("value"));
  176. }
  177. this.messageSecurityVersion = value;
  178. }
  179. }
  180. public SecurityTokenSerializer SecurityTokenSerializer
  181. {
  182. get
  183. {
  184. return this.securityTokenSerializer;
  185. }
  186. set
  187. {
  188. this.securityTokenSerializer = value;
  189. }
  190. }
  191. public SecurityAlgorithmSuite SecurityAlgorithmSuite
  192. {
  193. get
  194. {
  195. return this.federatedTokenProvider.SecurityAlgorithmSuite;
  196. }
  197. set
  198. {
  199. this.federatedTokenProvider.SecurityAlgorithmSuite = value;
  200. }
  201. }
  202. public int IssuedTokenRenewalThresholdPercentage
  203. {
  204. get
  205. {
  206. return this.federatedTokenProvider.ServiceTokenValidityThresholdPercentage;
  207. }
  208. set
  209. {
  210. this.federatedTokenProvider.ServiceTokenValidityThresholdPercentage = value;
  211. }
  212. }
  213. public CommunicationState State
  214. {
  215. get { return this.federatedTokenProvider.State; }
  216. }
  217. public virtual TimeSpan DefaultOpenTimeout
  218. {
  219. get { return ServiceDefaults.OpenTimeout; }
  220. }
  221. public virtual TimeSpan DefaultCloseTimeout
  222. {
  223. get { return ServiceDefaults.CloseTimeout; }
  224. }
  225. public override bool SupportsTokenCancellation
  226. {
  227. get
  228. {
  229. return this.federatedTokenProvider.SupportsTokenCancellation;
  230. }
  231. }
  232. internal ChannelParameterCollection ChannelParameters
  233. {
  234. get
  235. {
  236. return this.federatedTokenProvider.ChannelParameters;
  237. }
  238. set
  239. {
  240. this.federatedTokenProvider.ChannelParameters = value;
  241. }
  242. }
  243. internal SecurityTokenHandlerCollectionManager TokenHandlerCollectionManager
  244. {
  245. get
  246. {
  247. return this.tokenHandlerCollectionManager;
  248. }
  249. set
  250. {
  251. this.tokenHandlerCollectionManager = value;
  252. }
  253. }
  254. // communication object methods
  255. public void Abort()
  256. {
  257. this.federatedTokenProvider.Abort();
  258. }
  259. public void Close()
  260. {
  261. this.federatedTokenProvider.Close();
  262. }
  263. public void Close(TimeSpan timeout)
  264. {
  265. this.federatedTokenProvider.Close(timeout);
  266. }
  267. public IAsyncResult BeginClose(AsyncCallback callback, object state)
  268. {
  269. return this.federatedTokenProvider.BeginClose(callback, state);
  270. }
  271. public IAsyncResult BeginClose(TimeSpan timeout, AsyncCallback callback, object state)
  272. {
  273. return this.federatedTokenProvider.BeginClose(timeout, callback, state);
  274. }
  275. public void EndClose(IAsyncResult result)
  276. {
  277. this.federatedTokenProvider.EndClose(result);
  278. }
  279. void OnOpenCore()
  280. {
  281. if (this.securityTokenSerializer == null)
  282. {
  283. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.TokenSerializerNotSetonFederationProvider)));
  284. }
  285. this.federatedTokenProvider.StandardsManager = new SecurityStandardsManager(this.messageSecurityVersion, this.securityTokenSerializer);
  286. }
  287. public void Open()
  288. {
  289. OnOpenCore();
  290. this.federatedTokenProvider.Open();
  291. }
  292. public void Open(TimeSpan timeout)
  293. {
  294. OnOpenCore();
  295. this.federatedTokenProvider.Open(timeout);
  296. }
  297. public IAsyncResult BeginOpen(AsyncCallback callback, object state)
  298. {
  299. OnOpenCore();
  300. return this.federatedTokenProvider.BeginOpen(callback, state);
  301. }
  302. public IAsyncResult BeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
  303. {
  304. OnOpenCore();
  305. return this.federatedTokenProvider.BeginOpen(timeout, callback, state);
  306. }
  307. public void EndOpen(IAsyncResult result)
  308. {
  309. this.federatedTokenProvider.EndOpen(result);
  310. }
  311. public void Dispose()
  312. {
  313. this.Close();
  314. }
  315. // token provider methods
  316. protected override IAsyncResult BeginGetTokenCore(TimeSpan timeout, AsyncCallback callback, object state)
  317. {
  318. return this.federatedTokenProvider.BeginGetToken(timeout, callback, state);
  319. }
  320. protected override SecurityToken GetTokenCore(TimeSpan timeout)
  321. {
  322. return this.federatedTokenProvider.GetToken(timeout);
  323. }
  324. protected override SecurityToken EndGetTokenCore(IAsyncResult result)
  325. {
  326. return this.federatedTokenProvider.EndGetToken(result);
  327. }
  328. internal void SetupActAsOnBehalfOfParameters(System.IdentityModel.Protocols.WSTrust.FederatedClientCredentialsParameters actAsOnBehalfOfParameters)
  329. {
  330. if (actAsOnBehalfOfParameters == null)
  331. return;
  332. if (actAsOnBehalfOfParameters.IssuedSecurityToken != null)
  333. {
  334. throw System.IdentityModel.DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.AuthFailed));
  335. }
  336. if (actAsOnBehalfOfParameters.OnBehalfOf != null)
  337. {
  338. if (MessageSecurityVersion.TrustVersion == TrustVersion.WSTrust13)
  339. {
  340. if (TokenRequestParameterExists(WSTrust13Constants.ElementNames.OnBehalfOf, WSTrust13Constants.NamespaceURI))
  341. {
  342. throw System.IdentityModel.DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.DuplicateFederatedClientCredentialsParameters, WSTrust13Constants.ElementNames.OnBehalfOf));
  343. }
  344. TokenRequestParameters.Add(CreateXmlTokenElement(actAsOnBehalfOfParameters.OnBehalfOf,
  345. WSTrust13Constants.Prefix,
  346. WSTrust13Constants.ElementNames.OnBehalfOf,
  347. WSTrust13Constants.NamespaceURI,
  348. SecurityTokenHandlerCollectionManager.Usage.OnBehalfOf));
  349. }
  350. else if (MessageSecurityVersion.TrustVersion == TrustVersion.WSTrustFeb2005)
  351. {
  352. if (TokenRequestParameterExists(WSTrustFeb2005Constants.ElementNames.OnBehalfOf, WSTrustFeb2005Constants.NamespaceURI))
  353. {
  354. throw System.IdentityModel.DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.DuplicateFederatedClientCredentialsParameters, WSTrustFeb2005Constants.ElementNames.OnBehalfOf));
  355. }
  356. TokenRequestParameters.Add(CreateXmlTokenElement(actAsOnBehalfOfParameters.OnBehalfOf,
  357. WSTrustFeb2005Constants.Prefix,
  358. WSTrustFeb2005Constants.ElementNames.OnBehalfOf,
  359. WSTrustFeb2005Constants.NamespaceURI,
  360. SecurityTokenHandlerCollectionManager.Usage.OnBehalfOf));
  361. }
  362. else
  363. {
  364. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.UnsupportedTrustVersion, MessageSecurityVersion.TrustVersion.Namespace)));
  365. }
  366. }
  367. if (actAsOnBehalfOfParameters.ActAs != null)
  368. {
  369. if (TokenRequestParameterExists(WSTrust14Constants.ElementNames.ActAs, WSTrust14Constants.NamespaceURI))
  370. {
  371. throw System.IdentityModel.DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.DuplicateFederatedClientCredentialsParameters, WSTrust14Constants.ElementNames.ActAs));
  372. }
  373. TokenRequestParameters.Add(CreateXmlTokenElement(actAsOnBehalfOfParameters.ActAs,
  374. WSTrust14Constants.Prefix,
  375. WSTrust14Constants.ElementNames.ActAs,
  376. WSTrust14Constants.NamespaceURI,
  377. SecurityTokenHandlerCollectionManager.Usage.ActAs));
  378. }
  379. }
  380. bool TokenRequestParameterExists(string localName, string xmlNamespace)
  381. {
  382. foreach (XmlElement element in TokenRequestParameters)
  383. {
  384. if (element.LocalName == localName &&
  385. element.NamespaceURI == xmlNamespace)
  386. {
  387. return true;
  388. }
  389. }
  390. return false;
  391. }
  392. XmlElement CreateXmlTokenElement(SecurityToken token, string prefix, string name, string ns, string usage)
  393. {
  394. Stream stream = new MemoryStream();
  395. using (XmlDictionaryWriter xmlWriter = XmlDictionaryWriter.CreateTextWriter(stream, Encoding.UTF8, false))
  396. {
  397. xmlWriter.WriteStartElement(prefix, name, ns);
  398. WriteToken(xmlWriter, token, usage);
  399. xmlWriter.WriteEndElement();
  400. xmlWriter.Flush();
  401. }
  402. stream.Seek(0, SeekOrigin.Begin);
  403. XmlDocument dom = new XmlDocument();
  404. dom.PreserveWhitespace = true;
  405. dom.Load(new XmlTextReader(stream) { DtdProcessing = DtdProcessing.Prohibit });
  406. stream.Close();
  407. return dom.DocumentElement;
  408. }
  409. void WriteToken(XmlWriter xmlWriter, SecurityToken token, string usage)
  410. {
  411. SecurityTokenHandlerCollection tokenHandlerCollection = null;
  412. if (this.tokenHandlerCollectionManager.ContainsKey(usage))
  413. {
  414. tokenHandlerCollection = this.tokenHandlerCollectionManager[usage];
  415. }
  416. else
  417. {
  418. tokenHandlerCollection = this.tokenHandlerCollectionManager[SecurityTokenHandlerCollectionManager.Usage.Default];
  419. }
  420. if (tokenHandlerCollection != null && tokenHandlerCollection.CanWriteToken(token))
  421. {
  422. tokenHandlerCollection.WriteToken(xmlWriter, token);
  423. }
  424. else
  425. {
  426. SecurityTokenSerializer.WriteToken(xmlWriter, token);
  427. }
  428. }
  429. private class CoreFederatedTokenProvider : IssuanceTokenProviderBase<FederatedTokenProviderState>
  430. {
  431. internal const SecurityKeyEntropyMode defaultKeyEntropyMode = SecurityKeyEntropyMode.CombinedEntropy;
  432. static int MaxRsaSecurityTokenCacheSize = 1024;
  433. IChannelFactory<IRequestChannel> channelFactory;
  434. Binding issuerBinding;
  435. KeyedByTypeCollection<IEndpointBehavior> channelBehaviors;
  436. Collection<XmlElement> requestProperties = new Collection<XmlElement>();
  437. IdentityVerifier identityVerifier = IdentityVerifier.CreateDefault();
  438. bool addTargetServiceAppliesTo;
  439. SecurityKeyEntropyMode keyEntropyMode;
  440. SecurityKeyType keyType;
  441. bool isKeyTypePresentInRstProperties;
  442. int keySize;
  443. bool isKeySizePresentInRstProperties;
  444. int defaultPublicKeySize = 1024;
  445. MessageVersion messageVersion;
  446. ChannelParameterCollection channelParameters;
  447. readonly List<RsaSecurityToken> rsaSecurityTokens = new List<RsaSecurityToken>();
  448. SafeFreeCredentials credentialsHandle;
  449. bool ownCredentialsHandle;
  450. public CoreFederatedTokenProvider(SafeFreeCredentials credentialsHandle) : base()
  451. {
  452. this.credentialsHandle = credentialsHandle;
  453. this.channelBehaviors = new KeyedByTypeCollection<IEndpointBehavior>();
  454. this.addTargetServiceAppliesTo = true;
  455. this.keyEntropyMode = defaultKeyEntropyMode;
  456. }
  457. public Binding IssuerBinding
  458. {
  459. get
  460. {
  461. return this.issuerBinding;
  462. }
  463. set
  464. {
  465. this.CommunicationObject.ThrowIfDisposedOrImmutable();
  466. this.issuerBinding = value;
  467. }
  468. }
  469. public Collection<XmlElement> RequestProperties
  470. {
  471. get
  472. {
  473. return this.requestProperties;
  474. }
  475. }
  476. public SecurityKeyEntropyMode KeyEntropyMode
  477. {
  478. get
  479. {
  480. return this.keyEntropyMode;
  481. }
  482. set
  483. {
  484. this.CommunicationObject.ThrowIfDisposedOrImmutable();
  485. SecurityKeyEntropyModeHelper.Validate(value);
  486. this.keyEntropyMode = value;
  487. }
  488. }
  489. public IdentityVerifier IdentityVerifier
  490. {
  491. get
  492. {
  493. return this.identityVerifier;
  494. }
  495. set
  496. {
  497. this.CommunicationObject.ThrowIfDisposedOrImmutable();
  498. this.identityVerifier = value;
  499. }
  500. }
  501. public ChannelParameterCollection ChannelParameters
  502. {
  503. get
  504. {
  505. return this.channelParameters;
  506. }
  507. set
  508. {
  509. this.CommunicationObject.ThrowIfDisposedOrImmutable();
  510. this.channelParameters = value;
  511. }
  512. }
  513. public KeyedByTypeCollection<IEndpointBehavior> IssuerChannelBehaviors
  514. {
  515. get
  516. {
  517. return this.channelBehaviors;
  518. }
  519. }
  520. public override XmlDictionaryString RequestSecurityTokenAction
  521. {
  522. get
  523. {
  524. return this.StandardsManager.TrustDriver.RequestSecurityTokenAction;
  525. }
  526. }
  527. public override XmlDictionaryString RequestSecurityTokenResponseAction
  528. {
  529. get
  530. {
  531. return this.StandardsManager.TrustDriver.RequestSecurityTokenResponseAction;
  532. }
  533. }
  534. protected override MessageVersion MessageVersion
  535. {
  536. get
  537. {
  538. return this.messageVersion;
  539. }
  540. }
  541. protected override bool RequiresManualReplyAddressing
  542. {
  543. get
  544. {
  545. // the proxy adds reply headers automatically
  546. return false;
  547. }
  548. }
  549. bool TryGetKeyType(out SecurityKeyType keyType)
  550. {
  551. if (this.requestProperties != null)
  552. {
  553. for (int i = 0; i < this.requestProperties.Count; ++i)
  554. {
  555. if (this.StandardsManager.TrustDriver.TryParseKeyTypeElement(this.requestProperties[i], out keyType))
  556. {
  557. return true;
  558. }
  559. }
  560. }
  561. keyType = SecurityKeyType.SymmetricKey;
  562. return false;
  563. }
  564. bool TryGetKeySize(out int keySize)
  565. {
  566. if (this.requestProperties != null)
  567. {
  568. for (int i = 0; i < this.requestProperties.Count; ++i)
  569. {
  570. if (this.StandardsManager.TrustDriver.TryParseKeySizeElement(this.requestProperties[i], out keySize))
  571. {
  572. return true;
  573. }
  574. }
  575. }
  576. keySize = 0;
  577. return false;
  578. }
  579. public override void OnOpen(TimeSpan timeout)
  580. {
  581. if (this.IssuerAddress == null)
  582. {
  583. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.StsAddressNotSet, this.TargetAddress)));
  584. }
  585. if (this.IssuerBinding == null)
  586. {
  587. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.StsBindingNotSet, this.IssuerAddress)));
  588. }
  589. if (this.SecurityAlgorithmSuite == null)
  590. {
  591. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SecurityAlgorithmSuiteNotSet, typeof(IssuedSecurityTokenProvider))));
  592. }
  593. this.channelFactory = this.StandardsManager.TrustDriver.CreateFederationProxy(this.IssuerAddress, this.IssuerBinding, this.IssuerChannelBehaviors);
  594. this.messageVersion = this.IssuerBinding.MessageVersion;
  595. // if an appliesTo is specified in the request properties, then do not add the target service EPR as
  596. // appliesTo
  597. for (int i = 0; i < this.requestProperties.Count; ++i)
  598. {
  599. if (this.StandardsManager.TrustDriver.IsAppliesTo(this.requestProperties[i].LocalName, this.requestProperties[i].NamespaceURI))
  600. {
  601. this.addTargetServiceAppliesTo = false;
  602. break;
  603. }
  604. }
  605. this.isKeyTypePresentInRstProperties = TryGetKeyType(out this.keyType);
  606. if (!this.isKeyTypePresentInRstProperties)
  607. {
  608. this.keyType = SecurityKeyType.SymmetricKey;
  609. }
  610. this.isKeySizePresentInRstProperties = TryGetKeySize(out this.keySize);
  611. if (!this.isKeySizePresentInRstProperties && this.keyType != SecurityKeyType.BearerKey)
  612. {
  613. this.keySize = (this.keyType == SecurityKeyType.SymmetricKey) ? this.SecurityAlgorithmSuite.DefaultSymmetricKeyLength : this.defaultPublicKeySize;
  614. }
  615. base.OnOpen(timeout);
  616. }
  617. public override void OnOpening()
  618. {
  619. base.OnOpening();
  620. if (this.credentialsHandle == null)
  621. {
  622. if (this.IssuerBinding == null)
  623. {
  624. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.StsBindingNotSet, this.IssuerAddress)));
  625. }
  626. this.credentialsHandle = SecurityUtils.GetCredentialsHandle(this.IssuerBinding, this.IssuerChannelBehaviors);
  627. this.ownCredentialsHandle = true;
  628. }
  629. }
  630. public override void OnAbort()
  631. {
  632. if (this.channelFactory != null && this.channelFactory.State == CommunicationState.Opened)
  633. {
  634. this.channelFactory.Abort();
  635. this.channelFactory = null;
  636. }
  637. CleanUpRsaSecurityTokenCache();
  638. FreeCredentialsHandle();
  639. base.OnAbort();
  640. }
  641. public override void OnClose(TimeSpan timeout)
  642. {
  643. TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
  644. if (this.channelFactory != null && this.channelFactory.State == CommunicationState.Opened)
  645. {
  646. this.channelFactory.Close(timeoutHelper.RemainingTime());
  647. this.channelFactory = null;
  648. CleanUpRsaSecurityTokenCache();
  649. FreeCredentialsHandle();
  650. base.OnClose(timeoutHelper.RemainingTime());
  651. }
  652. }
  653. void FreeCredentialsHandle()
  654. {
  655. if (this.credentialsHandle != null)
  656. {
  657. if (this.ownCredentialsHandle)
  658. {
  659. this.credentialsHandle.Close();
  660. }
  661. this.credentialsHandle = null;
  662. }
  663. }
  664. protected override bool WillInitializeChannelFactoriesCompleteSynchronously(EndpointAddress target)
  665. {
  666. return (this.channelFactory.State != CommunicationState.Opened);
  667. }
  668. protected override void InitializeChannelFactories(EndpointAddress target, TimeSpan timeout)
  669. {
  670. if (this.channelFactory.State == CommunicationState.Created)
  671. {
  672. this.channelFactory.Open(timeout);
  673. }
  674. }
  675. protected override IAsyncResult BeginInitializeChannelFactories(EndpointAddress target, TimeSpan timeout, AsyncCallback callback, object state)
  676. {
  677. if (this.channelFactory.State == CommunicationState.Created)
  678. {
  679. return this.channelFactory.BeginOpen(timeout, callback, state);
  680. }
  681. else
  682. {
  683. return new CompletedAsyncResult(callback, state);
  684. }
  685. }
  686. protected override void EndInitializeChannelFactories(IAsyncResult result)
  687. {
  688. if (result is CompletedAsyncResult)
  689. {
  690. CompletedAsyncResult.End(result);
  691. }
  692. else
  693. {
  694. this.channelFactory.EndOpen(result);
  695. }
  696. }
  697. protected override IRequestChannel CreateClientChannel(EndpointAddress target, Uri via)
  698. {
  699. IRequestChannel result = this.channelFactory.CreateChannel(this.IssuerAddress);
  700. if (this.channelParameters != null)
  701. {
  702. this.channelParameters.PropagateChannelParameters(result);
  703. }
  704. if (this.ownCredentialsHandle)
  705. {
  706. ChannelParameterCollection newParameters = result.GetProperty<ChannelParameterCollection>();
  707. if (newParameters != null)
  708. {
  709. newParameters.Add(new SspiIssuanceChannelParameter(true, this.credentialsHandle));
  710. }
  711. }
  712. ReplaceSspiIssuanceChannelParameter(result.GetProperty<ChannelParameterCollection>(), new SspiIssuanceChannelParameter(true, this.credentialsHandle));
  713. return result;
  714. }
  715. void ReplaceSspiIssuanceChannelParameter( ChannelParameterCollection channelParameters, SspiIssuanceChannelParameter sicp )
  716. {
  717. if (channelParameters != null)
  718. {
  719. for (int i = 0; i < channelParameters.Count; ++i)
  720. {
  721. if (channelParameters[i] is SspiIssuanceChannelParameter)
  722. {
  723. channelParameters.RemoveAt(i);
  724. }
  725. }
  726. channelParameters.Add(sicp);
  727. }
  728. }
  729. protected override bool CreateNegotiationStateCompletesSynchronously(EndpointAddress target, Uri via)
  730. {
  731. return true;
  732. }
  733. protected override IAsyncResult BeginCreateNegotiationState(EndpointAddress target, Uri via, TimeSpan timeout, AsyncCallback callback, object state)
  734. {
  735. return new CompletedAsyncResult<FederatedTokenProviderState>(this.CreateNegotiationState(target, via, timeout), callback, state);
  736. }
  737. protected override FederatedTokenProviderState EndCreateNegotiationState(IAsyncResult result)
  738. {
  739. return CompletedAsyncResult<FederatedTokenProviderState>.End(result);
  740. }
  741. protected override FederatedTokenProviderState CreateNegotiationState(EndpointAddress target, Uri via, TimeSpan timeout)
  742. {
  743. if ((this.keyType == SecurityKeyType.SymmetricKey) || (this.keyType == SecurityKeyType.BearerKey))
  744. {
  745. byte[] keyEntropy;
  746. if (this.KeyEntropyMode == SecurityKeyEntropyMode.CombinedEntropy || this.KeyEntropyMode == SecurityKeyEntropyMode.ClientEntropy)
  747. {
  748. keyEntropy = new byte[this.keySize / 8];
  749. CryptoHelper.FillRandomBytes(keyEntropy);
  750. }
  751. else
  752. {
  753. keyEntropy = null;
  754. }
  755. return new FederatedTokenProviderState(keyEntropy);
  756. }
  757. else if (this.keyType == SecurityKeyType.AsymmetricKey)
  758. {
  759. return new FederatedTokenProviderState(CreateAndCacheRsaSecurityToken());
  760. }
  761. else
  762. {
  763. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
  764. }
  765. }
  766. protected override BodyWriter GetFirstOutgoingMessageBody(FederatedTokenProviderState negotiationState, out MessageProperties messageProperties)
  767. {
  768. messageProperties = null;
  769. RequestSecurityToken rst = new RequestSecurityToken(this.StandardsManager);
  770. if (this.addTargetServiceAppliesTo)
  771. {
  772. if (this.MessageVersion.Addressing == AddressingVersion.WSAddressing10)
  773. {
  774. rst.SetAppliesTo<EndpointAddress10>(
  775. EndpointAddress10.FromEndpointAddress(negotiationState.TargetAddress),
  776. DataContractSerializerDefaults.CreateSerializer(typeof(EndpointAddress10), DataContractSerializerDefaults.MaxItemsInObjectGraph));
  777. }
  778. else if (this.MessageVersion.Addressing == AddressingVersion.WSAddressingAugust2004)
  779. {
  780. rst.SetAppliesTo<EndpointAddressAugust2004>(
  781. EndpointAddressAugust2004.FromEndpointAddress(negotiationState.TargetAddress),
  782. DataContractSerializerDefaults.CreateSerializer(typeof(EndpointAddressAugust2004), DataContractSerializerDefaults.MaxItemsInObjectGraph));
  783. }
  784. else
  785. {
  786. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
  787. new ProtocolException(SR.GetString(SR.AddressingVersionNotSupported, this.MessageVersion.Addressing)));
  788. }
  789. }
  790. rst.Context = negotiationState.Context;
  791. if (!this.isKeySizePresentInRstProperties)
  792. {
  793. rst.KeySize = this.keySize;
  794. }
  795. Collection<XmlElement> newRequestProperties = new Collection<XmlElement>();
  796. if (this.requestProperties != null)
  797. {
  798. for (int i = 0; i < this.requestProperties.Count; ++i)
  799. {
  800. newRequestProperties.Add(this.requestProperties[i]);
  801. }
  802. }
  803. if (!isKeyTypePresentInRstProperties)
  804. {
  805. XmlElement keyTypeElement = this.StandardsManager.TrustDriver.CreateKeyTypeElement(this.keyType);
  806. newRequestProperties.Insert(0, keyTypeElement);
  807. }
  808. if (this.keyType == SecurityKeyType.SymmetricKey)
  809. {
  810. byte[] requestorEntropy = negotiationState.GetRequestorEntropy();
  811. rst.SetRequestorEntropy(requestorEntropy);
  812. }
  813. else if (this.keyType == SecurityKeyType.AsymmetricKey)
  814. {
  815. RsaKeyIdentifierClause rsaClause = new RsaKeyIdentifierClause(negotiationState.Rsa);
  816. SecurityKeyIdentifier keyIdentifier = new SecurityKeyIdentifier(rsaClause);
  817. newRequestProperties.Add(this.StandardsManager.TrustDriver.CreateUseKeyElement(keyIdentifier, this.StandardsManager));
  818. RsaSecurityTokenParameters rsaParameters = new RsaSecurityTokenParameters();
  819. rsaParameters.InclusionMode = SecurityTokenInclusionMode.Never;
  820. rsaParameters.RequireDerivedKeys = false;
  821. SupportingTokenSpecification rsaSpec = new SupportingTokenSpecification(negotiationState.RsaSecurityToken, EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance, SecurityTokenAttachmentMode.Endorsing, rsaParameters);
  822. messageProperties = new MessageProperties();
  823. SecurityMessageProperty security = new SecurityMessageProperty();
  824. security.OutgoingSupportingTokens.Add(rsaSpec);
  825. messageProperties.Security = security;
  826. }
  827. if (this.keyType == SecurityKeyType.SymmetricKey && this.KeyEntropyMode == SecurityKeyEntropyMode.CombinedEntropy)
  828. {
  829. newRequestProperties.Add(this.StandardsManager.TrustDriver.CreateComputedKeyAlgorithmElement(this.StandardsManager.TrustDriver.ComputedKeyAlgorithm));
  830. }
  831. rst.RequestProperties = newRequestProperties;
  832. rst.MakeReadOnly();
  833. return rst;
  834. }
  835. protected ReadOnlyCollection<IAuthorizationPolicy> GetServiceAuthorizationPolicies(AcceleratedTokenProviderState negotiationState)
  836. {
  837. EndpointIdentity identity;
  838. if (this.identityVerifier.TryGetIdentity(negotiationState.TargetAddress, out identity))
  839. {
  840. List<Claim> claims = new List<Claim>(1);
  841. claims.Add(identity.IdentityClaim);
  842. List<IAuthorizationPolicy> policies = new List<IAuthorizationPolicy>(1);
  843. policies.Add(new UnconditionalPolicy(SecurityUtils.CreateIdentity(identity.IdentityClaim.Resource.ToString()),
  844. new DefaultClaimSet(ClaimSet.System, claims)));
  845. return policies.AsReadOnly();
  846. }
  847. else
  848. {
  849. return EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance;
  850. }
  851. }
  852. protected override BodyWriter GetNextOutgoingMessageBody(Message incomingMessage, FederatedTokenProviderState negotiationState)
  853. {
  854. ThrowIfFault(incomingMessage, this.IssuerAddress);
  855. if ((this.StandardsManager.MessageSecurityVersion.TrustVersion == TrustVersion.WSTrustFeb2005 && incomingMessage.Headers.Action != this.StandardsManager.TrustDriver.RequestSecurityTokenResponseAction.Value) ||
  856. (this.StandardsManager.MessageSecurityVersion.TrustVersion == TrustVersion.WSTrust13 && incomingMessage.Headers.Action != this.StandardsManager.TrustDriver.RequestSecurityTokenResponseFinalAction.Value) ||
  857. incomingMessage.Headers.Action == null)
  858. {
  859. throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.InvalidActionForNegotiationMessage, incomingMessage.Headers.Action)), incomingMessage);
  860. }
  861. RequestSecurityTokenResponse rstr = null;
  862. XmlDictionaryReader bodyReader = incomingMessage.GetReaderAtBodyContents();
  863. using (bodyReader)
  864. {
  865. if (this.StandardsManager.MessageSecurityVersion.TrustVersion == TrustVersion.WSTrustFeb2005)
  866. rstr = this.StandardsManager.TrustDriver.CreateRequestSecurityTokenResponse(bodyReader);
  867. else if (this.StandardsManager.MessageSecurityVersion.TrustVersion == TrustVersion.WSTrust13)
  868. {
  869. RequestSecurityTokenResponseCollection rstrc = this.StandardsManager.TrustDriver.CreateRequestSecurityTokenResponseCollection(bodyReader);
  870. foreach (RequestSecurityTokenResponse rstrItem in rstrc.RstrCollection)
  871. {
  872. if (rstr != null)
  873. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.MoreThanOneRSTRInRSTRC)));
  874. rstr = rstrItem;
  875. }
  876. }
  877. else
  878. {
  879. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
  880. }
  881. incomingMessage.ReadFromBodyContentsToEnd(bodyReader);
  882. }
  883. if (rstr.Context != negotiationState.Context)
  884. {
  885. throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.BadSecurityNegotiationContext)), incomingMessage);
  886. }
  887. GenericXmlSecurityToken serviceToken;
  888. if ((this.keyType == SecurityKeyType.SymmetricKey) ||
  889. (this.keyType == SecurityKeyType.BearerKey))
  890. {
  891. ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies = GetServiceAuthorizationPolicies(negotiationState);
  892. byte[] keyEntropy = negotiationState.GetRequestorEntropy();
  893. serviceToken = rstr.GetIssuedToken(null, null, this.KeyEntropyMode, keyEntropy, null, authorizationPolicies, this.keySize, this.keyType == SecurityKeyType.BearerKey);
  894. }
  895. else if (this.keyType == SecurityKeyType.AsymmetricKey)
  896. {
  897. serviceToken = rstr.GetIssuedToken(null, EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance, negotiationState.Rsa);
  898. }
  899. else
  900. {
  901. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
  902. }
  903. negotiationState.SetServiceToken(serviceToken);
  904. return null;
  905. }
  906. // SC/Trust workshop change to turn off context
  907. protected override bool IsMultiLegNegotiation
  908. {
  909. get { return false; }
  910. }
  911. // This is to address RSACryptoServiceProvider finalizer exception issue
  912. // Step 1. Create Rsa and force deterministic keypair gen in this calling context.
  913. // Step 2. Cache if the calling thread is under impersonation context. The cache will
  914. // be disposed on Close/Abort assuming same calling context thread as the one calling open.
  915. RsaSecurityToken CreateAndCacheRsaSecurityToken()
  916. {
  917. RsaSecurityToken token;
  918. // Cache only under impersonation context.
  919. // 1) set cacheSize less than 0, to ignore this new behavior at all.
  920. // 2) set cacheSize to 0, if token provider should not dispose issued tokens on close/abort.
  921. // 3) other than that, the token provider will track and dispose issued tokens as much.
  922. if (MaxRsaSecurityTokenCacheSize >= 0 && IsImpersonatedContext())
  923. {
  924. // This will force deterministic keypair gen in this context.
  925. token = RsaSecurityToken.CreateSafeRsaSecurityToken(this.keySize);
  926. if (MaxRsaSecurityTokenCacheSize > 0)
  927. {
  928. lock (this.rsaSecurityTokens)
  929. {
  930. // Remove/Dispose the first token if cache is full.
  931. // The first token (if not disposed) will rely on GC for finalization.
  932. if (this.rsaSecurityTokens.Count >= MaxRsaSecurityTokenCacheSize)
  933. {
  934. this.rsaSecurityTokens.RemoveAt(0);
  935. }
  936. this.rsaSecurityTokens.Add(token);
  937. }
  938. }
  939. }
  940. else
  941. {
  942. token = new RsaSecurityToken(new RSACryptoServiceProvider(this.keySize));
  943. }
  944. return token;
  945. }
  946. void CleanUpRsaSecurityTokenCache()
  947. {
  948. lock (this.rsaSecurityTokens)
  949. {
  950. for (int i = 0; i < this.rsaSecurityTokens.Count; ++i)
  951. {
  952. this.rsaSecurityTokens[i].Dispose();
  953. }
  954. this.rsaSecurityTokens.Clear();
  955. }
  956. }
  957. // This api simply check if the calling thread is process primary thread.
  958. // We are not trying to be smart if the impersonation to the same user as
  959. // process token since privileges could be different.
  960. bool IsImpersonatedContext()
  961. {
  962. SafeCloseHandle tokenHandle = null;
  963. if (!SafeNativeMethods.OpenCurrentThreadToken(
  964. SafeNativeMethods.GetCurrentThread(),
  965. TokenAccessLevels.Query,
  966. true,
  967. out tokenHandle))
  968. {
  969. int error = Marshal.GetLastWin32Error();
  970. Utility.CloseInvalidOutSafeHandle(tokenHandle);
  971. if (error == (int)Win32Error.ERROR_NO_TOKEN)
  972. {
  973. return false;
  974. }
  975. System.ServiceModel.Dispatcher.ErrorBehavior.ThrowAndCatch(new Win32Exception(error));
  976. return true;
  977. }
  978. tokenHandle.Close();
  979. return true;
  980. }
  981. protected override void ValidateKeySize(GenericXmlSecurityToken issuedToken)
  982. {
  983. if (this.keyType == SecurityKeyType.BearerKey)
  984. {
  985. // We do not have a proof key associated with bearer
  986. // key type. So skip key size validation.
  987. return;
  988. }
  989. base.ValidateKeySize(issuedToken);
  990. }
  991. }
  992. class FederatedTokenProviderState : AcceleratedTokenProviderState
  993. {
  994. RsaSecurityToken rsaToken;
  995. public FederatedTokenProviderState(byte[] entropy)
  996. : base(entropy)
  997. {
  998. }
  999. public FederatedTokenProviderState(RsaSecurityToken rsaToken)
  1000. : base(null)
  1001. {
  1002. this.rsaToken = rsaToken;
  1003. }
  1004. public RSA Rsa
  1005. {
  1006. get { return this.rsaToken.Rsa; }
  1007. }
  1008. public RsaSecurityToken RsaSecurityToken
  1009. {
  1010. get { return this.rsaToken; }
  1011. }
  1012. }
  1013. }
  1014. }