protected override IProtocolMessage RequestCore(IDirectedProtocolMessage request)
        {
            this.ProcessMessageFilter(request, true);

            // Drop the outgoing message in the other channel's in-slot and let them know it's there.
            this.RemoteChannel.PostMessage(request);

            // Now wait for a response...
            MessageReceivingEndpoint     recipient;
            WebHeaderCollection          headers;
            IDictionary <string, string> responseData = this.AwaitIncomingMessage(out recipient, out headers);

            ErrorUtilities.VerifyInternal(recipient == null, "The recipient is expected to be null for direct responses.");

            // And deserialize it.
            IDirectResponseProtocolMessage responseMessage = this.MessageFactory.GetNewResponseMessage(request, responseData);

            if (responseMessage == null)
            {
                return(null);
            }

            var responseAccessor = this.MessageDescriptions.GetAccessor(responseMessage);

            responseAccessor.Deserialize(responseData);
            var responseMessageHttpRequest = responseMessage as IHttpDirectRequest;

            if (headers != null && responseMessageHttpRequest != null)
            {
                headers.ApplyTo(responseMessageHttpRequest.Headers);
            }

            this.ProcessMessageFilter(responseMessage, false);
            return(responseMessage);
        }
예제 #2
0
        /// <summary>
        /// Submits a direct request message to some remote party and blocks waiting for an immediately reply.
        /// </summary>
        /// <param name="request">The request message.</param>
        /// <returns>The response message, or null if the response did not carry a message.</returns>
        /// <remarks>
        /// Typically a deriving channel will override <see cref="CreateHttpRequest"/> to customize this method's
        /// behavior.  However in non-HTTP frameworks, such as unit test mocks, it may be appropriate to override
        /// this method to eliminate all use of an HTTP transport.
        /// </remarks>
        protected virtual IProtocolMessage RequestInternal(IDirectedProtocolMessage request)
        {
            HttpWebRequest webRequest = this.CreateHttpRequest(request);
            IDictionary <string, string> responseFields;

            using (DirectWebResponse response = this.GetDirectResponse(webRequest)) {
                if (response.ResponseStream == null)
                {
                    return(null);
                }

                responseFields = this.ReadFromResponseInternal(response);
            }

            IDirectResponseProtocolMessage responseMessage = this.MessageFactory.GetNewResponseMessage(request, responseFields);

            if (responseMessage == null)
            {
                return(null);
            }

            var responseSerializer = MessageSerializer.Get(responseMessage.GetType());

            responseSerializer.Deserialize(responseFields, responseMessage);

            return(responseMessage);
        }
		/// <summary>
		/// Initializes a new instance of the <see cref="ProtocolFaultResponseException"/> class
		/// such that it can be sent as a protocol message response to a remote caller.
		/// </summary>
		/// <param name="channel">The channel to use when encoding the response message.</param>
		/// <param name="errorResponse">The message to send back to the HTTP client.</param>
		/// <param name="faultedMessage">The message that was the cause of the exception.  May be null.</param>
		/// <param name="innerException">The inner exception.</param>
		/// <param name="message">The message for the exception.</param>
		protected internal ProtocolFaultResponseException(Channel channel, IDirectResponseProtocolMessage errorResponse, IProtocolMessage faultedMessage = null, Exception innerException = null, string message = null)
			: base(message ?? (innerException != null ? innerException.Message : null), faultedMessage, innerException) {
			Requires.NotNull(channel, "channel");
			Requires.NotNull(errorResponse, "errorResponse");
			this.channel = channel;
			this.ErrorResponseMessage = errorResponse;
		}
 /// <summary>
 /// Initializes a new instance of the <see cref="ProtocolFaultResponseException"/> class
 /// such that it can be sent as a protocol message response to a remote caller.
 /// </summary>
 /// <param name="channel">The channel to use when encoding the response message.</param>
 /// <param name="errorResponse">The message to send back to the HTTP client.</param>
 /// <param name="faultedMessage">The message that was the cause of the exception.  May be null.</param>
 /// <param name="innerException">The inner exception.</param>
 /// <param name="message">The message for the exception.</param>
 protected internal ProtocolFaultResponseException(Channel channel, IDirectResponseProtocolMessage errorResponse, IProtocolMessage faultedMessage = null, Exception innerException = null, string message = null)
     : base(message ?? (innerException != null ? innerException.Message : null), faultedMessage, innerException)
 {
     Requires.NotNull(channel, "channel");
     Requires.NotNull(errorResponse, "errorResponse");
     this.channel = channel;
     this.ErrorResponseMessage = errorResponse;
 }
