NegotiationTokenProvider.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel.Security
  5. {
  6. using System.Runtime;
  7. using System.ServiceModel;
  8. using System.ServiceModel.Channels;
  9. using System.ServiceModel.Description;
  10. using System.ServiceModel.Dispatcher;
  11. using System.Xml;
  12. // This is the base class for all token providers that negotiate an SCT from
  13. // the target service.
  14. abstract class NegotiationTokenProvider<T> : IssuanceTokenProviderBase<T>
  15. where T : IssuanceTokenProviderState
  16. {
  17. IChannelFactory<IRequestChannel> rstChannelFactory;
  18. bool requiresManualReplyAddressing;
  19. BindingContext issuanceBindingContext;
  20. MessageVersion messageVersion;
  21. protected NegotiationTokenProvider()
  22. : base()
  23. {
  24. }
  25. public BindingContext IssuerBindingContext
  26. {
  27. get { return this.issuanceBindingContext; }
  28. set
  29. {
  30. this.CommunicationObject.ThrowIfDisposedOrImmutable();
  31. if (value == null)
  32. {
  33. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
  34. }
  35. this.issuanceBindingContext = value.Clone();
  36. }
  37. }
  38. public override XmlDictionaryString RequestSecurityTokenAction
  39. {
  40. get
  41. {
  42. return this.StandardsManager.TrustDriver.RequestSecurityTokenAction;
  43. }
  44. }
  45. public override XmlDictionaryString RequestSecurityTokenResponseAction
  46. {
  47. get
  48. {
  49. return this.StandardsManager.TrustDriver.RequestSecurityTokenResponseAction;
  50. }
  51. }
  52. protected override MessageVersion MessageVersion
  53. {
  54. get
  55. {
  56. return this.messageVersion;
  57. }
  58. }
  59. protected override bool RequiresManualReplyAddressing
  60. {
  61. get
  62. {
  63. ThrowIfCreated();
  64. return this.requiresManualReplyAddressing;
  65. }
  66. }
  67. public override void OnClose(TimeSpan timeout)
  68. {
  69. TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
  70. if (this.rstChannelFactory != null)
  71. {
  72. this.rstChannelFactory.Close(timeout);
  73. this.rstChannelFactory = null;
  74. }
  75. base.OnClose(timeoutHelper.RemainingTime());
  76. }
  77. public override void OnAbort()
  78. {
  79. if (this.rstChannelFactory != null)
  80. {
  81. this.rstChannelFactory.Abort();
  82. this.rstChannelFactory = null;
  83. }
  84. base.OnAbort();
  85. }
  86. public override void OnOpen(TimeSpan timeout)
  87. {
  88. if (this.IssuerBindingContext == null)
  89. {
  90. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.IssuerBuildContextNotSet, this.GetType())));
  91. }
  92. TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
  93. this.SetupRstChannelFactory();
  94. this.rstChannelFactory.Open(timeout);
  95. base.OnOpen(timeoutHelper.RemainingTime());
  96. }
  97. protected abstract IChannelFactory<IRequestChannel> GetNegotiationChannelFactory(IChannelFactory<IRequestChannel> transportChannelFactory, ChannelBuilder channelBuilder);
  98. void SetupRstChannelFactory()
  99. {
  100. IChannelFactory<IRequestChannel> innerChannelFactory = null;
  101. ChannelBuilder channelBuilder = new ChannelBuilder(this.IssuerBindingContext.Clone(), true);
  102. // if the underlying transport does not support request/reply, wrap it inside
  103. // a service channel factory.
  104. if (channelBuilder.CanBuildChannelFactory<IRequestChannel>())
  105. {
  106. innerChannelFactory = channelBuilder.BuildChannelFactory<IRequestChannel>();
  107. this.requiresManualReplyAddressing = true;
  108. }
  109. else
  110. {
  111. ClientRuntime clientRuntime = new ClientRuntime("RequestSecurityTokenContract", NamingHelper.DefaultNamespace);
  112. clientRuntime.ValidateMustUnderstand = false;
  113. ServiceChannelFactory serviceChannelFactory = ServiceChannelFactory.BuildChannelFactory(channelBuilder, clientRuntime);
  114. serviceChannelFactory.ClientRuntime.UseSynchronizationContext = false;
  115. serviceChannelFactory.ClientRuntime.AddTransactionFlowProperties = false;
  116. ClientOperation rstOperation = new ClientOperation(serviceChannelFactory.ClientRuntime, "RequestSecurityToken", this.RequestSecurityTokenAction.Value);
  117. rstOperation.Formatter = MessageOperationFormatter.Instance;
  118. serviceChannelFactory.ClientRuntime.Operations.Add(rstOperation);
  119. if (this.IsMultiLegNegotiation)
  120. {
  121. ClientOperation rstrOperation = new ClientOperation(serviceChannelFactory.ClientRuntime, "RequestSecurityTokenResponse", this.RequestSecurityTokenResponseAction.Value);
  122. rstrOperation.Formatter = MessageOperationFormatter.Instance;
  123. serviceChannelFactory.ClientRuntime.Operations.Add(rstrOperation);
  124. }
  125. // service channel automatically adds reply headers
  126. this.requiresManualReplyAddressing = false;
  127. innerChannelFactory = new SecuritySessionSecurityTokenProvider.RequestChannelFactory(serviceChannelFactory);
  128. }
  129. this.rstChannelFactory = GetNegotiationChannelFactory(innerChannelFactory, channelBuilder);
  130. this.messageVersion = channelBuilder.Binding.MessageVersion;
  131. }
  132. // negotiation message processing overrides
  133. protected override bool WillInitializeChannelFactoriesCompleteSynchronously(EndpointAddress target)
  134. {
  135. return true;
  136. }
  137. protected override void InitializeChannelFactories(EndpointAddress target, TimeSpan timeout)
  138. {
  139. }
  140. protected override IAsyncResult BeginInitializeChannelFactories(EndpointAddress target, TimeSpan timeout, AsyncCallback callback, object state)
  141. {
  142. return new CompletedAsyncResult(callback, state);
  143. }
  144. protected override void EndInitializeChannelFactories(IAsyncResult result)
  145. {
  146. CompletedAsyncResult.End(result);
  147. }
  148. protected override IRequestChannel CreateClientChannel(EndpointAddress target, Uri via)
  149. {
  150. if (via != null)
  151. {
  152. return this.rstChannelFactory.CreateChannel(target, via);
  153. }
  154. else
  155. {
  156. return this.rstChannelFactory.CreateChannel(target);
  157. }
  158. }
  159. }
  160. }