5561ded581f42be01f7155a977f2814ad24523a5
[mono.git] / mcs / class / referencesource / System.ServiceModel / System / ServiceModel / Security / WSTrustServiceContract.cs
1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //------------------------------------------------------------
4
5 namespace System.ServiceModel.Security
6 {
7     using System;
8     using System.Collections;
9     using System.Collections.Generic;
10     using System.Diagnostics;
11     using System.IdentityModel;
12     using System.IdentityModel.Configuration;
13     using System.IdentityModel.Diagnostics;
14     using System.IdentityModel.Protocols.WSTrust;
15     using System.IdentityModel.Selectors;
16     using System.IdentityModel.Tokens;
17     using System.IO;
18     using System.Security.Claims;
19     using System.ServiceModel;
20     using System.ServiceModel.Activation;
21     using System.ServiceModel.Channels;
22     using System.ServiceModel.Description;
23     using System.Threading;
24     using System.Web.Services.Description;
25     using System.Xml;
26     using System.Xml.Schema;
27     using DiagnosticUtility = System.IdentityModel.DiagnosticUtility;
28     using Message = System.ServiceModel.Channels.Message;
29     using RequestContext = System.ServiceModel.Channels.RequestContext;
30     using RST = System.IdentityModel.Protocols.WSTrust.RequestSecurityToken;
31     using RSTR = System.IdentityModel.Protocols.WSTrust.RequestSecurityTokenResponse;
32     using SR = System.ServiceModel.SR;
33     using STS = System.IdentityModel.SecurityTokenService;
34     using Fx = System.Runtime.Fx;
35
36     /// <summary>
37     /// Definition of Trust Contract Implementation. Implements the following ServiceContract interfaces,
38     /// 1. IWSTrustFeb2005SyncContract
39     /// 2. IWSTrust13SyncContract
40     /// 3. IWSTrustFeb2005AsyncContract
41     /// 4. IWSTrust13AsyncContract
42     /// </summary>
43     [ServiceBehavior(Name = WSTrustServiceContractConstants.ServiceBehaviorName, Namespace = WSTrustServiceContractConstants.Namespace, InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
44     [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
45     public class WSTrustServiceContract : IWSTrustFeb2005SyncContract, IWSTrust13SyncContract, IWSTrustFeb2005AsyncContract, IWSTrust13AsyncContract, IWsdlExportExtension, IContractBehavior
46     {
47         const string soap11Namespace = "http://schemas.xmlsoap.org/soap/envelope/";
48         const string soap12Namespace = "http://www.w3.org/2003/05/soap-envelope";
49
50         SecurityTokenServiceConfiguration _securityTokenServiceConfiguration;
51
52         event EventHandler<WSTrustRequestProcessingErrorEventArgs> _requestFailed;
53
54         /// <summary>
55         /// Initializes an instance of <see cref="WSTrustServiceContract"/>
56         /// </summary>
57         /// <param name="securityTokenServiceConfiguration">Configuration object that initializes this instance.</param>
58         public WSTrustServiceContract(SecurityTokenServiceConfiguration securityTokenServiceConfiguration)
59         {
60             if (securityTokenServiceConfiguration == null)
61             {
62                 throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("securityTokenServiceConfiguration");
63             }
64
65             _securityTokenServiceConfiguration = securityTokenServiceConfiguration;
66         }
67
68         /// <summary>
69         /// Occurs when a Failure happens processing a Trust request from the 
70         /// client.
71         /// </summary>
72         public event EventHandler<WSTrustRequestProcessingErrorEventArgs> RequestFailed
73         {
74             add { _requestFailed += value; }
75             remove { _requestFailed -= value; }
76         }
77
78         /// <summary>
79         /// Returns the <see cref="SecurityTokenResolver" /> that resolves the following security tokens contained
80         /// in the current WCF message request's security header: protection token, endorsing, or signed endorsing
81         /// supporting tokens.
82         /// </summary>
83         /// <remarks>
84         /// This <see cref="SecurityTokenResolver" /> is used to resolve any SecurityTokenIdentifiers
85         /// when deserializing RST UseKey elements or RST RenewTarget elements.
86         /// </remarks>
87         /// <exception cref="ArgumentNullException"><param name="requestContext"/> is null.</exception>
88         protected virtual SecurityTokenResolver GetSecurityHeaderTokenResolver(RequestContext requestContext)
89         {
90             if (requestContext == null)
91             {
92                 throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("requestContext");
93             }
94
95             List<SecurityToken> tokenList = new List<SecurityToken>();
96             if (requestContext.RequestMessage != null
97                 && requestContext.RequestMessage.Properties != null
98                 && requestContext.RequestMessage.Properties.Security != null)
99             {
100                 // Add tokens in message
101                 SecurityMessageProperty msgProperty = requestContext.RequestMessage.Properties.Security;
102                 if (msgProperty.ProtectionToken != null)
103                 {
104                     tokenList.Add(msgProperty.ProtectionToken.SecurityToken);
105                 }
106                 if (msgProperty.HasIncomingSupportingTokens)
107                 {
108                     foreach (SupportingTokenSpecification tokenSpec in msgProperty.IncomingSupportingTokens)
109                     {
110                         if (tokenSpec != null &&
111                              (tokenSpec.SecurityTokenAttachmentMode == SecurityTokenAttachmentMode.Endorsing ||
112                                tokenSpec.SecurityTokenAttachmentMode == SecurityTokenAttachmentMode.SignedEndorsing))
113                         {
114                             tokenList.Add(tokenSpec.SecurityToken);
115                         }
116                     }
117                 }
118
119                 if (msgProperty.InitiatorToken != null)
120                 {
121                     tokenList.Add(msgProperty.InitiatorToken.SecurityToken);
122                 }
123             }
124
125             if (tokenList.Count > 0)
126             {
127                 return SecurityTokenResolver.CreateDefaultSecurityTokenResolver(tokenList.AsReadOnly(), true);
128             }
129             else
130             {
131                 return EmptySecurityTokenResolver.Instance;
132             }
133         }
134
135         /// <summary>
136         /// Returns the <see cref="SecurityTokenResolver" /> that will be used when resolving tokens and keys in the
137         /// Trust message body.
138         /// </summary>
139         /// <returns>A <see cref="SecurityTokenResolver" /> instance.</returns>
140         /// <seealso cref="GetSecurityHeaderTokenResolver"/>
141         protected virtual SecurityTokenResolver GetRstSecurityTokenResolver()
142         {
143             if (_securityTokenServiceConfiguration != null)
144             {
145                 SecurityTokenResolver tokenResolver = _securityTokenServiceConfiguration.SecurityTokenHandlers.Configuration.ServiceTokenResolver;
146
147                 if (tokenResolver != null && (!Object.ReferenceEquals(tokenResolver, EmptySecurityTokenResolver.Instance)))
148                 {
149                     return tokenResolver;
150                 }
151             }
152
153             if (OperationContext.Current != null && OperationContext.Current.Host != null &&
154                 OperationContext.Current.Host.Description != null)
155             {
156                 ServiceCredentials serviceCreds = OperationContext.Current.Host.Description.Behaviors.Find<ServiceCredentials>();
157                 if (serviceCreds != null && serviceCreds.ServiceCertificate != null && serviceCreds.ServiceCertificate.Certificate != null)
158                 {
159                     List<SecurityToken> serviceTokens = new List<SecurityToken>(1);
160                     serviceTokens.Add(new X509SecurityToken(serviceCreds.ServiceCertificate.Certificate));
161                     return SecurityTokenResolver.CreateDefaultSecurityTokenResolver(serviceTokens.AsReadOnly(), false);
162                 }
163             }
164
165             return EmptySecurityTokenResolver.Instance;
166         }
167
168         /// <summary>
169         /// Creates a WSTrustSerializationContext using the local resolver information 
170         /// of the WSTrustServiceClient.
171         /// </summary>
172         /// <returns>A WSTrustSerializationContext initialized with the current resolver information.</returns>
173         protected virtual WSTrustSerializationContext CreateSerializationContext()
174         {
175             return new WSTrustSerializationContext(_securityTokenServiceConfiguration.SecurityTokenHandlerCollectionManager,
176                                                    this.GetRstSecurityTokenResolver(),
177                                                    this.GetSecurityHeaderTokenResolver(OperationContext.Current.RequestContext)
178                                                    );
179
180         }
181
182         /// <summary>
183         /// Begins an asynchronous call to <see cref="DispatchRequest"/>.
184         /// </summary>
185         /// <param name="dispatchContext">Defines the request parameters to process and exposes properties
186         /// that determine the response message and action.</param>
187         /// <param name="asyncCallback">An optional asynchronous callback, to be called when the 
188         /// dispatch is complete.</param>
189         /// <param name="asyncState">A user-provided object that distinguishes this particular asynchronous 
190         /// dispatch request from other requests.</param>
191         /// <returns><see cref="IAsyncResult"/> that represents the asynchronous operation. Used as the input
192         /// to <see cref="EndDispatchRequest"/>.</returns>
193         protected virtual IAsyncResult BeginDispatchRequest(DispatchContext dispatchContext, AsyncCallback asyncCallback, object asyncState)
194         {
195             return new DispatchRequestAsyncResult(dispatchContext, asyncCallback, asyncState);
196         }
197
198         /// <summary>
199         /// Completes an asynchronous call to <see cref="DispatchRequest"/>.
200         /// </summary>
201         /// <param name="ar"><see cref="IAsyncResult"/> that was returned by the 
202         /// call to <see cref="BeginDispatchRequest"/>.</param>
203         /// <returns>The <see cref="DispatchContext"/> that exposes properties which determine the response
204         /// message and action.</returns>
205         protected virtual DispatchContext EndDispatchRequest(IAsyncResult ar)
206         {
207             return DispatchRequestAsyncResult.End(ar);
208         }
209
210         /// <summary>
211         /// Processes a WS-Trust request message, and optionally determines the appropriate
212         /// response message and the WS-Addressing action for the response message.
213         /// </summary>
214         /// <param name="dispatchContext">Defines the request parameters to process and exposes properties
215         /// that determine the response message and action.</param>
216         protected virtual void DispatchRequest(DispatchContext dispatchContext)
217         {
218             RST rst = dispatchContext.RequestMessage as RST;
219             STS sts = dispatchContext.SecurityTokenService;
220             ClaimsPrincipal icp = dispatchContext.Principal;
221
222             if (rst != null)
223             {
224                 switch (rst.RequestType)
225                 {
226                     case RequestTypes.Cancel:
227                         dispatchContext.ResponseMessage = sts.Cancel(icp, rst);
228                         break;
229                     case RequestTypes.Issue:
230                         dispatchContext.ResponseMessage = sts.Issue(icp, rst);
231                         break;
232                     case RequestTypes.Renew:
233                         dispatchContext.ResponseMessage = sts.Renew(icp, rst);
234                         break;
235                     case RequestTypes.Validate:
236                         dispatchContext.ResponseMessage = sts.Validate(icp, rst);
237                         break;
238                     default:
239                         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ID3112, rst.RequestType)));
240                 }
241             }
242             else
243             {
244                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidRequestException(SR.GetString(SR.ID3022)));
245             }
246         }
247
248         /// <summary>
249         /// Handles Synchronous calls to the STS.
250         /// </summary>
251         /// <param name="requestMessage">Incoming Request message.</param>
252         /// <param name="requestSerializer">Trust Request Serializer.</param>
253         /// <param name="responseSerializer">Trust Response Serializer.</param>
254         /// <param name="requestAction">Request SOAP action.</param>
255         /// <param name="responseAction">Response SOAP action.</param>
256         /// <param name="trustNamespace">Namespace URI of the trust version of the incoming request.</param>
257         /// <returns>Response message that contains the serialized RSTR.</returns>
258         /// <exception cref="ArgumentNullException">One of the argument is null.</exception>
259         protected virtual Message ProcessCore(Message requestMessage, WSTrustRequestSerializer requestSerializer, WSTrustResponseSerializer responseSerializer, string requestAction, string responseAction, string trustNamespace)
260         {
261             if (requestMessage == null)
262             {
263                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("requestMessage");
264             }
265
266             if (requestSerializer == null)
267             {
268                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("requestSerializer");
269             }
270
271             if (responseSerializer == null)
272             {
273                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("responseSerializer");
274             }
275
276             if (String.IsNullOrEmpty(requestAction))
277             {
278                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("requestAction");
279             }
280
281             if (String.IsNullOrEmpty(responseAction))
282             {
283                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("responseAction");
284             }
285
286             if (String.IsNullOrEmpty(trustNamespace))
287             {
288                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("trustNamespace");
289             }
290
291             Message response = null;
292             try
293             {
294                 Fx.Assert(OperationContext.Current != null, "");
295                 Fx.Assert(OperationContext.Current.RequestContext != null, "");
296
297                 //
298                 // Create the Serialization and Dispatch context objects.
299                 //
300                 WSTrustSerializationContext serializationContext = CreateSerializationContext();
301
302                 DispatchContext dispatchContext = CreateDispatchContext(requestMessage,
303                                                                          requestAction,
304                                                                          responseAction,
305                                                                          trustNamespace,
306                                                                          requestSerializer,
307                                                                          responseSerializer,
308                                                                          serializationContext);
309
310                 //
311                 // Validate the dispatch context.
312                 //
313                 ValidateDispatchContext(dispatchContext);
314
315                 //
316                 // Dispatch the STS message.
317                 //
318                 DispatchRequest(dispatchContext);
319
320                 //
321                 // Create the response Message object with the appropriate action.
322                 //
323                 response = Message.CreateMessage(OperationContext.Current.RequestContext.RequestMessage.Version,
324                                                   dispatchContext.ResponseAction,
325                                                   new WSTrustResponseBodyWriter(dispatchContext.ResponseMessage, responseSerializer, serializationContext));
326             }
327             catch (Exception ex)
328             {
329                 if (!HandleException(ex, trustNamespace, requestAction, requestMessage.Version.Envelope))
330                 {
331                     throw;
332                 }
333             }
334
335             return response;
336         }
337
338         /// <summary>
339         /// Creates a <see cref="DispatchContext"/> object for use by the <see cref="DispatchRequest"/> method.
340         /// </summary>
341         /// <param name="requestMessage">The incoming request message.</param>
342         /// <param name="requestAction">The SOAP action of the request.</param>
343         /// <param name="responseAction">The default SOAP action of the response.</param>
344         /// <param name="trustNamespace">Namespace URI of the trust version of the incoming request.</param>
345         /// <param name="requestSerializer">The <see cref="WSTrustRequestSerializer"/> used to deserialize 
346         /// incoming RST messages.</param>
347         /// <param name="responseSerializer">The <see cref="WSTrustResponseSerializer"/> used to deserialize 
348         /// incoming RSTR messages.</param>
349         /// <param name="serializationContext">The <see cref="WSTrustSerializationContext"/> to use 
350         /// when deserializing incoming messages.</param>
351         /// <returns>A <see cref="DispatchContext"/> object.</returns>
352         protected virtual DispatchContext CreateDispatchContext(Message requestMessage,
353                                                                  string requestAction,
354                                                                  string responseAction,
355                                                                  string trustNamespace,
356                                                                  WSTrustRequestSerializer requestSerializer,
357                                                                  WSTrustResponseSerializer responseSerializer,
358                                                                  WSTrustSerializationContext serializationContext)
359         {
360             DispatchContext dispatchContext = new DispatchContext()
361             {
362                 Principal = OperationContext.Current.ClaimsPrincipal as ClaimsPrincipal,
363                 RequestAction = requestAction,
364                 ResponseAction = responseAction,
365                 TrustNamespace = trustNamespace
366             };
367
368             XmlReader requestBodyReader = requestMessage.GetReaderAtBodyContents();
369             //
370             // Take a peek at the request with the serializers to figure out if this is a standard incoming
371             // RST or if this is an instance of a challenge-response style message pattern where an RSTR comes in.
372             //
373             if (requestSerializer.CanRead(requestBodyReader))
374             {
375                 dispatchContext.RequestMessage = requestSerializer.ReadXml(requestBodyReader, serializationContext);
376             }
377             else if (responseSerializer.CanRead(requestBodyReader))
378             {
379                 dispatchContext.RequestMessage = responseSerializer.ReadXml(requestBodyReader, serializationContext);
380             }
381             else
382             {
383                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
384                     new InvalidRequestException(SR.GetString(SR.ID3114)));
385             }
386
387             //
388             // CAUTION: Don't create the STS until after the RST or RSTR is deserialized or the test team
389             //          has major infrastructure problems.
390             //          
391             dispatchContext.SecurityTokenService = CreateSTS();
392             return dispatchContext;
393         }
394
395         /// <summary>
396         /// Validates the DispatchContext.
397         /// </summary>
398         /// <param name="dispatchContext">The <see cref="DispatchContext"/> to validate.</param>
399         /// <remarks>
400         /// This routine ensures that the <see cref="DispatchContext"/> represents a legal request
401         /// prior to being passed into <see cref="DispatchRequest"/>. This routine's default implementation
402         /// is to reject incoming RST messages with RSTR actions and vice versa.
403         /// </remarks>
404         protected virtual void ValidateDispatchContext(DispatchContext dispatchContext)
405         {
406             if (dispatchContext.RequestMessage is RST
407                  && !IsValidRSTAction(dispatchContext))
408             {
409                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
410                     new InvalidRequestException(
411                         SR.GetString(SR.ID3113, "RequestSecurityToken", dispatchContext.RequestAction)));
412             }
413
414             if (dispatchContext.RequestMessage is RSTR
415                  && !IsValidRSTRAction(dispatchContext))
416             {
417                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
418                     new InvalidRequestException(
419                         SR.GetString(SR.ID3113, "RequestSecurityTokenResponse", dispatchContext.RequestAction)));
420             }
421         }
422
423         /// <summary>
424         /// Determines if the DispatchContext contains a valid request action for incoming RST messages.
425         /// </summary>
426         private static bool IsValidRSTAction(DispatchContext dispatchContext)
427         {
428             bool valid = false;
429             string action = dispatchContext.RequestAction;
430
431             if (dispatchContext.TrustNamespace == WSTrust13Constants.NamespaceURI)
432             {
433                 switch (action)
434                 {
435                     case WSTrust13Constants.Actions.Cancel:
436                     case WSTrust13Constants.Actions.Issue:
437                     case WSTrust13Constants.Actions.Renew:
438                     case WSTrust13Constants.Actions.Validate:
439                         valid = true;
440                         break;
441                 }
442             }
443             if (dispatchContext.TrustNamespace == WSTrustFeb2005Constants.NamespaceURI)
444             {
445                 switch (action)
446                 {
447                     case WSTrustFeb2005Constants.Actions.Cancel:
448                     case WSTrustFeb2005Constants.Actions.Issue:
449                     case WSTrustFeb2005Constants.Actions.Renew:
450                     case WSTrustFeb2005Constants.Actions.Validate:
451                         valid = true;
452                         break;
453                 }
454             }
455
456             return valid;
457         }
458
459         /// <summary>
460         /// Determines if the DispatchContext contains a valid request action for incoming RSTR messages.
461         /// </summary>
462         private static bool IsValidRSTRAction(DispatchContext dispatchContext)
463         {
464             bool valid = false;
465             string action = dispatchContext.RequestAction;
466
467             if (dispatchContext.TrustNamespace == WSTrust13Constants.NamespaceURI)
468             {
469                 switch (action)
470                 {
471                     case WSTrust13Constants.Actions.CancelFinalResponse:
472                     case WSTrust13Constants.Actions.CancelResponse:
473                     case WSTrust13Constants.Actions.IssueFinalResponse:
474                     case WSTrust13Constants.Actions.IssueResponse:
475                     case WSTrust13Constants.Actions.RenewFinalResponse:
476                     case WSTrust13Constants.Actions.RenewResponse:
477                     case WSTrust13Constants.Actions.ValidateFinalResponse:
478                     case WSTrust13Constants.Actions.ValidateResponse:
479                         valid = true;
480                         break;
481                 }
482             }
483             if (dispatchContext.TrustNamespace == WSTrustFeb2005Constants.NamespaceURI)
484             {
485                 switch (action)
486                 {
487                     case WSTrustFeb2005Constants.Actions.CancelResponse:
488                     case WSTrustFeb2005Constants.Actions.IssueResponse:
489                     case WSTrustFeb2005Constants.Actions.RenewResponse:
490                     case WSTrustFeb2005Constants.Actions.ValidateResponse:
491                         valid = true;
492                         break;
493                 }
494             }
495
496             return valid;
497         }
498
499         private STS CreateSTS()
500         {
501             STS sts = _securityTokenServiceConfiguration.CreateSecurityTokenService();
502
503             if (sts == null)
504             {
505                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ID3002)));
506             }
507
508             return sts;
509         }
510
511         /// <summary>
512         /// Handles Asynchronous call to the STS.
513         /// </summary>
514         /// <param name="requestMessage">Incoming Request message.</param>
515         /// <param name="requestSerializer">Trust Request Serializer.</param>
516         /// <param name="responseSerializer">Trust Response Serializer.</param>
517         /// <param name="requestAction">Request SOAP action.</param>
518         /// <param name="responseAction">Response SOAP action.</param>
519         /// <param name="trustNamespace">Namespace URI of the trust version of the incoming request.</param>
520         /// <param name="callback">Callback that gets invoked when the Asynchronous call ends.</param>
521         /// <param name="state">state information of the Asynchronous call.</param>
522         /// <returns>IAsyncResult that should be passed back to the End method to complete the Asynchronous call.</returns>
523         /// <exception cref="ArgumentNullException">One of the argument is null.</exception>
524         protected virtual IAsyncResult BeginProcessCore(Message requestMessage, WSTrustRequestSerializer requestSerializer, WSTrustResponseSerializer responseSerializer, string requestAction, string responseAction, string trustNamespace, AsyncCallback callback, object state)
525         {
526             if (requestMessage == null)
527             {
528                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("request");
529             }
530
531             if (requestSerializer == null)
532             {
533                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("requestSerializer");
534             }
535
536             if (responseSerializer == null)
537             {
538                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("responseSerializer");
539             }
540
541             if (String.IsNullOrEmpty(requestAction))
542             {
543                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("requestAction");
544             }
545
546             if (String.IsNullOrEmpty(responseAction))
547             {
548                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("responseAction");
549             }
550
551             if (String.IsNullOrEmpty(trustNamespace))
552             {
553                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("trustNamespace");
554             }
555
556             IAsyncResult result = null;
557             try
558             {
559                 Fx.Assert(OperationContext.Current != null, "");
560                 Fx.Assert(OperationContext.Current.RequestContext != null, "");
561
562                 //
563                 // Create the Serialization and Dispatch context objects.
564                 //
565                 WSTrustSerializationContext serializationContext = CreateSerializationContext();
566
567                 DispatchContext dispatchContext = CreateDispatchContext(requestMessage,
568                                                                          requestAction,
569                                                                          responseAction,
570                                                                          trustNamespace,
571                                                                          requestSerializer,
572                                                                          responseSerializer,
573                                                                          serializationContext);
574
575                 //
576                 // Validate the dispatch context.
577                 //
578                 ValidateDispatchContext(dispatchContext);
579
580                 //
581                 // Dispatch the message asynchronously.
582                 //
583                 result = new ProcessCoreAsyncResult(this,
584                                                      dispatchContext,
585                                                      OperationContext.Current.RequestContext.RequestMessage.Version,
586                                                      responseSerializer,
587                                                      serializationContext,
588                                                      callback,
589                                                      state);
590             }
591             catch (Exception ex)
592             {
593                 if (!HandleException(ex, trustNamespace, requestAction, requestMessage.Version.Envelope))
594                 {
595                     throw;
596                 }
597             }
598
599             return result;
600         }
601
602         /// <summary>
603         /// Completes an Asynchronous call to the STS.
604         /// </summary>
605         /// <param name="ar">IAsyncResult that was returned by the call to the Asynchronous Begin method.</param>
606         /// <param name="requestAction">Request SOAP Action.</param>
607         /// <param name="responseAction">Response SOAP Action.</param>
608         /// <param name="trustNamespace">Namespace URI of the current trust version.</param>
609         /// <returns>Message that contains the serialized RST message.</returns>
610         /// <exception cref="ArgumentNullException">One of the argument is null.</exception>
611         protected virtual Message EndProcessCore(IAsyncResult ar, string requestAction, string responseAction, string trustNamespace)
612         {
613             if (ar == null)
614             {
615                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("ar");
616             }
617
618             ProcessCoreAsyncResult asyncResult = ar as ProcessCoreAsyncResult;
619             if (asyncResult == null)
620             {
621                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.ID2004, typeof(ProcessCoreAsyncResult), ar.GetType()), "ar"));
622             }
623
624             Message message = null;
625             try
626             {
627                 message = ProcessCoreAsyncResult.End(ar);
628             }
629             catch (Exception ex)
630             {
631                 if (!HandleException(ex, trustNamespace, requestAction, asyncResult.MessageVersion.Envelope))
632                 {
633                     throw;
634                 }
635             }
636
637             return message;
638         }
639
640         /// <summary>
641         /// Raises the Error Event and converts the given exception to a FaultException if required. If the original
642         /// exception was a FaultException or PreserveOriginalException flag is set to true then the conversion to 
643         /// FaultException is not done.
644         /// </summary>
645         /// <param name="ex">The original exception.</param>
646         /// <param name="trustNamespace">Trust Namespace of the current trust version.</param>
647         /// <param name="action">The Trust action that caused the exception.</param>
648         /// <param name="requestEnvelopeVersion">Version of the request envolope.</param>
649         protected virtual bool HandleException(Exception ex, string trustNamespace, string action, EnvelopeVersion requestEnvelopeVersion)
650         {
651             if (System.Runtime.Fx.IsFatal(ex))
652             {
653                 return false;
654             }
655
656             if (DiagnosticUtility.ShouldTrace(TraceEventType.Warning))
657             {
658                 TraceUtility.TraceString(
659                     TraceEventType.Warning,
660                     "RequestFailed: TrustNamespace={0}, Action={1}, Exception={2}",
661                     trustNamespace,
662                     action,
663                     ex);
664             }
665
666             // raise the exception events.
667             if (_requestFailed != null)
668             {
669                 _requestFailed(this, new WSTrustRequestProcessingErrorEventArgs(action, ex));
670             }
671
672             bool preserveOriginalException = false;
673             ServiceDebugBehavior debugBehavior = OperationContext.Current.Host.Description.Behaviors.Find<ServiceDebugBehavior>();
674             if (debugBehavior != null)
675             {
676                 preserveOriginalException = debugBehavior.IncludeExceptionDetailInFaults;
677             }
678
679             if (String.IsNullOrEmpty(trustNamespace) || String.IsNullOrEmpty(action) || preserveOriginalException || ex is FaultException)
680             {
681                 // Just throw the original exception.
682                 return false;
683             }
684             else
685             {
686                 FaultException faultException = OperationContext.Current.Host.Credentials.ExceptionMapper.FromException(ex, (requestEnvelopeVersion == EnvelopeVersion.Soap11) ? soap11Namespace : soap12Namespace, trustNamespace);
687                 if (faultException != null)
688                 {
689                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(faultException);
690                 }
691
692                 // The exception is not one of the recognized exceptions. Just throw the original exception.
693                 return false;
694             }
695         }
696
697         #region IWSTrustFeb2005SyncContract and IWSTrust13SyncContract Methods
698
699         /// <summary>
700         /// Processes a Trust 1.3 Cancel message synchronously.
701         /// </summary>
702         /// <param name="message">Incoming Request message.</param>
703         /// <returns>Message with the serialized response.</returns>
704         public Message ProcessTrust13Cancel(Message message)
705         {
706             return ProcessCore(message, _securityTokenServiceConfiguration.WSTrust13RequestSerializer, _securityTokenServiceConfiguration.WSTrust13ResponseSerializer, WSTrust13Constants.Actions.Cancel, WSTrust13Constants.Actions.CancelFinalResponse, WSTrust13Constants.NamespaceURI);
707         }
708
709         /// <summary>
710         /// Processes a Trust 1.3 Issue message synchronously.
711         /// </summary>
712         /// <param name="message">Incoming Request message.</param>
713         /// <returns>Message with the serialized response.</returns>
714         public Message ProcessTrust13Issue(Message message)
715         {
716             return ProcessCore(message, _securityTokenServiceConfiguration.WSTrust13RequestSerializer, _securityTokenServiceConfiguration.WSTrust13ResponseSerializer, WSTrust13Constants.Actions.Issue, WSTrust13Constants.Actions.IssueFinalResponse, WSTrust13Constants.NamespaceURI);
717         }
718
719         /// <summary>
720         /// Processes a Trust 1.3 Renew message synchronously.
721         /// </summary>
722         /// <param name="message">Incoming Request message.</param>
723         /// <returns>Message with the serialized response.</returns>
724         public Message ProcessTrust13Renew(Message message)
725         {
726             return ProcessCore(message, _securityTokenServiceConfiguration.WSTrust13RequestSerializer, _securityTokenServiceConfiguration.WSTrust13ResponseSerializer, WSTrust13Constants.Actions.Renew, WSTrust13Constants.Actions.RenewFinalResponse, WSTrust13Constants.NamespaceURI);
727         }
728
729         /// <summary>
730         /// Processes a Trust 1.3 Validate message synchronously.
731         /// </summary>
732         /// <param name="message">Incoming Request message.</param>
733         /// <returns>Message with the serialized response.</returns>
734         public Message ProcessTrust13Validate(Message message)
735         {
736             return ProcessCore(message, _securityTokenServiceConfiguration.WSTrust13RequestSerializer, _securityTokenServiceConfiguration.WSTrust13ResponseSerializer, WSTrust13Constants.Actions.Validate, WSTrust13Constants.Actions.ValidateFinalResponse, WSTrust13Constants.NamespaceURI);
737         }
738
739         /// <summary>
740         /// Processes a Trust 1.3 RSTR/Cancel message synchronously.
741         /// </summary>
742         /// <param name="message">Incoming Request message.</param>
743         /// <returns>Message with the serialized response.</returns>
744         public Message ProcessTrust13CancelResponse(Message message)
745         {
746             return ProcessCore(message,
747                                 _securityTokenServiceConfiguration.WSTrust13RequestSerializer,
748                                 _securityTokenServiceConfiguration.WSTrust13ResponseSerializer,
749                                 WSTrust13Constants.Actions.CancelResponse,
750                                 WSTrust13Constants.Actions.CancelFinalResponse,
751                                 WSTrust13Constants.NamespaceURI);
752         }
753
754         /// <summary>
755         /// Processes a Trust 1.3 RSTR/Issue message synchronously.
756         /// </summary>
757         /// <param name="message">Incoming Request message.</param>
758         /// <returns>Message with the serialized response.</returns>
759         public Message ProcessTrust13IssueResponse(Message message)
760         {
761             return ProcessCore(message,
762                                 _securityTokenServiceConfiguration.WSTrust13RequestSerializer,
763                                 _securityTokenServiceConfiguration.WSTrust13ResponseSerializer,
764                                 WSTrust13Constants.Actions.IssueResponse,
765                                 WSTrust13Constants.Actions.IssueFinalResponse,
766                                 WSTrust13Constants.NamespaceURI);
767         }
768
769         /// <summary>
770         /// Processes a Trust 1.3 RSTR/Renew message synchronously.
771         /// </summary>
772         /// <param name="message">Incoming Request message.</param>
773         /// <returns>Message with the serialized response.</returns>
774         public Message ProcessTrust13RenewResponse(Message message)
775         {
776             return ProcessCore(message,
777                                 _securityTokenServiceConfiguration.WSTrust13RequestSerializer,
778                                 _securityTokenServiceConfiguration.WSTrust13ResponseSerializer,
779                                 WSTrust13Constants.Actions.RenewResponse,
780                                 WSTrust13Constants.Actions.RenewFinalResponse,
781                                 WSTrust13Constants.NamespaceURI);
782         }
783
784         /// <summary>
785         /// Processes a Trust 1.3 RSTR/Validate message synchronously.
786         /// </summary>
787         /// <param name="message">Incoming Request message.</param>
788         /// <returns>Message with the serialized response.</returns>
789         public Message ProcessTrust13ValidateResponse(Message message)
790         {
791             return ProcessCore(message,
792                                 _securityTokenServiceConfiguration.WSTrust13RequestSerializer,
793                                 _securityTokenServiceConfiguration.WSTrust13ResponseSerializer,
794                                 WSTrust13Constants.Actions.ValidateResponse,
795                                 WSTrust13Constants.Actions.ValidateFinalResponse,
796                                 WSTrust13Constants.NamespaceURI);
797         }
798
799         /// <summary>
800         /// Processes a Trust Feb 2005 Cancel message synchronously.
801         /// </summary>
802         /// <param name="message">Incoming Request message.</param>
803         /// <returns>Message with the serialized response.</returns>
804         public Message ProcessTrustFeb2005Cancel(Message message)
805         {
806             return ProcessCore(message, _securityTokenServiceConfiguration.WSTrustFeb2005RequestSerializer, _securityTokenServiceConfiguration.WSTrustFeb2005ResponseSerializer, WSTrustFeb2005Constants.Actions.Cancel, WSTrustFeb2005Constants.Actions.CancelResponse, WSTrustFeb2005Constants.NamespaceURI);
807         }
808
809         /// <summary>
810         /// Processes a Trust Feb 2005 Issue message synchronously.
811         /// </summary>
812         /// <param name="message">Incoming Request message.</param>
813         /// <returns>Message with the serialized response.</returns>
814         public Message ProcessTrustFeb2005Issue(Message message)
815         {
816             return ProcessCore(message, _securityTokenServiceConfiguration.WSTrustFeb2005RequestSerializer, _securityTokenServiceConfiguration.WSTrustFeb2005ResponseSerializer, WSTrustFeb2005Constants.Actions.Issue, WSTrustFeb2005Constants.Actions.IssueResponse, WSTrustFeb2005Constants.NamespaceURI);
817         }
818
819         /// <summary>
820         /// Processes a Trust Feb 2005 Renew message synchronously.
821         /// </summary>
822         /// <param name="message">Incoming Request message.</param>
823         /// <returns>Message with the serialized response.</returns>
824         public Message ProcessTrustFeb2005Renew(Message message)
825         {
826             return ProcessCore(message, _securityTokenServiceConfiguration.WSTrustFeb2005RequestSerializer, _securityTokenServiceConfiguration.WSTrustFeb2005ResponseSerializer, WSTrustFeb2005Constants.Actions.Renew, WSTrustFeb2005Constants.Actions.RenewResponse, WSTrustFeb2005Constants.NamespaceURI);
827         }
828
829         /// <summary>
830         /// Processes a Trust Feb 2005 Validate message synchronously.
831         /// </summary>
832         /// <param name="message">Incoming Request message.</param>
833         /// <returns>Message with the serialized response.</returns>
834         public Message ProcessTrustFeb2005Validate(Message message)
835         {
836             return ProcessCore(message, _securityTokenServiceConfiguration.WSTrustFeb2005RequestSerializer, _securityTokenServiceConfiguration.WSTrustFeb2005ResponseSerializer, WSTrustFeb2005Constants.Actions.Validate, WSTrustFeb2005Constants.Actions.ValidateResponse, WSTrustFeb2005Constants.NamespaceURI);
837         }
838
839         /// <summary>
840         /// Processes a Trust Feb 2005 RSTR/Cancel message synchronously.
841         /// </summary>
842         /// <param name="message">Incoming Request message.</param>
843         /// <returns>Message with the serialized response.</returns>
844         public Message ProcessTrustFeb2005CancelResponse(Message message)
845         {
846             return ProcessCore(message,
847                                 _securityTokenServiceConfiguration.WSTrustFeb2005RequestSerializer,
848                                 _securityTokenServiceConfiguration.WSTrustFeb2005ResponseSerializer,
849                                 WSTrustFeb2005Constants.Actions.CancelResponse,
850                                 WSTrustFeb2005Constants.Actions.CancelResponse,
851                                 WSTrustFeb2005Constants.NamespaceURI);
852         }
853
854         /// <summary>
855         /// Processes a Trust Feb 2005 RSTR/Issue message synchronously.
856         /// </summary>
857         /// <param name="message">Incoming Request message.</param>
858         /// <returns>Message with the serialized response.</returns>
859         public Message ProcessTrustFeb2005IssueResponse(Message message)
860         {
861             return ProcessCore(message,
862                                 _securityTokenServiceConfiguration.WSTrustFeb2005RequestSerializer,
863                                 _securityTokenServiceConfiguration.WSTrustFeb2005ResponseSerializer,
864                                 WSTrustFeb2005Constants.Actions.IssueResponse,
865                                 WSTrustFeb2005Constants.Actions.IssueResponse,
866                                 WSTrustFeb2005Constants.NamespaceURI);
867         }
868
869         /// <summary>
870         /// Processes a Trust Feb 2005 RSTR/Renew message synchronously.
871         /// </summary>
872         /// <param name="message">Incoming Request message.</param>
873         /// <returns>Message with the serialized response.</returns>
874         public Message ProcessTrustFeb2005RenewResponse(Message message)
875         {
876             return ProcessCore(message,
877                                 _securityTokenServiceConfiguration.WSTrustFeb2005RequestSerializer,
878                                 _securityTokenServiceConfiguration.WSTrustFeb2005ResponseSerializer,
879                                 WSTrustFeb2005Constants.Actions.RenewResponse,
880                                 WSTrustFeb2005Constants.Actions.RenewResponse,
881                                 WSTrustFeb2005Constants.NamespaceURI);
882         }
883
884         /// <summary>
885         /// Processes a Trust Feb 2005 RSTR/Validate message synchronously.
886         /// </summary>
887         /// <param name="message">Incoming Request message.</param>
888         /// <returns>Message with the serialized response.</returns>
889         public Message ProcessTrustFeb2005ValidateResponse(Message message)
890         {
891             return ProcessCore(message,
892                                 _securityTokenServiceConfiguration.WSTrustFeb2005RequestSerializer,
893                                 _securityTokenServiceConfiguration.WSTrustFeb2005ResponseSerializer,
894                                 WSTrustFeb2005Constants.Actions.ValidateResponse,
895                                 WSTrustFeb2005Constants.Actions.ValidateResponse,
896                                 WSTrustFeb2005Constants.NamespaceURI);
897         }
898
899         /// <summary>
900         /// Gets the SecurityTokenServiceConfiguration
901         /// </summary>
902         public SecurityTokenServiceConfiguration SecurityTokenServiceConfiguration
903         {
904             get
905             {
906                 return _securityTokenServiceConfiguration;
907             }
908         }
909
910         #endregion
911
912         #region IWSTrustFeb2005AsyncContract and IWSTrust13AsyncContract  Methods
913
914         /// <summary>
915         /// Processes an Asynchronous call to Trust Feb 1.3 Cancel message.
916         /// </summary>
917         /// <param name="request">Incoming Request message.</param>
918         /// <param name="callback">Callback to be invoked when the Asynchronous operation ends.</param>
919         /// <param name="state">Asynchronous state.</param>
920         /// <returns>IAsyncResult that should be passed back to the End method to complete the Asynchronous call.</returns>
921         public IAsyncResult BeginTrust13Cancel(Message request, AsyncCallback callback, object state)
922         {
923             return BeginProcessCore(request, _securityTokenServiceConfiguration.WSTrust13RequestSerializer, _securityTokenServiceConfiguration.WSTrust13ResponseSerializer, WSTrust13Constants.Actions.Cancel, WSTrust13Constants.Actions.CancelFinalResponse, WSTrust13Constants.NamespaceURI, callback, state);
924         }
925
926         /// <summary>
927         /// Completes an Asynchronous call to Trust 1.3 Cancel message.
928         /// </summary>
929         /// <param name="ar">IAsyncResult object returned by the Begin method that started the Asynchronous call.</param>
930         /// <returns>Message containing the Serialized RSTR.</returns>
931         public Message EndTrust13Cancel(IAsyncResult ar)
932         {
933             return EndProcessCore(ar, WSTrust13Constants.Actions.Cancel, WSTrust13Constants.Actions.CancelFinalResponse, WSTrust13Constants.NamespaceURI);
934         }
935
936         /// <summary>
937         /// Processes an Asynchronous call to Trust 1.3 Issue message.
938         /// </summary>
939         /// <param name="request">Incoming Request message.</param>
940         /// <param name="callback">Callback to be invoked when the Asynchronous operation ends.</param>
941         /// <param name="state">Asynchronous state.</param>
942         /// <returns>IAsyncResult that should be passed back to the End method to complete the Asynchronous call.</returns>
943         public IAsyncResult BeginTrust13Issue(Message request, AsyncCallback callback, object state)
944         {
945             return BeginProcessCore(request, _securityTokenServiceConfiguration.WSTrust13RequestSerializer, _securityTokenServiceConfiguration.WSTrust13ResponseSerializer, WSTrust13Constants.Actions.Issue, WSTrust13Constants.Actions.IssueFinalResponse, WSTrust13Constants.NamespaceURI, callback, state);
946         }
947
948         /// <summary>
949         /// Completes an Asynchronous call to Trust 1.3 Issue message.
950         /// </summary>
951         /// <param name="ar">IAsyncResult object returned by the Begin method that started the Asynchronous call.</param>
952         /// <returns>Message containing the Serialized RSTR.</returns>
953         public Message EndTrust13Issue(IAsyncResult ar)
954         {
955             return EndProcessCore(ar, WSTrust13Constants.Actions.Issue, WSTrust13Constants.Actions.IssueFinalResponse, WSTrust13Constants.NamespaceURI);
956         }
957
958         /// <summary>
959         /// Processes an Asynchronous call to Trust 1.3 Renew message.
960         /// </summary>
961         /// <param name="request">Incoming Request message.</param>
962         /// <param name="callback">Callback to be invoked when the Asynchronous operation ends.</param>
963         /// <param name="state">Asynchronous state.</param>
964         /// <returns>IAsyncResult that should be passed back to the End method to complete the Asynchronous call.</returns>
965         public IAsyncResult BeginTrust13Renew(Message request, AsyncCallback callback, object state)
966         {
967             return BeginProcessCore(request, _securityTokenServiceConfiguration.WSTrust13RequestSerializer, _securityTokenServiceConfiguration.WSTrust13ResponseSerializer, WSTrust13Constants.Actions.Renew, WSTrust13Constants.Actions.RenewFinalResponse, WSTrust13Constants.NamespaceURI, callback, state);
968         }
969
970         /// <summary>
971         /// Completes an Asynchronous call to Trust 1.3 Renew message.
972         /// </summary>
973         /// <param name="ar">IAsyncResult object returned by the Begin method that started the Asynchronous call.</param>
974         /// <returns>Message containing the Serialized RSTR.</returns>
975         public Message EndTrust13Renew(IAsyncResult ar)
976         {
977             return EndProcessCore(ar, WSTrust13Constants.Actions.Renew, WSTrust13Constants.Actions.RenewFinalResponse, WSTrust13Constants.NamespaceURI);
978         }
979
980         /// <summary>
981         /// Processes an Asynchronous call to Trust 1.3 Validate message.
982         /// </summary>
983         /// <param name="request">Incoming Request message.</param>
984         /// <param name="callback">Callback to be invoked when the Asynchronous operation ends.</param>
985         /// <param name="state">Asynchronous state.</param>
986         /// <returns>IAsyncResult that should be passed back to the End method to complete the Asynchronous call.</returns>
987         public IAsyncResult BeginTrust13Validate(Message request, AsyncCallback callback, object state)
988         {
989             return BeginProcessCore(request, _securityTokenServiceConfiguration.WSTrust13RequestSerializer, _securityTokenServiceConfiguration.WSTrust13ResponseSerializer, WSTrust13Constants.Actions.Validate, WSTrust13Constants.Actions.ValidateFinalResponse, WSTrust13Constants.NamespaceURI, callback, state);
990         }
991
992         /// <summary>
993         /// Completes an Asynchronous call to Trust 1.3 Validate message.
994         /// </summary>
995         /// <param name="ar">IAsyncResult object returned by the Begin method that started the Asynchronous call.</param>
996         /// <returns>Message containing the Serialized RSTR.</returns>
997         public Message EndTrust13Validate(IAsyncResult ar)
998         {
999             return EndProcessCore(ar, WSTrust13Constants.Actions.Validate, WSTrust13Constants.Actions.ValidateFinalResponse, WSTrust13Constants.NamespaceURI);
1000         }
1001
1002         /// <summary>
1003         /// Processes an Asynchronous call to Trust 1.3 RSTR/Cancel message.
1004         /// </summary>
1005         /// <param name="request">Incoming Request message.</param>
1006         /// <param name="callback">Callback to be invoked when the Asynchronous operation ends.</param>
1007         /// <param name="state">Asynchronous state.</param>
1008         /// <returns>IAsyncResult that should be passed back to the End method to complete the Asynchronous call.</returns>
1009         public IAsyncResult BeginTrust13CancelResponse(Message request, AsyncCallback callback, object state)
1010         {
1011             return BeginProcessCore(request,
1012                                      _securityTokenServiceConfiguration.WSTrust13RequestSerializer,
1013                                      _securityTokenServiceConfiguration.WSTrust13ResponseSerializer,
1014                                      WSTrust13Constants.Actions.CancelResponse,
1015                                      WSTrust13Constants.Actions.CancelFinalResponse,
1016                                      WSTrust13Constants.NamespaceURI,
1017                                      callback,
1018                                      state);
1019         }
1020
1021         /// <summary>
1022         /// Completes an Asynchronous call to Trust 1.3 RSTR/Cancel message.
1023         /// </summary>
1024         /// <param name="ar">IAsyncResult object returned by the Begin method that started the Asynchronous call.</param>
1025         /// <returns>Message containing the Serialized RSTR.</returns>
1026         public Message EndTrust13CancelResponse(IAsyncResult ar)
1027         {
1028             return EndProcessCore(ar,
1029                                    WSTrust13Constants.Actions.CancelResponse,
1030                                    WSTrust13Constants.Actions.CancelFinalResponse,
1031                                    WSTrust13Constants.NamespaceURI);
1032         }
1033
1034         /// <summary>
1035         /// Processes an Asynchronous call to Trust 1.3 RSTR/Issue message.
1036         /// </summary>
1037         /// <param name="request">Incoming Request message.</param>
1038         /// <param name="callback">Callback to be invoked when the Asynchronous operation ends.</param>
1039         /// <param name="state">Asynchronous state.</param>
1040         /// <returns>IAsyncResult that should be passed back to the End method to complete the Asynchronous call.</returns>
1041         public IAsyncResult BeginTrust13IssueResponse(Message request, AsyncCallback callback, object state)
1042         {
1043             return BeginProcessCore(request,
1044                                      _securityTokenServiceConfiguration.WSTrust13RequestSerializer,
1045                                      _securityTokenServiceConfiguration.WSTrust13ResponseSerializer,
1046                                      WSTrust13Constants.Actions.IssueResponse,
1047                                      WSTrust13Constants.Actions.IssueFinalResponse,
1048                                      WSTrust13Constants.NamespaceURI,
1049                                      callback,
1050                                      state);
1051         }
1052
1053         /// <summary>
1054         /// Completes an Asynchronous call to Trust 1.3 RSTR/Issue message.
1055         /// </summary>
1056         /// <param name="ar">IAsyncResult object returned by the Begin method that started the Asynchronous call.</param>
1057         /// <returns>Message containing the Serialized RSTR.</returns>
1058         public Message EndTrust13IssueResponse(IAsyncResult ar)
1059         {
1060             return EndProcessCore(ar,
1061                                    WSTrust13Constants.Actions.IssueResponse,
1062                                    WSTrust13Constants.Actions.IssueFinalResponse,
1063                                    WSTrust13Constants.NamespaceURI);
1064         }
1065
1066         /// <summary>
1067         /// Processes an Asynchronous call to Trust 1.3 RSTR/Renew message.
1068         /// </summary>
1069         /// <param name="request">Incoming Request message.</param>
1070         /// <param name="callback">Callback to be invoked when the Asynchronous operation ends.</param>
1071         /// <param name="state">Asynchronous state.</param>
1072         /// <returns>IAsyncResult that should be passed back to the End method to complete the Asynchronous call.</returns>
1073         public IAsyncResult BeginTrust13RenewResponse(Message request, AsyncCallback callback, object state)
1074         {
1075             return BeginProcessCore(request,
1076                                      _securityTokenServiceConfiguration.WSTrust13RequestSerializer,
1077                                      _securityTokenServiceConfiguration.WSTrust13ResponseSerializer,
1078                                      WSTrust13Constants.Actions.RenewResponse,
1079                                      WSTrust13Constants.Actions.RenewFinalResponse,
1080                                      WSTrust13Constants.NamespaceURI,
1081                                      callback,
1082                                      state);
1083         }
1084
1085         /// <summary>
1086         /// Completes an Asynchronous call to Trust 1.3 RSTR/Renew message.
1087         /// </summary>
1088         /// <param name="ar">IAsyncResult object returned by the Begin method that started the Asynchronous call.</param>
1089         /// <returns>Message containing the Serialized RSTR.</returns>
1090         public Message EndTrust13RenewResponse(IAsyncResult ar)
1091         {
1092             return EndProcessCore(ar,
1093                                    WSTrust13Constants.Actions.RenewResponse,
1094                                    WSTrust13Constants.Actions.RenewFinalResponse,
1095                                    WSTrust13Constants.NamespaceURI);
1096         }
1097
1098         /// <summary>
1099         /// Processes an Asynchronous call to Trust 1.3 RSTR/Validate message.
1100         /// </summary>
1101         /// <param name="request">Incoming Request message.</param>
1102         /// <param name="callback">Callback to be invoked when the Asynchronous operation ends.</param>
1103         /// <param name="state">Asynchronous state.</param>
1104         /// <returns>IAsyncResult that should be passed back to the End method to complete the Asynchronous call.</returns>
1105         public IAsyncResult BeginTrust13ValidateResponse(Message request, AsyncCallback callback, object state)
1106         {
1107             return BeginProcessCore(request,
1108                                      _securityTokenServiceConfiguration.WSTrust13RequestSerializer,
1109                                      _securityTokenServiceConfiguration.WSTrust13ResponseSerializer,
1110                                      WSTrust13Constants.Actions.ValidateResponse,
1111                                      WSTrust13Constants.Actions.ValidateFinalResponse,
1112                                      WSTrust13Constants.NamespaceURI,
1113                                      callback,
1114                                      state);
1115         }
1116
1117         /// <summary>
1118         /// Completes an Asynchronous call to Trust 1.3 RSTR/Validate message.
1119         /// </summary>
1120         /// <param name="ar">IAsyncResult object returned by the Begin method that started the Asynchronous call.</param>
1121         /// <returns>Message containing the Serialized RSTR.</returns>
1122         public Message EndTrust13ValidateResponse(IAsyncResult ar)
1123         {
1124             return EndProcessCore(ar,
1125                                    WSTrust13Constants.Actions.ValidateResponse,
1126                                    WSTrust13Constants.Actions.ValidateFinalResponse,
1127                                    WSTrust13Constants.NamespaceURI);
1128         }
1129
1130         /// <summary>
1131         /// Processes an Asynchronous call to Trust 2005 Cancel message.
1132         /// </summary>
1133         /// <param name="request">Incoming Request message.</param>
1134         /// <param name="callback">Callback to be invoked when the Asynchronous operation ends.</param>
1135         /// <param name="state">Asynchronous state.</param>
1136         /// <returns>IAsyncResult that should be passed back to the End method to complete the Asynchronous call.</returns>
1137         public IAsyncResult BeginTrustFeb2005Cancel(Message request, AsyncCallback callback, object state)
1138         {
1139             return BeginProcessCore(request, _securityTokenServiceConfiguration.WSTrustFeb2005RequestSerializer, _securityTokenServiceConfiguration.WSTrustFeb2005ResponseSerializer, WSTrustFeb2005Constants.Actions.Cancel, WSTrustFeb2005Constants.Actions.CancelResponse, WSTrustFeb2005Constants.NamespaceURI, callback, state);
1140         }
1141
1142         /// <summary>
1143         /// Completes an Asynchronous call to Trust Feb 2005 Cancel message.
1144         /// </summary>
1145         /// <param name="ar">IAsyncResult object returned by the Begin method that started the Asynchronous call.</param>
1146         /// <returns>Message containing the Serialized RSTR.</returns>
1147         public Message EndTrustFeb2005Cancel(IAsyncResult ar)
1148         {
1149             return EndProcessCore(ar, WSTrustFeb2005Constants.Actions.Cancel, WSTrustFeb2005Constants.Actions.CancelResponse, WSTrustFeb2005Constants.NamespaceURI);
1150         }
1151
1152         /// <summary>
1153         /// Processes an Asynchronous call to Trust Feb 2005 Issue message.
1154         /// </summary>
1155         /// <param name="request">Incoming Request message.</param>
1156         /// <param name="callback">Callback to be invoked when the Asynchronous operation ends.</param>
1157         /// <param name="state">Asynchronous state.</param>
1158         /// <returns>IAsyncResult that should be passed back to the End method to complete the Asynchronous call.</returns>
1159         public IAsyncResult BeginTrustFeb2005Issue(Message request, AsyncCallback callback, object state)
1160         {
1161             return BeginProcessCore(request, _securityTokenServiceConfiguration.WSTrustFeb2005RequestSerializer, _securityTokenServiceConfiguration.WSTrustFeb2005ResponseSerializer, WSTrustFeb2005Constants.Actions.Issue, WSTrustFeb2005Constants.Actions.IssueResponse, WSTrustFeb2005Constants.NamespaceURI, callback, state);
1162         }
1163
1164         /// <summary>
1165         /// Completes an Asynchronous call to Trust Feb 2005 Issue message.
1166         /// </summary>
1167         /// <param name="ar">IAsyncResult object returned by the Begin method that started the Asynchronous call.</param>
1168         /// <returns>Message containing the Serialized RSTR.</returns>
1169         public Message EndTrustFeb2005Issue(IAsyncResult ar)
1170         {
1171             return EndProcessCore(ar, WSTrustFeb2005Constants.Actions.Issue, WSTrustFeb2005Constants.Actions.IssueResponse, WSTrustFeb2005Constants.NamespaceURI);
1172         }
1173
1174         /// <summary>
1175         /// Processes an Asynchronous call to Trust Feb 2005 Renew message.
1176         /// </summary>
1177         /// <param name="request">Incoming Request message.</param>
1178         /// <param name="callback">Callback to be invoked when the Asynchronous operation ends.</param>
1179         /// <param name="state">Asynchronous state.</param>
1180         /// <returns>IAsyncResult that should be passed back to the End method to complete the Asynchronous call.</returns>
1181         public IAsyncResult BeginTrustFeb2005Renew(Message request, AsyncCallback callback, object state)
1182         {
1183             return BeginProcessCore(request, _securityTokenServiceConfiguration.WSTrustFeb2005RequestSerializer, _securityTokenServiceConfiguration.WSTrustFeb2005ResponseSerializer, WSTrustFeb2005Constants.Actions.Renew, WSTrustFeb2005Constants.Actions.RenewResponse, WSTrustFeb2005Constants.NamespaceURI, callback, state);
1184         }
1185
1186         /// <summary>
1187         /// Completes an Asynchronous call to Trust Feb 2005 Renew message.
1188         /// </summary>
1189         /// <param name="ar">IAsyncResult object returned by the Begin method that started the Asynchronous call.</param>
1190         /// <returns>Message containing the Serialized RSTR.</returns>
1191         public Message EndTrustFeb2005Renew(IAsyncResult ar)
1192         {
1193             return EndProcessCore(ar, WSTrustFeb2005Constants.Actions.Renew, WSTrustFeb2005Constants.Actions.RenewResponse, WSTrustFeb2005Constants.NamespaceURI);
1194         }
1195
1196         /// <summary>
1197         /// Processes an Asynchronous call to Trust Feb 2005 Validate message.
1198         /// </summary>
1199         /// <param name="request">Incoming Request message.</param>
1200         /// <param name="callback">Callback to be invoked when the Asynchronous operation ends.</param>
1201         /// <param name="state">Asynchronous state.</param>
1202         /// <returns>IAsyncResult that should be passed back to the End method to complete the Asynchronous call.</returns>
1203         public IAsyncResult BeginTrustFeb2005Validate(Message request, AsyncCallback callback, object state)
1204         {
1205             return BeginProcessCore(request, _securityTokenServiceConfiguration.WSTrustFeb2005RequestSerializer, _securityTokenServiceConfiguration.WSTrustFeb2005ResponseSerializer, WSTrustFeb2005Constants.Actions.Validate, WSTrustFeb2005Constants.Actions.ValidateResponse, WSTrustFeb2005Constants.NamespaceURI, callback, state);
1206         }
1207
1208         /// <summary>
1209         /// Completes an Asynchronous call to Trust Feb 2005 Validate message.
1210         /// </summary>
1211         /// <param name="ar">IAsyncResult object returned by the Begin method that started the Asynchronous call.</param>
1212         /// <returns>Message containing the Serialized RSTR.</returns>
1213         public Message EndTrustFeb2005Validate(IAsyncResult ar)
1214         {
1215             return EndProcessCore(ar, WSTrustFeb2005Constants.Actions.Validate, WSTrustFeb2005Constants.Actions.ValidateResponse, WSTrustFeb2005Constants.NamespaceURI);
1216         }
1217
1218         /// <summary>
1219         /// Processes an Asynchronous call to Trust Feb 2005 RSTR/Cancel message.
1220         /// </summary>
1221         /// <param name="request">Incoming Request message.</param>
1222         /// <param name="callback">Callback to be invoked when the Asynchronous operation ends.</param>
1223         /// <param name="state">Asynchronous state.</param>
1224         /// <returns>IAsyncResult that should be passed back to the End method to complete the Asynchronous call.</returns>
1225         public IAsyncResult BeginTrustFeb2005CancelResponse(Message request, AsyncCallback callback, object state)
1226         {
1227             return BeginProcessCore(request,
1228                                      _securityTokenServiceConfiguration.WSTrustFeb2005RequestSerializer,
1229                                      _securityTokenServiceConfiguration.WSTrustFeb2005ResponseSerializer,
1230                                      WSTrustFeb2005Constants.Actions.CancelResponse,
1231                                      WSTrustFeb2005Constants.Actions.CancelResponse,
1232                                      WSTrustFeb2005Constants.NamespaceURI,
1233                                      callback,
1234                                      state);
1235         }
1236
1237         /// <summary>
1238         /// Completes an Asynchronous call to Trust Feb 2005 RSTR/Cancel message.
1239         /// </summary>
1240         /// <param name="ar">IAsyncResult object returned by the Begin method that started the Asynchronous call.</param>
1241         /// <returns>Message containing the Serialized RSTR.</returns>
1242         public Message EndTrustFeb2005CancelResponse(IAsyncResult ar)
1243         {
1244             return EndProcessCore(ar,
1245                                    WSTrustFeb2005Constants.Actions.CancelResponse,
1246                                    WSTrustFeb2005Constants.Actions.CancelResponse,
1247                                    WSTrustFeb2005Constants.NamespaceURI);
1248         }
1249
1250         /// <summary>
1251         /// Processes an Asynchronous call to Trust Feb 2005 RSTR/Issue message.
1252         /// </summary>
1253         /// <param name="request">Incoming Request message.</param>
1254         /// <param name="callback">Callback to be invoked when the Asynchronous operation ends.</param>
1255         /// <param name="state">Asynchronous state.</param>
1256         /// <returns>IAsyncResult that should be passed back to the End method to complete the Asynchronous call.</returns>
1257         public IAsyncResult BeginTrustFeb2005IssueResponse(Message request, AsyncCallback callback, object state)
1258         {
1259             return BeginProcessCore(request,
1260                                      _securityTokenServiceConfiguration.WSTrustFeb2005RequestSerializer,
1261                                      _securityTokenServiceConfiguration.WSTrustFeb2005ResponseSerializer,
1262                                      WSTrustFeb2005Constants.Actions.IssueResponse,
1263                                      WSTrustFeb2005Constants.Actions.IssueResponse,
1264                                      WSTrustFeb2005Constants.NamespaceURI,
1265                                      callback,
1266                                      state);
1267         }
1268
1269         /// <summary>
1270         /// Completes an Asynchronous call to Trust Feb 2005 RSTR/Issue message.
1271         /// </summary>
1272         /// <param name="ar">IAsyncResult object returned by the Begin method that started the Asynchronous call.</param>
1273         /// <returns>Message containing the Serialized RSTR.</returns>
1274         public Message EndTrustFeb2005IssueResponse(IAsyncResult ar)
1275         {
1276             return EndProcessCore(ar,
1277                                    WSTrustFeb2005Constants.Actions.IssueResponse,
1278                                    WSTrustFeb2005Constants.Actions.IssueResponse,
1279                                    WSTrustFeb2005Constants.NamespaceURI);
1280         }
1281
1282         /// <summary>
1283         /// Processes an Asynchronous call to Trust Feb 2005 RSTR/Renew message.
1284         /// </summary>
1285         /// <param name="request">Incoming Request message.</param>
1286         /// <param name="callback">Callback to be invoked when the Asynchronous operation ends.</param>
1287         /// <param name="state">Asynchronous state.</param>
1288         /// <returns>IAsyncResult that should be passed back to the End method to complete the Asynchronous call.</returns>
1289         public IAsyncResult BeginTrustFeb2005RenewResponse(Message request, AsyncCallback callback, object state)
1290         {
1291             return BeginProcessCore(request,
1292                                      _securityTokenServiceConfiguration.WSTrustFeb2005RequestSerializer,
1293                                      _securityTokenServiceConfiguration.WSTrustFeb2005ResponseSerializer,
1294                                      WSTrustFeb2005Constants.Actions.RenewResponse,
1295                                      WSTrustFeb2005Constants.Actions.RenewResponse,
1296                                      WSTrustFeb2005Constants.NamespaceURI,
1297                                      callback,
1298                                      state);
1299         }
1300
1301         /// <summary>
1302         /// Completes an Asynchronous call to Trust Feb 2005 RSTR/Renew message.
1303         /// </summary>
1304         /// <param name="ar">IAsyncResult object returned by the Begin method that started the Asynchronous call.</param>
1305         /// <returns>Message containing the Serialized RSTR.</returns>
1306         public Message EndTrustFeb2005RenewResponse(IAsyncResult ar)
1307         {
1308             return EndProcessCore(ar,
1309                                    WSTrustFeb2005Constants.Actions.RenewResponse,
1310                                    WSTrustFeb2005Constants.Actions.RenewResponse,
1311                                    WSTrustFeb2005Constants.NamespaceURI);
1312         }
1313
1314         /// <summary>
1315         /// Processes an Asynchronous call to Trust Feb 2005 RSTR/Validate message.
1316         /// </summary>
1317         /// <param name="request">Incoming Request message.</param>
1318         /// <param name="callback">Callback to be invoked when the Asynchronous operation ends.</param>
1319         /// <param name="state">Asynchronous state.</param>
1320         /// <returns>IAsyncResult that should be passed back to the End method to complete the Asynchronous call.</returns>
1321         public IAsyncResult BeginTrustFeb2005ValidateResponse(Message request, AsyncCallback callback, object state)
1322         {
1323             return BeginProcessCore(request,
1324                                      _securityTokenServiceConfiguration.WSTrustFeb2005RequestSerializer,
1325                                      _securityTokenServiceConfiguration.WSTrustFeb2005ResponseSerializer,
1326                                      WSTrustFeb2005Constants.Actions.ValidateResponse,
1327                                      WSTrustFeb2005Constants.Actions.ValidateResponse,
1328                                      WSTrustFeb2005Constants.NamespaceURI,
1329                                      callback,
1330                                      state);
1331         }
1332
1333         /// <summary>
1334         /// Completes an Asynchronous call to Trust Feb 2005 RSTR/Validate message.
1335         /// </summary>
1336         /// <param name="ar">IAsyncResult object returned by the Begin method that started the Asynchronous call.</param>
1337         /// <returns>Message containing the Serialized RSTR.</returns>
1338         public Message EndTrustFeb2005ValidateResponse(IAsyncResult ar)
1339         {
1340             return EndProcessCore(ar,
1341                                    WSTrustFeb2005Constants.Actions.ValidateResponse,
1342                                    WSTrustFeb2005Constants.Actions.ValidateResponse,
1343                                    WSTrustFeb2005Constants.NamespaceURI);
1344         }
1345
1346         #endregion
1347
1348         //
1349         // An async result class that represents the async version of the ProcessCore method.
1350         //
1351         internal class ProcessCoreAsyncResult : AsyncResult
1352         {
1353             //
1354             // Encapsulate the local variables in the sync version of ProcessCore as fields.
1355             //
1356             WSTrustServiceContract _trustServiceContract;
1357             DispatchContext _dispatchContext;
1358             MessageVersion _messageVersion;
1359             WSTrustResponseSerializer _responseSerializer;
1360             WSTrustSerializationContext _serializationContext;
1361
1362             public ProcessCoreAsyncResult(WSTrustServiceContract contract,
1363                                            DispatchContext dispatchContext,
1364                                            MessageVersion messageVersion,
1365                                            WSTrustResponseSerializer responseSerializer,
1366                                            WSTrustSerializationContext serializationContext,
1367                                            AsyncCallback asyncCallback,
1368                                            object asyncState)
1369                 : base(asyncCallback, asyncState)
1370             {
1371                 if (contract == null)
1372                 {
1373                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contract");
1374                 }
1375
1376                 if (dispatchContext == null)
1377                 {
1378                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("dispatchContext");
1379                 }
1380
1381                 if (responseSerializer == null)
1382                 {
1383                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("responseSerializer");
1384                 }
1385
1386                 if (serializationContext == null)
1387                 {
1388                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serializationContext");
1389                 }
1390
1391                 _trustServiceContract = contract;
1392                 _dispatchContext = dispatchContext;
1393                 _messageVersion = messageVersion;
1394                 _responseSerializer = responseSerializer;
1395                 _serializationContext = serializationContext;
1396
1397                 contract.BeginDispatchRequest(dispatchContext, OnDispatchRequestCompleted, null);
1398             }
1399
1400             public WSTrustServiceContract TrustServiceContract
1401             {
1402                 get { return _trustServiceContract; }
1403             }
1404
1405             public DispatchContext DispatchContext
1406             {
1407                 get { return _dispatchContext; }
1408             }
1409
1410             public MessageVersion MessageVersion
1411             {
1412                 get { return _messageVersion; }
1413             }
1414
1415             public WSTrustResponseSerializer ResponseSerializer
1416             {
1417                 get { return _responseSerializer; }
1418             }
1419
1420             public WSTrustSerializationContext SerializationContext
1421             {
1422                 get { return _serializationContext; }
1423             }
1424
1425             public new static Message End(IAsyncResult ar)
1426             {
1427                 AsyncResult.End(ar);
1428
1429                 ProcessCoreAsyncResult pcar = ar as ProcessCoreAsyncResult;
1430                 if (pcar == null)
1431                 {
1432                     throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID2004, typeof(ProcessCoreAsyncResult), ar.GetType()));
1433                 }
1434
1435                 //
1436                 // Create the response Message object with the appropriate action.
1437                 //
1438                 return Message.CreateMessage(OperationContext.Current.RequestContext.RequestMessage.Version,
1439                                               pcar.DispatchContext.ResponseAction,
1440                                               new WSTrustResponseBodyWriter(pcar.DispatchContext.ResponseMessage,
1441                                                                              pcar.ResponseSerializer,
1442                                                                              pcar.SerializationContext));
1443             }
1444
1445             //
1446             // Asynchronously invoked when WSTrustServiceContract.BeginDispatchRequest completes.
1447             //
1448             private void OnDispatchRequestCompleted(IAsyncResult ar)
1449             {
1450                 try
1451                 {
1452                     _dispatchContext = _trustServiceContract.EndDispatchRequest(ar);
1453                     this.Complete(false);
1454                 }
1455                 catch (Exception ex)
1456                 {
1457                     if (System.Runtime.Fx.IsFatal(ex))
1458                     {
1459                         throw;
1460                     }
1461                     this.Complete(false, ex);
1462                 }
1463             }
1464         }
1465
1466         //
1467         // AsyncResult to encapsulate the default async implementation of DispatchRequest
1468         //
1469         internal class DispatchRequestAsyncResult : AsyncResult
1470         {
1471             DispatchContext _dispatchContext;
1472
1473             public DispatchContext DispatchContext
1474             {
1475                 get { return _dispatchContext; }
1476             }
1477
1478             public DispatchRequestAsyncResult(DispatchContext dispatchContext, AsyncCallback asyncCallback, object asyncState)
1479                 : base(asyncCallback, asyncState)
1480             {
1481                 _dispatchContext = dispatchContext;
1482
1483                 ClaimsPrincipal icp = dispatchContext.Principal;
1484                 RST rst = dispatchContext.RequestMessage as RST;
1485                 STS sts = dispatchContext.SecurityTokenService;
1486
1487                 if (rst == null)
1488                 {
1489                     this.Complete(true, DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidRequestException(SR.GetString(SR.ID3023))));
1490                     return;
1491                 }
1492
1493                 switch (rst.RequestType)
1494                 {
1495                     case RequestTypes.Cancel:
1496                         sts.BeginCancel(icp, rst, OnCancelComplete, null);
1497                         break;
1498                     case RequestTypes.Issue:
1499                         sts.BeginIssue(icp, rst, OnIssueComplete, null);
1500                         break;
1501                     case RequestTypes.Renew:
1502                         sts.BeginRenew(icp, rst, OnRenewComplete, null);
1503                         break;
1504                     case RequestTypes.Validate:
1505                         sts.BeginValidate(icp, rst, OnValidateComplete, null);
1506                         break;
1507                     default:
1508                         this.Complete(true, DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ID3112, rst.RequestType))));
1509                         break;
1510                 }
1511             }
1512
1513             public new static DispatchContext End(IAsyncResult ar)
1514             {
1515                 AsyncResult.End(ar);
1516
1517                 DispatchRequestAsyncResult dcar = ar as DispatchRequestAsyncResult;
1518                 if (dcar == null)
1519                 {
1520                     throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID2004, typeof(DispatchRequestAsyncResult), ar.GetType()));
1521                 }
1522                 return dcar.DispatchContext;
1523             }
1524
1525             void OnCancelComplete(IAsyncResult ar)
1526             {
1527                 try
1528                 {
1529                     _dispatchContext.ResponseMessage = _dispatchContext.SecurityTokenService.EndCancel(ar);
1530                     Complete(false);
1531                 }
1532                 catch (Exception e)
1533                 {
1534                     System.ServiceModel.DiagnosticUtility.TraceHandledException(e, TraceEventType.Error);
1535
1536                     if (Fx.IsFatal(e)) throw;
1537                     Complete(false, e);
1538                 }
1539             }
1540
1541             void OnIssueComplete(IAsyncResult ar)
1542             {
1543                 try
1544                 {
1545                     _dispatchContext.ResponseMessage = _dispatchContext.SecurityTokenService.EndIssue(ar);
1546                     Complete(false);
1547                 }
1548                 catch (Exception e)
1549                 {
1550                     System.ServiceModel.DiagnosticUtility.TraceHandledException(e, TraceEventType.Error);
1551
1552                     if (Fx.IsFatal(e)) throw;
1553                     Complete(false, e);
1554                 }
1555             }
1556
1557             void OnRenewComplete(IAsyncResult ar)
1558             {
1559                 try
1560                 {
1561                     _dispatchContext.ResponseMessage = _dispatchContext.SecurityTokenService.EndRenew(ar);
1562                     Complete(false);
1563                 }
1564                 catch (Exception e)
1565                 {
1566                     System.ServiceModel.DiagnosticUtility.TraceHandledException(e, TraceEventType.Error);
1567
1568                     if (Fx.IsFatal(e)) throw;
1569                     Complete(false, e);
1570                 }
1571             }
1572
1573             void OnValidateComplete(IAsyncResult ar)
1574             {
1575                 try
1576                 {
1577                     _dispatchContext.ResponseMessage = _dispatchContext.SecurityTokenService.EndValidate(ar);
1578                     Complete(false);
1579                 }
1580                 catch (Exception e)
1581                 {
1582                     System.ServiceModel.DiagnosticUtility.TraceHandledException(e, TraceEventType.Error);
1583
1584                     if (Fx.IsFatal(e)) throw;
1585                     Complete(false, e);
1586                 }
1587             }
1588
1589         }
1590
1591         #region IContractBehavior Members
1592
1593         /// <summary>
1594         /// Configures any binding elements to support the contract behavior.
1595         /// </summary>
1596         /// <remarks>
1597         /// Inherited from IContractBehavior
1598         /// </remarks>
1599         public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
1600         {
1601             return;
1602         }
1603
1604         /// <summary>
1605         /// Implements a modification or extension of the client across a contract.
1606         /// </summary>
1607         /// <remarks>
1608         /// Inherited from IContractBehavior
1609         /// </remarks>
1610         public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
1611         {
1612             return;
1613         }
1614
1615         /// <summary>
1616         /// Implements a modification or extension of the client across a contract.
1617         /// </summary>
1618         /// <remarks>
1619         /// Inherited from IContractBehavior
1620         /// </remarks>
1621         public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.DispatchRuntime dispatchRuntime)
1622         {
1623             return;
1624         }
1625
1626         /// <summary>
1627         /// Implement to confirm that the contract and endpoint can support the contract
1628         /// behavior.
1629         /// </summary>
1630         /// <remarks>
1631         /// Inherited from IContractBehavior
1632         /// </remarks>
1633         public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
1634         {
1635             return;
1636         }
1637
1638         #endregion
1639
1640         #region IWsdlExportExtension Members
1641
1642         /// <summary>
1643         /// Implementation for IWsdlExportExtension.ExportContract. The default implementation 
1644         /// does nothing. Can be overriden in the derived class for specific behavior.
1645         /// </summary>
1646         /// <param name="exporter">The WsdlExporter that exports the contract information.</param>
1647         /// <param name="context">Provides mappings from exported WSDL elements to the contract description.</param>
1648         public virtual void ExportContract(WsdlExporter exporter, WsdlContractConversionContext context)
1649         {
1650             return;
1651         }
1652
1653         /// <summary>
1654         /// Implements IWsdlExportExtensions.ExportEndpoint. The default implementation does the following,
1655         /// For every Trust contract found,
1656         /// 1. It includes the appropriate trust namespace in the WSDL.
1657         /// 2. Imports the appropriate Trust schema and all dependent schemas.
1658         /// 3. Fixes the Messages of each operation to it appropriate WS-Trust equivalent.
1659         ///     Trust Contract exposed by the Framework takes a System.ServiceModel.Channels.Message in and 
1660         ///     returns a System.ServiceModel.Channels.Message out. But Trust messages expects and RST and 
1661         ///     returns an RSTR/RSTRC. This method fixes the message names with the appropriate WS-Trust
1662         ///     messages.
1663         /// </summary>
1664         /// <param name="exporter">The WsdlExporter that exports the contract information.</param>
1665         /// <param name="context">Provides mappings from exported WSDL elements to the endpoint description.</param>
1666         /// <exception cref="ArgumentNullException">The input argument 'exporter' or 'context' is null.</exception>
1667         public virtual void ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context)
1668         {
1669             if (exporter == null)
1670             {
1671                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("exporter");
1672             }
1673
1674             if (context == null)
1675             {
1676                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
1677             }
1678
1679             if (context.WsdlPort == null)
1680             {
1681                 throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID3146));
1682             }
1683
1684             if (context.WsdlPort.Service == null)
1685             {
1686                 throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID3147));
1687             }
1688
1689             if (context.WsdlPort.Service.ServiceDescription == null)
1690             {
1691                 throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID3148));
1692             }
1693
1694             System.Web.Services.Description.ServiceDescription serviceDescription = context.WsdlPort.Service.ServiceDescription;
1695
1696             // Iterate throught the Ports and for each of our contracts fix the input and output messages 
1697             // of the contract and import the required schemas.
1698             foreach (PortType portType in serviceDescription.PortTypes)
1699             {
1700                 if (StringComparer.Ordinal.Equals(portType.Name, WSTrustServiceContractConstants.Contracts.IWSTrustFeb2005Sync))
1701                 {
1702                     IncludeNamespace(context, WSTrustFeb2005Constants.Prefix, WSTrustFeb2005Constants.NamespaceURI);
1703                     ImportSchema(exporter, context, WSTrustFeb2005Constants.NamespaceURI);
1704
1705                     FixMessageElement(
1706                         serviceDescription,
1707                         portType,
1708                         context,
1709                         WSTrustServiceContractConstants.Operations.TrustFeb2005Cancel,
1710                         new XmlQualifiedName(
1711                             WSTrustFeb2005Constants.ElementNames.RequestSecurityToken,
1712                             WSTrustFeb2005Constants.NamespaceURI),
1713                         new XmlQualifiedName(WSTrustFeb2005Constants.ElementNames.RequestSecurityTokenResponse,
1714                             WSTrustFeb2005Constants.NamespaceURI));
1715
1716                     FixMessageElement(
1717                         serviceDescription,
1718                         portType,
1719                         context,
1720                         WSTrustServiceContractConstants.Operations.TrustFeb2005Issue,
1721                         new XmlQualifiedName(
1722                             WSTrustFeb2005Constants.ElementNames.RequestSecurityToken,
1723                             WSTrustFeb2005Constants.NamespaceURI),
1724                         new XmlQualifiedName(
1725                             WSTrustFeb2005Constants.ElementNames.RequestSecurityTokenResponse,
1726                             WSTrustFeb2005Constants.NamespaceURI));
1727
1728                     FixMessageElement(
1729                         serviceDescription,
1730                         portType,
1731                         context,
1732                         WSTrustServiceContractConstants.Operations.TrustFeb2005Renew,
1733                         new XmlQualifiedName(
1734                             WSTrustFeb2005Constants.ElementNames.RequestSecurityToken,
1735                             WSTrustFeb2005Constants.NamespaceURI),
1736                         new XmlQualifiedName(
1737                             WSTrustFeb2005Constants.ElementNames.RequestSecurityTokenResponse,
1738                             WSTrustFeb2005Constants.NamespaceURI));
1739
1740                     FixMessageElement(
1741                         serviceDescription,
1742                         portType,
1743                         context,
1744                         WSTrustServiceContractConstants.Operations.TrustFeb2005Validate,
1745                         new XmlQualifiedName(
1746                             WSTrustFeb2005Constants.ElementNames.RequestSecurityToken,
1747                             WSTrustFeb2005Constants.NamespaceURI),
1748                         new XmlQualifiedName(
1749                             WSTrustFeb2005Constants.ElementNames.RequestSecurityTokenResponse,
1750                             WSTrustFeb2005Constants.NamespaceURI));
1751                 }
1752                 else if (StringComparer.OrdinalIgnoreCase.Equals(portType.Name, WSTrustServiceContractConstants.Contracts.IWSTrust13Sync))
1753                 {
1754                     IncludeNamespace(context, WSTrust13Constants.Prefix, WSTrust13Constants.NamespaceURI);
1755                     ImportSchema(exporter, context, WSTrust13Constants.NamespaceURI);
1756
1757                     FixMessageElement(
1758                         serviceDescription,
1759                         portType,
1760                         context,
1761                         WSTrustServiceContractConstants.Operations.Trust13Cancel,
1762                         new XmlQualifiedName(
1763                             WSTrust13Constants.ElementNames.RequestSecurityToken,
1764                             WSTrust13Constants.NamespaceURI),
1765                         new XmlQualifiedName(
1766                             WSTrust13Constants.ElementNames.RequestSecurityTokenResponseCollection,
1767                             WSTrust13Constants.NamespaceURI));
1768
1769                     FixMessageElement(
1770                         serviceDescription,
1771                         portType,
1772                         context,
1773                         WSTrustServiceContractConstants.Operations.Trust13Issue,
1774                         new XmlQualifiedName(
1775                             WSTrust13Constants.ElementNames.RequestSecurityToken,
1776                             WSTrust13Constants.NamespaceURI),
1777                         new XmlQualifiedName(
1778                             WSTrust13Constants.ElementNames.RequestSecurityTokenResponseCollection,
1779                             WSTrust13Constants.NamespaceURI));
1780
1781                     FixMessageElement(
1782                         serviceDescription,
1783                         portType,
1784                         context,
1785                         WSTrustServiceContractConstants.Operations.Trust13Renew,
1786                         new XmlQualifiedName(
1787                             WSTrust13Constants.ElementNames.RequestSecurityToken,
1788                             WSTrust13Constants.NamespaceURI),
1789                         new XmlQualifiedName(
1790                             WSTrust13Constants.ElementNames.RequestSecurityTokenResponseCollection,
1791                             WSTrust13Constants.NamespaceURI));
1792
1793                     FixMessageElement(
1794                         serviceDescription,
1795                         portType,
1796                         context,
1797                         WSTrustServiceContractConstants.Operations.Trust13Validate,
1798                         new XmlQualifiedName(
1799                             WSTrust13Constants.ElementNames.RequestSecurityToken,
1800                             WSTrust13Constants.NamespaceURI),
1801                         new XmlQualifiedName(
1802                             WSTrust13Constants.ElementNames.RequestSecurityTokenResponseCollection,
1803                             WSTrust13Constants.NamespaceURI));
1804                 }
1805                 else if (StringComparer.OrdinalIgnoreCase.Equals(portType.Name, WSTrustServiceContractConstants.Contracts.IWSTrustFeb2005Async))
1806                 {
1807                     IncludeNamespace(context, WSTrustFeb2005Constants.Prefix, WSTrustFeb2005Constants.NamespaceURI);
1808                     ImportSchema(exporter, context, WSTrustFeb2005Constants.NamespaceURI);
1809
1810                     FixMessageElement(
1811                         serviceDescription,
1812                         portType,
1813                         context,
1814                         WSTrustServiceContractConstants.Operations.TrustFeb2005CancelAsync,
1815                         new XmlQualifiedName(
1816                             WSTrustFeb2005Constants.ElementNames.RequestSecurityToken,
1817                             WSTrustFeb2005Constants.NamespaceURI),
1818                         new XmlQualifiedName(
1819                             WSTrustFeb2005Constants.ElementNames.RequestSecurityTokenResponse,
1820                             WSTrustFeb2005Constants.NamespaceURI));
1821
1822                     FixMessageElement(
1823                         serviceDescription,
1824                         portType,
1825                         context,
1826                         WSTrustServiceContractConstants.Operations.TrustFeb2005IssueAsync,
1827                         new XmlQualifiedName(
1828                             WSTrustFeb2005Constants.ElementNames.RequestSecurityToken,
1829                             WSTrustFeb2005Constants.NamespaceURI),
1830                         new XmlQualifiedName(
1831                             WSTrustFeb2005Constants.ElementNames.RequestSecurityTokenResponse,
1832                             WSTrustFeb2005Constants.NamespaceURI));
1833
1834                     FixMessageElement(
1835                         serviceDescription,
1836                         portType,
1837                         context,
1838                         WSTrustServiceContractConstants.Operations.TrustFeb2005RenewAsync,
1839                         new XmlQualifiedName(
1840                             WSTrustFeb2005Constants.ElementNames.RequestSecurityToken,
1841                             WSTrustFeb2005Constants.NamespaceURI),
1842                         new XmlQualifiedName(
1843                             WSTrustFeb2005Constants.ElementNames.RequestSecurityTokenResponse,
1844                             WSTrustFeb2005Constants.NamespaceURI));
1845
1846                     FixMessageElement(
1847                         serviceDescription,
1848                         portType,
1849                         context,
1850                         WSTrustServiceContractConstants.Operations.TrustFeb2005ValidateAsync,
1851                         new XmlQualifiedName(
1852                             WSTrustFeb2005Constants.ElementNames.RequestSecurityToken,
1853                             WSTrustFeb2005Constants.NamespaceURI),
1854                         new XmlQualifiedName(
1855                             WSTrustFeb2005Constants.ElementNames.RequestSecurityTokenResponse,
1856                             WSTrustFeb2005Constants.NamespaceURI));
1857                 }
1858                 else if (StringComparer.OrdinalIgnoreCase.Equals(portType.Name, WSTrustServiceContractConstants.Contracts.IWSTrust13Async))
1859                 {
1860                     IncludeNamespace(context, WSTrust13Constants.Prefix, WSTrust13Constants.NamespaceURI);
1861                     ImportSchema(exporter, context, WSTrust13Constants.NamespaceURI);
1862
1863                     FixMessageElement(
1864                         serviceDescription,
1865                         portType,
1866                         context,
1867                         WSTrustServiceContractConstants.Operations.Trust13CancelAsync,
1868                         new XmlQualifiedName(
1869                             WSTrust13Constants.ElementNames.RequestSecurityToken,
1870                             WSTrust13Constants.NamespaceURI),
1871                         new XmlQualifiedName(
1872                             WSTrust13Constants.ElementNames.RequestSecurityTokenResponseCollection,
1873                             WSTrust13Constants.NamespaceURI));
1874
1875                     FixMessageElement(
1876                         serviceDescription,
1877                         portType,
1878                         context,
1879                         WSTrustServiceContractConstants.Operations.Trust13IssueAsync,
1880                         new XmlQualifiedName(
1881                             WSTrust13Constants.ElementNames.RequestSecurityToken,
1882                             WSTrust13Constants.NamespaceURI),
1883                         new XmlQualifiedName(
1884                             WSTrust13Constants.ElementNames.RequestSecurityTokenResponseCollection,
1885                             WSTrust13Constants.NamespaceURI));
1886
1887                     FixMessageElement(
1888                         serviceDescription,
1889                         portType,
1890                         context,
1891                         WSTrustServiceContractConstants.Operations.Trust13RenewAsync,
1892                         new XmlQualifiedName(
1893                             WSTrust13Constants.ElementNames.RequestSecurityToken,
1894                             WSTrust13Constants.NamespaceURI),
1895                         new XmlQualifiedName(
1896                             WSTrust13Constants.ElementNames.RequestSecurityTokenResponseCollection,
1897                             WSTrust13Constants.NamespaceURI));
1898
1899                     FixMessageElement(
1900                         serviceDescription,
1901                         portType,
1902                         context,
1903                         WSTrustServiceContractConstants.Operations.Trust13ValidateAsync,
1904                         new XmlQualifiedName(
1905                             WSTrust13Constants.ElementNames.RequestSecurityToken,
1906                             WSTrust13Constants.NamespaceURI),
1907                         new XmlQualifiedName(
1908                             WSTrust13Constants.ElementNames.RequestSecurityTokenResponseCollection,
1909                             WSTrust13Constants.NamespaceURI));
1910                 }
1911             }
1912         }
1913
1914         #endregion
1915
1916         /// <summary>
1917         /// Adds the required WS-Trust namespaces to the WSDL if not already present.
1918         /// </summary>
1919         /// <param name="context">Provides mappings from exported WSDL elements to the endpoint description.</param>
1920         /// <param name="prefix">The prefix of the namespace to be included.</param>
1921         /// <param name="ns">Namespace to be included.</param>
1922         /// <exception cref="ArgumentException">Either 'prefix' or 'ns' is null or empty string.</exception>
1923         /// <exception cref="ArgumentNullException">The 'context' parameter is null.</exception>
1924         protected virtual void IncludeNamespace(WsdlEndpointConversionContext context, string prefix, string ns)
1925         {
1926             if (context == null)
1927             {
1928                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
1929             }
1930
1931             if (String.IsNullOrEmpty(prefix))
1932             {
1933                 throw DiagnosticUtility.ThrowHelperArgumentNullOrEmptyString("prefix");
1934             }
1935
1936             if (String.IsNullOrEmpty(ns))
1937             {
1938                 throw DiagnosticUtility.ThrowHelperArgumentNullOrEmptyString("ns");
1939             }
1940
1941             bool alreadyPresent = false;
1942             XmlQualifiedName[] namespaces = context.WsdlBinding.ServiceDescription.Namespaces.ToArray();
1943             for (int i = 0; i < namespaces.Length; ++i)
1944             {
1945                 if (StringComparer.Ordinal.Equals(namespaces[i].Namespace, ns))
1946                 {
1947                     alreadyPresent = true;
1948                     break;
1949                 }
1950             }
1951
1952             if (!alreadyPresent)
1953             {
1954                 context.WsdlBinding.ServiceDescription.Namespaces.Add(prefix, ns);
1955             }
1956         }
1957
1958         /// <summary>
1959         /// Imports all the required schema if not already present in the WSDL.
1960         /// The default implementation will import the following schemas,
1961         ///     (a) WS-Trust Feb 2005.
1962         ///     (b) WS-Trust 1.3
1963         /// Derived classes can override this method to import other schemas.
1964         /// </summary>
1965         /// <param name="exporter">The WsdlExporter that exports the contract information.</param>
1966         /// <param name="context">Provides mappings from exported WSDL elements to the endpoint description.</param>
1967         /// <param name="ns">The current WS-Trust namespace for which the schemas are imported.</param>
1968         /// <exception cref="ArgumentNullException">The parameter 'exporter' or 'context' is null.</exception>
1969         /// <exception cref="ArgumentException">The parameter 'ns' is either null or String.Empty.</exception>
1970         /// <exception cref="InvalidOperationException">The namespace 'ns' is not a recognized WS-Trust namespace.</exception>
1971         protected virtual void ImportSchema(WsdlExporter exporter, WsdlEndpointConversionContext context, string ns)
1972         {
1973             if (exporter == null)
1974             {
1975                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("exporter");
1976             }
1977
1978             if (context == null)
1979             {
1980                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
1981             }
1982
1983             if (String.IsNullOrEmpty(ns))
1984             {
1985                 throw DiagnosticUtility.ThrowHelperArgumentNullOrEmptyString("ns");
1986             }
1987
1988             foreach (XmlSchema xmlSchema in context.WsdlPort.Service.ServiceDescription.Types.Schemas)
1989             {
1990                 foreach (XmlSchemaObject include in xmlSchema.Includes)
1991                 {
1992                     XmlSchemaImport schemaImport = include as XmlSchemaImport;
1993                     if ((schemaImport != null) && StringComparer.Ordinal.Equals(schemaImport.Namespace, ns))
1994                     {
1995                         // The schema is already imported. Just return.
1996                         return;
1997                     }
1998                 }
1999             }
2000
2001             XmlSchema schema = GetXmlSchema(exporter, ns);
2002             if (schema == null)
2003             {
2004                 throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID3004, ns));
2005             }
2006             XmlSchema importedSchema = null;
2007             if (context.WsdlPort.Service.ServiceDescription.Types.Schemas.Count == 0)
2008             {
2009                 importedSchema = new XmlSchema();
2010                 context.WsdlPort.Service.ServiceDescription.Types.Schemas.Add(importedSchema);
2011             }
2012             else
2013             {
2014                 importedSchema = context.WsdlPort.Service.ServiceDescription.Types.Schemas[0];
2015             }
2016
2017             XmlSchemaImport import = new XmlSchemaImport();
2018             import.Namespace = ns;
2019             exporter.GeneratedXmlSchemas.Add(schema);
2020             importedSchema.Includes.Add(import);
2021         }
2022
2023
2024         /// <summary>
2025         /// For a given namespace this method looks up the WsdlExporter to see if an XmlSchema has been cached and returns that. 
2026         /// Else it loads the schema for that given namespace and returns the loaded XmlSchema.
2027         /// </summary>
2028         /// <param name="exporter">The WsdlExporter that exports the contract information.</param>
2029         /// <param name="ns">The namespace for which the schema is to be obtained.</param>
2030         /// <exception cref="ArgumentNullException">The parameter 'exporter' is null.</exception>
2031         /// <exception cref="ArgumentException">The parameter 'ns' is either null or String.Empty.</exception>
2032         /// <exception cref="InvalidOperationException">The namespace 'ns' is not a recognized WS-Trust namespace.</exception>
2033         static XmlSchema GetXmlSchema(WsdlExporter exporter, string ns)
2034         {
2035             if (exporter == null)
2036             {
2037                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("exporter");
2038             }
2039
2040             if (String.IsNullOrEmpty(ns))
2041             {
2042                 throw DiagnosticUtility.ThrowHelperArgumentNullOrEmptyString("ns");
2043             }
2044
2045             ICollection schemas = exporter.GeneratedXmlSchemas.Schemas(ns);
2046             if ((schemas != null) && (schemas.Count > 0))
2047             {
2048                 foreach (XmlSchema s in schemas)
2049                 {
2050                     return s;
2051                 }
2052             }
2053
2054             string xmlSchema = null;
2055             switch (ns)
2056             {
2057                 case WSTrustFeb2005Constants.NamespaceURI:
2058                     xmlSchema = WSTrustFeb2005Constants.Schema;
2059                     break;
2060                 case WSTrust13Constants.NamespaceURI:
2061                     xmlSchema = WSTrust13Constants.Schema;
2062                     break;
2063                 default:
2064                     throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID5004, ns));
2065             }
2066
2067             return XmlSchema.Read(new StringReader(xmlSchema), null);
2068         }
2069
2070         /// <summary>
2071         /// During WSDL generation, the method fixes a given operation message element to refer to the 
2072         /// RST and RSTR elements of the appropriate WS-Trust version. 
2073         /// </summary>
2074         /// <param name="serviceDescription">The ServiceDescription that has the current state of the exported 
2075         /// WSDL.</param>
2076         /// <param name="portType">The WSDL PortType whose messages are to be fixed.</param>
2077         /// <param name="context">Provides mappings from exported WSDL elements to the endpoint description.</param>
2078         /// <param name="operationName">The operation name inside the PortType.</param>
2079         /// <param name="inputMessageElement">The XmlQualifiedName of the input message element.</param>
2080         /// <param name="outputMessageElement">The XmlQualifiedName of the output message element.</param>
2081         /// <exception cref="ArgumentNullException">The parameter 'serviceDescription', 'portType', 'inputMessageType'
2082         /// or 'outputMessageType' is null.</exception>
2083         /// <exception cref="ArgumentException">The parameter 'operationName' is null or Empty.</exception>
2084         /// <remarks>
2085         /// Trust Contract exposed by the Framework takes a System.ServiceModel.Channels.Message in and 
2086         /// returns a System.ServiceModel.Channels.Message out. But Trust messages expects and RST and 
2087         /// returns an RSTR/RSTRC. This method fixes the message elements with the appropriate WS-Trust
2088         /// messages specified by the XmlQualified names 'inputMessageElement' and 'outputMessageElement'.
2089         /// </remarks>
2090         protected virtual void FixMessageElement(
2091                                 System.Web.Services.Description.ServiceDescription serviceDescription,
2092                                 PortType portType,
2093                                 WsdlEndpointConversionContext context,
2094                                 string operationName,
2095                                 XmlQualifiedName inputMessageElement,
2096                                 XmlQualifiedName outputMessageElement)
2097         {
2098             if (serviceDescription == null)
2099             {
2100                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serviceDescription");
2101             }
2102
2103             if (portType == null)
2104             {
2105                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("portType");
2106             }
2107
2108             if (context == null)
2109             {
2110                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
2111             }
2112
2113             if (String.IsNullOrEmpty(operationName))
2114             {
2115                 throw DiagnosticUtility.ThrowHelperArgumentNullOrEmptyString("operationName");
2116             }
2117
2118             if (inputMessageElement == null)
2119             {
2120                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("inputMessageElement");
2121             }
2122
2123             if (outputMessageElement == null)
2124             {
2125                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("outputMessageElement");
2126             }
2127
2128             Operation operation = null;
2129             System.Web.Services.Description.Message inputMessage = null;
2130             System.Web.Services.Description.Message outputMessage = null;
2131
2132             foreach (Operation op in portType.Operations)
2133             {
2134                 if (StringComparer.Ordinal.Equals(op.Name, operationName))
2135                 {
2136                     operation = op;
2137
2138                     // Find the correspinding message in the messages collection.
2139                     foreach (System.Web.Services.Description.Message message in serviceDescription.Messages)
2140                     {
2141                         if (StringComparer.Ordinal.Equals(message.Name, op.Messages.Input.Message.Name))
2142                         {
2143                             if (message.Parts.Count != 1)
2144                             {
2145                                 throw DiagnosticUtility.ThrowHelperInvalidOperation(
2146                                     SR.GetString(SR.ID3144, portType.Name, op.Name, message.Name, message.Parts.Count));
2147                             }
2148                             inputMessage = message;
2149                         }
2150                         else if (StringComparer.Ordinal.Equals(message.Name, op.Messages.Output.Message.Name))
2151                         {
2152                             if (message.Parts.Count != 1)
2153                             {
2154                                 throw DiagnosticUtility.ThrowHelperInvalidOperation(
2155                                     SR.GetString(SR.ID3144, portType.Name, op.Name, message.Name, message.Parts.Count));
2156                             }
2157                             outputMessage = message;
2158                         }
2159
2160                         if ((inputMessage != null) && (outputMessage != null))
2161                         {
2162                             break;
2163                         }
2164                     }
2165                 }
2166
2167                 if (operation != null)
2168                 {
2169                     break;
2170                 }
2171             }
2172
2173             if (operation == null)
2174             {
2175                 // This operation is missing. This might be due to another Behavior that has modified the WSDL as
2176                 // well. Ignore this and return.
2177                 return;
2178             }
2179
2180             if (inputMessage == null)
2181             {
2182                 throw DiagnosticUtility.ThrowHelperInvalidOperation(
2183                     SR.GetString(SR.ID3149, portType.Name, portType.Namespaces, operationName));
2184             }
2185             if (outputMessage == null)
2186             {
2187                 throw DiagnosticUtility.ThrowHelperInvalidOperation(
2188                     SR.GetString(SR.ID3150, portType.Name, portType.Namespaces, operationName));
2189             }
2190
2191             inputMessage.Parts[0].Element = inputMessageElement;
2192             outputMessage.Parts[0].Element = outputMessageElement;
2193             inputMessage.Parts[0].Type = null;
2194             outputMessage.Parts[0].Type = null;
2195         }
2196     }
2197 }