예제 #5
0
        public void SingleResponseMessageType()
        {
            this.factory.AddMessageTypes(new MessageDescription[] { MessageDescriptions.Get(typeof(DirectResponseMessageMock), V1) });
            var fields = new Dictionary <string, string> {
                { "random", "bits" },
            };
            IDirectedProtocolMessage request = new RequestMessageMock(receiver.Location, V1);

            Assert.IsNull(this.factory.GetNewResponseMessage(request, fields));
            fields["Age"] = "18";
            IDirectResponseProtocolMessage response = this.factory.GetNewResponseMessage(request, fields);

            Assert.IsInstanceOf <DirectResponseMessageMock>(response);
            Assert.AreSame(request, response.OriginatingRequest);

            // Verify that we can instantiate a response with a derived-type of an expected request message.
            request  = new TestSignedDirectedMessage();
            response = this.factory.GetNewResponseMessage(request, fields);
            Assert.IsInstanceOf <DirectResponseMessageMock>(response);
            Assert.AreSame(request, response.OriginatingRequest);
        }
예제 #6
0
		/// <summary>
		/// Called when receiving a direct response message, before deserialization begins.
		/// </summary>
		/// <param name="response">The HTTP direct response.</param>
		/// <param name="message">The newly instantiated message, prior to deserialization.</param>
		protected override void OnReceivingDirectResponse(HttpResponseMessage response, IDirectResponseProtocolMessage message) {
			base.OnReceivingDirectResponse(response, message);

			// Verify that the expected HTTP status code was used for the message,
			// per OpenID 2.0 section 5.1.2.2.
			// Note: The v1.1 spec doesn't require 400 responses for some error messages
			if (message.Version.Major >= 2) {
				var httpDirectResponse = message as IHttpDirectResponse;
				if (httpDirectResponse != null) {
					ErrorUtilities.VerifyProtocol(
						httpDirectResponse.HttpStatusCode == response.StatusCode,
						MessagingStrings.UnexpectedHttpStatusCode,
						(int)httpDirectResponse.HttpStatusCode,
						(int)response.StatusCode);
				}
			}
		}
예제 #7
0
		/// <summary>
		/// Checks the incoming HTTP request for an access token request and prepares a response if the request message was found.
		/// </summary>
		/// <param name="httpRequestInfo">The HTTP request info.</param>
		/// <param name="response">The formulated response, or <c>null</c> if the request was not found..</param>
		/// <returns>A value indicating whether any access token request was found in the HTTP request.</returns>
		/// <remarks>
		/// This method assumes that the authorization server and the resource server are the same and that they share a single
		/// asymmetric key for signing and encrypting the access token.  If this is not true, use the <see cref="ReadAccessTokenRequest"/> method instead.
		/// </remarks>
		public bool TryPrepareAccessTokenResponse(HttpRequestInfo httpRequestInfo, out IDirectResponseProtocolMessage response) {
			Contract.Requires<ArgumentNullException>(httpRequestInfo != null);
			Contract.Ensures(Contract.Result<bool>() == (Contract.ValueAtReturn<IDirectResponseProtocolMessage>(out response) != null));

			var request = this.ReadAccessTokenRequest(httpRequestInfo);
			if (request != null) {
				response = this.PrepareAccessTokenResponse(request);
				return true;
			}

			response = null;
			return false;
		}
예제 #8
0
		/// <summary>
		/// Checks the incoming HTTP request for an access token request and prepares a response if the request message was found.
		/// </summary>
		/// <param name="response">The formulated response, or <c>null</c> if the request was not found..</param>
		/// <returns>A value indicating whether any access token request was found in the HTTP request.</returns>
		/// <remarks>
		/// This method assumes that the authorization server and the resource server are the same and that they share a single
		/// asymmetric key for signing and encrypting the access token.  If this is not true, use the <see cref="ReadAccessTokenRequest"/> method instead.
		/// </remarks>
		public bool TryPrepareAccessTokenResponse(out IDirectResponseProtocolMessage response) {
			return this.TryPrepareAccessTokenResponse(this.Channel.GetRequestFromContext(), out response);
		}
