/// <summary>
        /// Initializes an instance of <see cref="WSTrustResponseBodyWriter"/>
        /// </summary>
        /// <param name="requestSecurityTokenResponse">The Response object that can write the body contents.</param>
        /// <param name="serializer">Serializer to use for serializing the RSTR.</param>
        /// <param name="context">The <see cref="WSTrustSerializationContext"/> of this request.</param>
        /// <exception cref="ArgumentNullException">serializer parameter is null.</exception>
        public WSTrustResponseBodyWriter(RSTR requestSecurityTokenResponse, WSTrustResponseSerializer serializer, WSTrustSerializationContext context)
            : base( true )
        {
            if ( serializer == null )
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "serializer" );
            }

            if ( requestSecurityTokenResponse == null )
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("requestSecurityTokenResponse");
            }

            if ( context == null )
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "context" );
            }

            _serializer = serializer;
            _rstr = requestSecurityTokenResponse;
            _context = context;
        }
        /// <summary>
        /// Creates a <see cref="DispatchContext"/> object for use by the <see cref="DispatchRequest"/> method.
        /// </summary>
        /// <param name="requestMessage">The incoming request message.</param>
        /// <param name="requestAction">The SOAP action of the request.</param>
        /// <param name="responseAction">The default SOAP action of the response.</param>
        /// <param name="trustNamespace">Namespace URI of the trust version of the incoming request.</param>
        /// <param name="requestSerializer">The <see cref="WSTrustRequestSerializer"/> used to deserialize 
        /// incoming RST messages.</param>
        /// <param name="responseSerializer">The <see cref="WSTrustResponseSerializer"/> used to deserialize 
        /// incoming RSTR messages.</param>
        /// <param name="serializationContext">The <see cref="WSTrustSerializationContext"/> to use 
        /// when deserializing incoming messages.</param>
        /// <returns>A <see cref="DispatchContext"/> object.</returns>
        protected virtual DispatchContext CreateDispatchContext(Message requestMessage,
                                                                 string requestAction,
                                                                 string responseAction,
                                                                 string trustNamespace,
                                                                 WSTrustRequestSerializer requestSerializer,
                                                                 WSTrustResponseSerializer responseSerializer,
                                                                 WSTrustSerializationContext serializationContext)
        {
            DispatchContext dispatchContext = new DispatchContext()
            {
                Principal = OperationContext.Current.ClaimsPrincipal as ClaimsPrincipal,
                RequestAction = requestAction,
                ResponseAction = responseAction,
                TrustNamespace = trustNamespace
            };

            XmlReader requestBodyReader = requestMessage.GetReaderAtBodyContents();
            //
            // Take a peek at the request with the serializers to figure out if this is a standard incoming
            // RST or if this is an instance of a challenge-response style message pattern where an RSTR comes in.
            //
            if (requestSerializer.CanRead(requestBodyReader))
            {
                dispatchContext.RequestMessage = requestSerializer.ReadXml(requestBodyReader, serializationContext);
            }
            else if (responseSerializer.CanRead(requestBodyReader))
            {
                dispatchContext.RequestMessage = responseSerializer.ReadXml(requestBodyReader, serializationContext);
            }
            else
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    new InvalidRequestException(SR.GetString(SR.ID3114)));
            }

            //
            // CAUTION: Don't create the STS until after the RST or RSTR is deserialized or the test team
            //          has major infrastructure problems.
            //          
            dispatchContext.SecurityTokenService = CreateSTS();
            return dispatchContext;
        }
        /// <summary>
        /// Handles Asynchronous call to the STS.
        /// </summary>
        /// <param name="requestMessage">Incoming Request message.</param>
        /// <param name="requestSerializer">Trust Request Serializer.</param>
        /// <param name="responseSerializer">Trust Response Serializer.</param>
        /// <param name="requestAction">Request SOAP action.</param>
        /// <param name="responseAction">Response SOAP action.</param>
        /// <param name="trustNamespace">Namespace URI of the trust version of the incoming request.</param>
        /// <param name="callback">Callback that gets invoked when the Asynchronous call ends.</param>
        /// <param name="state">state information of the Asynchronous call.</param>
        /// <returns>IAsyncResult that should be passed back to the End method to complete the Asynchronous call.</returns>
        /// <exception cref="ArgumentNullException">One of the argument is null.</exception>
        protected virtual IAsyncResult BeginProcessCore(Message requestMessage, WSTrustRequestSerializer requestSerializer, WSTrustResponseSerializer responseSerializer, string requestAction, string responseAction, string trustNamespace, AsyncCallback callback, object state)
        {
            if (requestMessage == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("request");
            }

            if (requestSerializer == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("requestSerializer");
            }

            if (responseSerializer == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("responseSerializer");
            }

            if (String.IsNullOrEmpty(requestAction))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("requestAction");
            }

            if (String.IsNullOrEmpty(responseAction))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("responseAction");
            }

            if (String.IsNullOrEmpty(trustNamespace))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("trustNamespace");
            }

            IAsyncResult result = null;
            try
            {
                Fx.Assert(OperationContext.Current != null, "");
                Fx.Assert(OperationContext.Current.RequestContext != null, "");

                //
                // Create the Serialization and Dispatch context objects.
                //
                WSTrustSerializationContext serializationContext = CreateSerializationContext();

                DispatchContext dispatchContext = CreateDispatchContext(requestMessage,
                                                                         requestAction,
                                                                         responseAction,
                                                                         trustNamespace,
                                                                         requestSerializer,
                                                                         responseSerializer,
                                                                         serializationContext);

                //
                // Validate the dispatch context.
                //
                ValidateDispatchContext(dispatchContext);

                //
                // Dispatch the message asynchronously.
                //
                result = new ProcessCoreAsyncResult(this,
                                                     dispatchContext,
                                                     OperationContext.Current.RequestContext.RequestMessage.Version,
                                                     responseSerializer,
                                                     serializationContext,
                                                     callback,
                                                     state);
            }
            catch (Exception ex)
            {
                if (!HandleException(ex, trustNamespace, requestAction, requestMessage.Version.Envelope))
                {
                    throw;
                }
            }

            return result;
        }
        /// <summary>
        /// Handles Synchronous calls to the STS.
        /// </summary>
        /// <param name="requestMessage">Incoming Request message.</param>
        /// <param name="requestSerializer">Trust Request Serializer.</param>
        /// <param name="responseSerializer">Trust Response Serializer.</param>
        /// <param name="requestAction">Request SOAP action.</param>
        /// <param name="responseAction">Response SOAP action.</param>
        /// <param name="trustNamespace">Namespace URI of the trust version of the incoming request.</param>
        /// <returns>Response message that contains the serialized RSTR.</returns>
        /// <exception cref="ArgumentNullException">One of the argument is null.</exception>
        protected virtual Message ProcessCore(Message requestMessage, WSTrustRequestSerializer requestSerializer, WSTrustResponseSerializer responseSerializer, string requestAction, string responseAction, string trustNamespace)
        {
            if (requestMessage == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("requestMessage");
            }

            if (requestSerializer == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("requestSerializer");
            }

            if (responseSerializer == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("responseSerializer");
            }

            if (String.IsNullOrEmpty(requestAction))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("requestAction");
            }

            if (String.IsNullOrEmpty(responseAction))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("responseAction");
            }

            if (String.IsNullOrEmpty(trustNamespace))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("trustNamespace");
            }

            Message response = null;
            try
            {
                Fx.Assert(OperationContext.Current != null, "");
                Fx.Assert(OperationContext.Current.RequestContext != null, "");

                //
                // Create the Serialization and Dispatch context objects.
                //
                WSTrustSerializationContext serializationContext = CreateSerializationContext();

                DispatchContext dispatchContext = CreateDispatchContext(requestMessage,
                                                                         requestAction,
                                                                         responseAction,
                                                                         trustNamespace,
                                                                         requestSerializer,
                                                                         responseSerializer,
                                                                         serializationContext);

                //
                // Validate the dispatch context.
                //
                ValidateDispatchContext(dispatchContext);

                //
                // Dispatch the STS message.
                //
                DispatchRequest(dispatchContext);

                //
                // Create the response Message object with the appropriate action.
                //
                response = Message.CreateMessage(OperationContext.Current.RequestContext.RequestMessage.Version,
                                                  dispatchContext.ResponseAction,
                                                  new WSTrustResponseBodyWriter(dispatchContext.ResponseMessage, responseSerializer, serializationContext));
            }
            catch (Exception ex)
            {
                if (!HandleException(ex, trustNamespace, requestAction, requestMessage.Version.Envelope))
                {
                    throw;
                }
            }

            return response;
        }
            public ProcessCoreAsyncResult(WSTrustServiceContract contract,
                                           DispatchContext dispatchContext,
                                           MessageVersion messageVersion,
                                           WSTrustResponseSerializer responseSerializer,
                                           WSTrustSerializationContext serializationContext,
                                           AsyncCallback asyncCallback,
                                           object asyncState)
                : base(asyncCallback, asyncState)
            {
                if (contract == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contract");
                }

                if (dispatchContext == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("dispatchContext");
                }

                if (responseSerializer == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("responseSerializer");
                }

                if (serializationContext == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serializationContext");
                }

                _trustServiceContract = contract;
                _dispatchContext = dispatchContext;
                _messageVersion = messageVersion;
                _responseSerializer = responseSerializer;
                _serializationContext = serializationContext;

                contract.BeginDispatchRequest(dispatchContext, OnDispatchRequestCompleted, null);
            }
        public static void WriteKnownResponseElement(RequestSecurityTokenResponse rstr, XmlWriter writer, WSTrustSerializationContext context, WSTrustResponseSerializer responseSerializer, WSTrustConstantsAdapter trustConstants)
        {
            if (rstr == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rstr");
            }

            if (writer == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
            }

            if (context == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
            }

            if (responseSerializer == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("responseSerializer");
            }

            if (trustConstants == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("trustConstants");
            }

            if (rstr.Entropy != null)
            {
                responseSerializer.WriteXmlElement(writer, trustConstants.Elements.Entropy, rstr.Entropy, rstr, context);
            }

            if (rstr.KeySizeInBits.HasValue)
            {
                responseSerializer.WriteXmlElement(writer, trustConstants.Elements.KeySize, rstr.KeySizeInBits, rstr, context);
            }

            if (rstr.Lifetime != null)
            {
                responseSerializer.WriteXmlElement(writer, trustConstants.Elements.Lifetime, rstr.Lifetime, rstr, context);
            }

            if (rstr.AppliesTo != null)
            {
                responseSerializer.WriteXmlElement(writer, WSPolicyConstants.ElementNames.AppliesTo, rstr.AppliesTo, rstr, context);
            }

            if (rstr.RequestedSecurityToken != null)
            {
                responseSerializer.WriteXmlElement(writer, trustConstants.Elements.RequestedSecurityToken, rstr.RequestedSecurityToken, rstr, context);
            }

            if (rstr.RequestedProofToken != null)
            {
                responseSerializer.WriteXmlElement(writer, trustConstants.Elements.RequestedProofToken, rstr.RequestedProofToken, rstr, context);
            }

            if (rstr.RequestedAttachedReference != null)
            {
                responseSerializer.WriteXmlElement(writer, trustConstants.Elements.RequestedAttachedReference, rstr.RequestedAttachedReference, rstr, context);
            }

            if (rstr.RequestedUnattachedReference != null)
            {
                responseSerializer.WriteXmlElement(writer, trustConstants.Elements.RequestedUnattachedReference, rstr.RequestedUnattachedReference, rstr, context);
            }

            if (!string.IsNullOrEmpty(rstr.SignWith))
            {
                responseSerializer.WriteXmlElement(writer, trustConstants.Elements.SignWith, rstr.SignWith, rstr, context);
            }

            if (!string.IsNullOrEmpty(rstr.EncryptWith))
            {
                responseSerializer.WriteXmlElement(writer, trustConstants.Elements.EncryptWith, rstr.EncryptWith, rstr, context);
            }

            if (!string.IsNullOrEmpty(rstr.TokenType))
            {
                responseSerializer.WriteXmlElement(writer, trustConstants.Elements.TokenType, rstr.TokenType, rstr, context);
            }

            if (!string.IsNullOrEmpty(rstr.RequestType))
            {
                responseSerializer.WriteXmlElement(writer, trustConstants.Elements.RequestType, rstr.RequestType, rstr, context);
            }

            if (!string.IsNullOrEmpty(rstr.KeyType))
            {
                responseSerializer.WriteXmlElement(writer, trustConstants.Elements.KeyType, rstr.KeyType, rstr, context);
            }

            if (!string.IsNullOrEmpty(rstr.AuthenticationType))
            {
                responseSerializer.WriteXmlElement(writer, trustConstants.Elements.AuthenticationType, rstr.AuthenticationType, rstr, context);
            }

            if (!string.IsNullOrEmpty(rstr.EncryptionAlgorithm))
            {
                responseSerializer.WriteXmlElement(writer, trustConstants.Elements.EncryptionAlgorithm, rstr.EncryptionAlgorithm, rstr, context);
            }

            if (!string.IsNullOrEmpty(rstr.CanonicalizationAlgorithm))
            {
                responseSerializer.WriteXmlElement(writer, trustConstants.Elements.CanonicalizationAlgorithm, rstr.CanonicalizationAlgorithm, rstr, context);
            }

            if (!string.IsNullOrEmpty(rstr.SignatureAlgorithm))
            {
                responseSerializer.WriteXmlElement(writer, trustConstants.Elements.SignatureAlgorithm, rstr.SignatureAlgorithm, rstr, context);
            }

            if (rstr.BinaryExchange != null)
            {
                responseSerializer.WriteXmlElement(writer, trustConstants.Elements.BinaryExchange, rstr.BinaryExchange, rstr, context);
            }

            if (rstr.Status != null)
            {
                responseSerializer.WriteXmlElement(writer, trustConstants.Elements.Status, rstr.Status, rstr, context);
            }

            if (rstr.RequestedTokenCancelled)
            {
                responseSerializer.WriteXmlElement(writer, trustConstants.Elements.RequestedTokenCancelled, rstr.RequestedTokenCancelled, rstr, context);
            }
        }
        public static void WriteResponse(RequestSecurityTokenResponse response, XmlWriter writer, WSTrustSerializationContext context, WSTrustResponseSerializer responseSerializer, WSTrustConstantsAdapter trustConstants)
        {
            if (response == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("response");
            }

            if (writer == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
            }

            if (context == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
            }

            if (responseSerializer == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("responseSerializer");
            }

            if (trustConstants == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("trustConstants");
            }

            responseSerializer.Validate(response);

            // Step 1: Write RSTR start element
            writer.WriteStartElement(trustConstants.Prefix, trustConstants.Elements.RequestSecurityTokenResponse, trustConstants.NamespaceURI);

            // Step 2: Write known RSTR attributes, i.e. Context
            if (!string.IsNullOrEmpty(response.Context))
            {
                writer.WriteAttributeString(trustConstants.Attributes.Context, response.Context);
            }

            // Step 3: Write known RSTR elements
            responseSerializer.WriteKnownResponseElement(response, writer, context);

            // Step 4: Write custom RSTR elements
            foreach (KeyValuePair<string, object> messageParam in response.Properties)
            {
                responseSerializer.WriteXmlElement(writer, messageParam.Key, messageParam.Value, response, context);
            }

            // Step 5: Write RSTR end element to close it
            writer.WriteEndElement();
        }
        public static RequestSecurityTokenResponse CreateResponse(XmlReader reader, WSTrustSerializationContext context, WSTrustResponseSerializer responseSerializer, WSTrustConstantsAdapter trustConstants)
        {
            if (reader == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
            }

            if (context == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
            }

            if (responseSerializer == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("responseSerializer");
            }

            if (trustConstants == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("trustConstants");
            }

            if (!reader.IsStartElement(trustConstants.Elements.RequestSecurityTokenResponse, trustConstants.NamespaceURI))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new WSTrustSerializationException(SR.GetString(SR.ID3032, reader.LocalName, reader.NamespaceURI, trustConstants.Elements.RequestSecurityTokenResponse, trustConstants.NamespaceURI)));
            }

            RequestSecurityTokenResponse rstr = responseSerializer.CreateInstance();
            bool isEmptyElement = reader.IsEmptyElement;
            rstr.Context = reader.GetAttribute(trustConstants.Attributes.Context);

            reader.Read();
            if (!isEmptyElement)
            {
                while (reader.IsStartElement())
                {
                    responseSerializer.ReadXmlElement(reader, rstr, context);
                }

                reader.ReadEndElement();
            }

            responseSerializer.Validate(rstr);

            return rstr;
        }