WSTrustFeb2005.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.ServiceModel.Security
  5. {
  6. using System;
  7. using System.ServiceModel;
  8. using System.ServiceModel.Description;
  9. using System.Collections;
  10. using System.Collections.Generic;
  11. using System.Collections.ObjectModel;
  12. using System.Diagnostics;
  13. using System.Globalization;
  14. using System.IO;
  15. using System.Text;
  16. using System.Threading;
  17. using System.Xml;
  18. using System.IdentityModel.Claims;
  19. using System.IdentityModel.Policy;
  20. using System.IdentityModel.Tokens;
  21. using System.Security.Cryptography.X509Certificates;
  22. using System.ServiceModel.Security.Tokens;
  23. using HexBinary = System.Runtime.Remoting.Metadata.W3cXsd2001.SoapHexBinary;
  24. using System.ServiceModel.Channels;
  25. using System.ServiceModel.Security;
  26. using System.Runtime.Serialization;
  27. using System.ServiceModel.Dispatcher;
  28. using KeyIdentifierEntry = WSSecurityTokenSerializer.KeyIdentifierEntry;
  29. using KeyIdentifierClauseEntry = WSSecurityTokenSerializer.KeyIdentifierClauseEntry;
  30. using TokenEntry = WSSecurityTokenSerializer.TokenEntry;
  31. using StrEntry = WSSecurityTokenSerializer.StrEntry;
  32. class WSTrustFeb2005 : WSTrust
  33. {
  34. public WSTrustFeb2005(WSSecurityTokenSerializer tokenSerializer)
  35. : base(tokenSerializer)
  36. {
  37. }
  38. public override TrustDictionary SerializerDictionary
  39. {
  40. get { return XD.TrustFeb2005Dictionary; }
  41. }
  42. public class DriverFeb2005 : Driver
  43. {
  44. public DriverFeb2005(SecurityStandardsManager standardsManager)
  45. : base(standardsManager)
  46. {
  47. }
  48. public override TrustDictionary DriverDictionary
  49. {
  50. get
  51. {
  52. return XD.TrustFeb2005Dictionary;
  53. }
  54. }
  55. public override XmlDictionaryString RequestSecurityTokenResponseFinalAction
  56. {
  57. get
  58. {
  59. return XD.TrustFeb2005Dictionary.RequestSecurityTokenIssuanceResponse;
  60. }
  61. }
  62. public override bool IsSessionSupported
  63. {
  64. get
  65. {
  66. return true;
  67. }
  68. }
  69. public override bool IsIssuedTokensSupported
  70. {
  71. get
  72. {
  73. return true;
  74. }
  75. }
  76. public override string IssuedTokensHeaderName
  77. {
  78. get
  79. {
  80. return this.DriverDictionary.IssuedTokensHeader.Value;
  81. }
  82. }
  83. public override string IssuedTokensHeaderNamespace
  84. {
  85. get
  86. {
  87. return this.DriverDictionary.Namespace.Value;
  88. }
  89. }
  90. public override string RequestTypeRenew
  91. {
  92. get
  93. {
  94. return this.DriverDictionary.RequestTypeRenew.Value;
  95. }
  96. }
  97. public override string RequestTypeClose
  98. {
  99. get
  100. {
  101. return this.DriverDictionary.RequestTypeClose.Value;
  102. }
  103. }
  104. public override Collection<XmlElement> ProcessUnknownRequestParameters(Collection<XmlElement> unknownRequestParameters, Collection<XmlElement> originalRequestParameters)
  105. {
  106. return unknownRequestParameters;
  107. }
  108. protected override void ReadReferences(XmlElement rstrXml, out SecurityKeyIdentifierClause requestedAttachedReference,
  109. out SecurityKeyIdentifierClause requestedUnattachedReference)
  110. {
  111. XmlElement issuedTokenXml = null;
  112. requestedAttachedReference = null;
  113. requestedUnattachedReference = null;
  114. for (int i = 0; i < rstrXml.ChildNodes.Count; ++i)
  115. {
  116. XmlElement child = rstrXml.ChildNodes[i] as XmlElement;
  117. if (child != null)
  118. {
  119. if (child.LocalName == this.DriverDictionary.RequestedSecurityToken.Value && child.NamespaceURI == this.DriverDictionary.Namespace.Value)
  120. {
  121. issuedTokenXml = XmlHelper.GetChildElement(child);
  122. }
  123. else if (child.LocalName == this.DriverDictionary.RequestedAttachedReference.Value && child.NamespaceURI == this.DriverDictionary.Namespace.Value)
  124. {
  125. requestedAttachedReference = GetKeyIdentifierXmlReferenceClause(XmlHelper.GetChildElement(child));
  126. }
  127. else if (child.LocalName == this.DriverDictionary.RequestedUnattachedReference.Value && child.NamespaceURI == this.DriverDictionary.Namespace.Value)
  128. {
  129. requestedUnattachedReference = GetKeyIdentifierXmlReferenceClause(XmlHelper.GetChildElement(child));
  130. }
  131. }
  132. }
  133. try
  134. {
  135. if (issuedTokenXml != null)
  136. {
  137. if (requestedAttachedReference == null)
  138. {
  139. this.StandardsManager.TryCreateKeyIdentifierClauseFromTokenXml(issuedTokenXml, SecurityTokenReferenceStyle.Internal, out requestedAttachedReference);
  140. }
  141. if (requestedUnattachedReference == null)
  142. {
  143. this.StandardsManager.TryCreateKeyIdentifierClauseFromTokenXml(issuedTokenXml, SecurityTokenReferenceStyle.External, out requestedUnattachedReference);
  144. }
  145. }
  146. }
  147. catch (XmlException)
  148. {
  149. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.TrustDriverIsUnableToCreatedNecessaryAttachedOrUnattachedReferences, issuedTokenXml.ToString())));
  150. }
  151. }
  152. protected override bool ReadRequestedTokenClosed(XmlElement rstrXml)
  153. {
  154. for (int i = 0; i < rstrXml.ChildNodes.Count; ++i)
  155. {
  156. XmlElement child = (rstrXml.ChildNodes[i] as XmlElement);
  157. if (child != null)
  158. {
  159. if (child.LocalName == this.DriverDictionary.RequestedTokenClosed.Value && child.NamespaceURI == this.DriverDictionary.Namespace.Value)
  160. {
  161. return true;
  162. }
  163. }
  164. }
  165. return false;
  166. }
  167. protected override void ReadTargets(XmlElement rstXml, out SecurityKeyIdentifierClause renewTarget, out SecurityKeyIdentifierClause closeTarget)
  168. {
  169. renewTarget = null;
  170. closeTarget = null;
  171. for (int i = 0; i < rstXml.ChildNodes.Count; ++i)
  172. {
  173. XmlElement child = (rstXml.ChildNodes[i] as XmlElement);
  174. if (child != null)
  175. {
  176. if (child.LocalName == this.DriverDictionary.RenewTarget.Value && child.NamespaceURI == this.DriverDictionary.Namespace.Value)
  177. renewTarget = this.StandardsManager.SecurityTokenSerializer.ReadKeyIdentifierClause(new XmlNodeReader(child.FirstChild));
  178. else if (child.LocalName == this.DriverDictionary.CloseTarget.Value && child.NamespaceURI == this.DriverDictionary.Namespace.Value)
  179. closeTarget = this.StandardsManager.SecurityTokenSerializer.ReadKeyIdentifierClause(new XmlNodeReader(child.FirstChild));
  180. }
  181. }
  182. }
  183. protected override void WriteReferences(RequestSecurityTokenResponse rstr, XmlDictionaryWriter writer)
  184. {
  185. if (rstr.RequestedAttachedReference != null)
  186. {
  187. writer.WriteStartElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.RequestedAttachedReference, this.DriverDictionary.Namespace);
  188. this.StandardsManager.SecurityTokenSerializer.WriteKeyIdentifierClause(writer, rstr.RequestedAttachedReference);
  189. writer.WriteEndElement();
  190. }
  191. if (rstr.RequestedUnattachedReference != null)
  192. {
  193. writer.WriteStartElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.RequestedUnattachedReference, this.DriverDictionary.Namespace);
  194. this.StandardsManager.SecurityTokenSerializer.WriteKeyIdentifierClause(writer, rstr.RequestedUnattachedReference);
  195. writer.WriteEndElement();
  196. }
  197. }
  198. protected override void WriteRequestedTokenClosed(RequestSecurityTokenResponse rstr, XmlDictionaryWriter writer)
  199. {
  200. if (rstr.IsRequestedTokenClosed)
  201. {
  202. writer.WriteElementString(this.DriverDictionary.RequestedTokenClosed, this.DriverDictionary.Namespace, String.Empty);
  203. }
  204. }
  205. protected override void WriteTargets(RequestSecurityToken rst, XmlDictionaryWriter writer)
  206. {
  207. if (rst.RenewTarget != null)
  208. {
  209. writer.WriteStartElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.RenewTarget, this.DriverDictionary.Namespace);
  210. this.StandardsManager.SecurityTokenSerializer.WriteKeyIdentifierClause(writer, rst.RenewTarget);
  211. writer.WriteEndElement();
  212. }
  213. if (rst.CloseTarget != null)
  214. {
  215. writer.WriteStartElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.CloseTarget, this.DriverDictionary.Namespace);
  216. this.StandardsManager.SecurityTokenSerializer.WriteKeyIdentifierClause(writer, rst.CloseTarget);
  217. writer.WriteEndElement();
  218. }
  219. }
  220. // this is now the abstract in WSTrust
  221. public override IChannelFactory<IRequestChannel> CreateFederationProxy(EndpointAddress address, Binding binding, KeyedByTypeCollection<IEndpointBehavior> channelBehaviors)
  222. {
  223. if (channelBehaviors == null)
  224. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("channelBehaviors");
  225. ChannelFactory<IWsTrustFeb2005SecurityTokenService> result = new ChannelFactory<IWsTrustFeb2005SecurityTokenService>(binding, address);
  226. SetProtectionLevelForFederation(result.Endpoint.Contract.Operations);
  227. // remove the default client credentials that gets added to channel factories
  228. result.Endpoint.Behaviors.Remove<ClientCredentials>();
  229. for (int i = 0; i < channelBehaviors.Count; ++i)
  230. {
  231. result.Endpoint.Behaviors.Add(channelBehaviors[i]);
  232. }
  233. // add a behavior that removes the UI channel initializer added by the client credentials since there should be no UI
  234. // initializer popped up as part of obtaining the federation token (the UI should already have been popped up for the main channel)
  235. result.Endpoint.Behaviors.Add(new InteractiveInitializersRemovingBehavior());
  236. return new RequestChannelFactory<IWsTrustFeb2005SecurityTokenService>(result);
  237. }
  238. [ServiceContract]
  239. internal interface IWsTrustFeb2005SecurityTokenService
  240. {
  241. [OperationContract(IsOneWay = false,
  242. Action = TrustFeb2005Strings.RequestSecurityTokenIssuance,
  243. ReplyAction = TrustFeb2005Strings.RequestSecurityTokenIssuanceResponse)]
  244. [FaultContract(typeof(string), Action = "*", ProtectionLevel = System.Net.Security.ProtectionLevel.Sign)]
  245. Message RequestToken(Message message);
  246. }
  247. public class InteractiveInitializersRemovingBehavior : IEndpointBehavior
  248. {
  249. public void Validate(ServiceEndpoint serviceEndpoint) { }
  250. public void AddBindingParameters(ServiceEndpoint serviceEndpoint, BindingParameterCollection bindingParameters) { }
  251. public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher) { }
  252. public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime behavior)
  253. {
  254. // it is very unlikely that InteractiveChannelInitializers will be null, this is defensive in case ClientRuntime every has a
  255. // bug. I am OK with this as ApplyingClientBehavior is a one-time channel setup.
  256. if (behavior != null && behavior.InteractiveChannelInitializers != null)
  257. {
  258. // clear away any interactive initializer
  259. behavior.InteractiveChannelInitializers.Clear();
  260. }
  261. }
  262. }
  263. public class RequestChannelFactory<TokenService> : ChannelFactoryBase, IChannelFactory<IRequestChannel>
  264. {
  265. ChannelFactory<TokenService> innerChannelFactory;
  266. public RequestChannelFactory(ChannelFactory<TokenService> innerChannelFactory)
  267. {
  268. this.innerChannelFactory = innerChannelFactory;
  269. }
  270. public IRequestChannel CreateChannel(EndpointAddress address)
  271. {
  272. return this.innerChannelFactory.CreateChannel<IRequestChannel>(address);
  273. }
  274. public IRequestChannel CreateChannel(EndpointAddress address, Uri via)
  275. {
  276. return this.innerChannelFactory.CreateChannel<IRequestChannel>(address, via);
  277. }
  278. protected override void OnAbort()
  279. {
  280. this.innerChannelFactory.Abort();
  281. }
  282. protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
  283. {
  284. return this.innerChannelFactory.BeginOpen(timeout, callback, state);
  285. }
  286. protected override void OnEndOpen(IAsyncResult result)
  287. {
  288. this.innerChannelFactory.EndOpen(result);
  289. }
  290. protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
  291. {
  292. return this.innerChannelFactory.BeginClose(timeout, callback, state);
  293. }
  294. protected override void OnEndClose(IAsyncResult result)
  295. {
  296. this.innerChannelFactory.EndClose(result);
  297. }
  298. protected override void OnClose(TimeSpan timeout)
  299. {
  300. this.innerChannelFactory.Close(timeout);
  301. }
  302. protected override void OnOpen(TimeSpan timeout)
  303. {
  304. this.innerChannelFactory.Open(timeout);
  305. }
  306. public override T GetProperty<T>()
  307. {
  308. return this.innerChannelFactory.GetProperty<T>();
  309. }
  310. }
  311. }
  312. }
  313. }