예제 #9
0
 protected virtual void OnReceivingDirectResponse(HttpResponseMessage response, IDirectResponseProtocolMessage message)
 {
 }
예제 #10
0
        /// <summary>
        /// Called when receiving a direct response message, before deserialization begins.
        /// </summary>
        /// <param name="response">The HTTP direct response.</param>
        /// <param name="message">The newly instantiated message, prior to deserialization.</param>
        protected override void OnReceivingDirectResponse(IncomingWebResponse response, IDirectResponseProtocolMessage message)
        {
            base.OnReceivingDirectResponse(response, message);

            // Verify that the expected HTTP status code was used for the message,
            // per OpenID 2.0 section 5.1.2.2.
            // Note: The v1.1 spec doesn't require 400 responses for some error messages
            if (message.Version.Major >= 2)
            {
                var httpDirectResponse = message as IHttpDirectResponse;
                if (httpDirectResponse != null)
                {
                    ErrorUtilities.VerifyProtocol(
                        httpDirectResponse.HttpStatusCode == response.Status,
                        MessagingStrings.UnexpectedHttpStatusCode,
                        (int)httpDirectResponse.HttpStatusCode,
                        (int)response.Status);
                }
            }
        }
		/// <summary>
		/// Checks the incoming HTTP request for an access token request and prepares a response if the request message was found.
		/// </summary>
		/// <param name="httpRequestInfo">The HTTP request info.</param>
		/// <param name="response">The formulated response, or <c>null</c> if the request was not found..</param>
		/// <returns>A value indicating whether any access token request was found in the HTTP request.</returns>
		/// <remarks>
		/// This method assumes that the authorization server and the resource server are the same and that they share a single
		/// asymmetric key for signing and encrypting the access token.  If this is not true, use the <see cref="ReadAccessTokenRequest"/> method instead.
		/// </remarks>
		public bool TryPrepareAccessTokenResponse(HttpRequestInfo httpRequestInfo, out IDirectResponseProtocolMessage response) {
			Contract.Requires<ArgumentNullException>(httpRequestInfo != null);
			Contract.Ensures(Contract.Result<bool>() == (Contract.ValueAtReturn<IDirectResponseProtocolMessage>(out response) != null));

			var request = this.ReadAccessTokenRequest(httpRequestInfo);
			if (request != null) {
				// This convenience method only encrypts access tokens assuming that this auth server
				// doubles as the resource server.
				using (var resourceServerPublicKey = this.AuthorizationServerServices.CreateAccessTokenSigningCryptoServiceProvider()) {
					response = this.PrepareAccessTokenResponse(request, resourceServerPublicKey);
				}

				return true;
			}

			response = null;
			return false;
		}
 /// <summary>
 /// Determines whether the specified message is a direct response.
 /// </summary>
 /// <param name="message">The message in question.</param>
 /// <returns>
 ///     <c>true</c> if the specified message is a direct response; otherwise, <c>false</c>.
 /// </returns>
 /// <remarks>
 /// Although an <see cref="IProtocolMessage"/> may implement the
 /// <see cref="IDirectResponseProtocolMessage"/> interface, it may only be doing
 /// that for its derived classes.  These objects are only requests if their
 /// <see cref="IDirectResponseProtocolMessage.OriginatingRequest"/> property is non-null.
 /// </remarks>
 internal static bool IsDirectResponse(this IDirectResponseProtocolMessage message)
 {
     ErrorUtilities.VerifyArgumentNotNull(message, "message");
     return(message.OriginatingRequest != null);
 }
예제 #13
0
 /// <summary>
 /// Determines whether the specified message is a direct response.
 /// </summary>
 /// <param name="message">The message in question.</param>
 /// <returns>
 ///     <c>true</c> if the specified message is a direct response; otherwise, <c>false</c>.
 /// </returns>
 /// <remarks>
 /// Although an <see cref="IProtocolMessage"/> may implement the
 /// <see cref="IDirectResponseProtocolMessage"/> interface, it may only be doing
 /// that for its derived classes.  These objects are only requests if their
 /// <see cref="IDirectResponseProtocolMessage.OriginatingRequest"/> property is non-null.
 /// </remarks>
 internal static bool IsDirectResponse(this IDirectResponseProtocolMessage message)
 {
     Contract.Requires <ArgumentNullException>(message != null);
     return(message.OriginatingRequest != null);
 }