/// <summary>
        /// Initializes a new instance of the <see cref="AutoResponsiveRequest"/> class.
        /// </summary>
        /// <param name="request">The request message.</param>
        /// <param name="response">The response that is ready for transmittal.</param>
        internal AutoResponsiveRequest(IDirectedProtocolMessage request, IProtocolMessage response)
            : base(request)
        {
            ErrorUtilities.VerifyArgumentNotNull(response, "response");

            this.response = response;
        }
        public void ReadFromRequestAuthorizationScattered()
        {
            // Start by creating a standard POST HTTP request.
            var postedFields = new Dictionary <string, string> {
                { "age", "15" },
            };

            // Now add another field to the request URL
            var builder = new UriBuilder(MessagingTestBase.DefaultUrlForHttpRequestInfo);

            builder.Query = "Name=Andrew";

            // Finally, add an Authorization header
            var authHeaderFields = new Dictionary <string, string> {
                { "Location", "http://hostb/pathB" },
                { "Timestamp", XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.Utc) },
            };
            var headers = new NameValueCollection();

            headers.Add(HttpRequestHeaders.Authorization, CreateAuthorizationHeader(authHeaderFields));
            headers.Add(HttpRequestHeaders.ContentType, Channel.HttpFormUrlEncoded);

            var requestInfo = new HttpRequestInfo("POST", builder.Uri, form: postedFields.ToNameValueCollection(), headers: headers);

            IDirectedProtocolMessage requestMessage = this.channel.ReadFromRequest(requestInfo);

            Assert.IsNotNull(requestMessage);
            Assert.IsInstanceOf <TestMessage>(requestMessage);
            TestMessage testMessage = (TestMessage)requestMessage;

            Assert.AreEqual(15, testMessage.Age);
            Assert.AreEqual("Andrew", testMessage.Name);
            Assert.AreEqual("http://hostb/pathB", testMessage.Location.AbsoluteUri);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="AutoResponsiveRequest"/> class.
        /// </summary>
        /// <param name="provider">The provider that received the request message.</param>
        /// <param name="request">The request message.</param>
        /// <param name="response">The response that is ready for transmittal.</param>
        internal AutoResponsiveRequest(OpenIdProvider provider, IDirectedProtocolMessage request, IProtocolMessage response)
            : base(provider, request)
        {
            ErrorUtilities.VerifyArgumentNotNull(response, "response");

            this.response = response;
        }
示例#4
0
        /// <summary>
        /// Initializes a web request for sending by attaching a message to it.
        /// Use this method to prepare a protected resource request that you do NOT
        /// expect an OAuth message response to.
        /// </summary>
        /// <param name="request">The message to attach.</param>
        /// <returns>The initialized web request.</returns>
        internal HttpWebRequest InitializeRequest(IDirectedProtocolMessage request)
        {
            Contract.Requires <ArgumentNullException>(request != null);

            ProcessOutgoingMessage(request);
            return(this.CreateHttpRequest(request));
        }
        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);
        }
        protected virtual MessageDescription GetMessageDescription(IDirectedProtocolMessage request, IDictionary <string, string> fields)
        {
            var matches = (from responseMessageType in this.responseMessageTypes
                           let messge = responseMessageType.Key
                                        where messge.CheckMessagePartsPassBasicValidation(fields)
                                        let ctors = this.FindMatchingResponseConstructors(messge, request.GetType())
                                                    where ctors.Any()
                                                    orderby GetDerivationDistance(ctors.First().GetParameters()[0].ParameterType, request.GetType()),
                           CountInCommon(messge.Mapping.Keys, fields.Keys) descending,
                           messge.Mapping.Count descending
                           select messge).CacheGeneratedResults();
            var match = matches.FirstOrDefault();

            if (match != null)
            {
                if (Logger.Messaging.IsWarnEnabled() && matches.Count() > 1)
                {
                    Logger.Messaging.WarnFormat(
                        "Multiple message types seemed to fit the incoming data: {0}",
                        matches.ToStringDeferred());
                }

                return(match);
            }
            else
            {
                return(null);
            }
        }
        /// <summary>
        /// Creates a web request prepared with OAuth authorization
        /// that may be further tailored by adding parameters by the caller.
        /// </summary>
        /// <param name="endpoint">The URL and method on the Service Provider to send the request to.</param>
        /// <param name="accessToken">The access token that permits access to the protected resource.</param>
        /// <returns>The initialized WebRequest object.</returns>
        public WebRequest PrepareAuthorizedRequest(MessageReceivingEndpoint endpoint, string accessToken)
        {
            IDirectedProtocolMessage message = this.CreateAuthorizingMessage(endpoint, accessToken);
            HttpWebRequest           wr      = this.OAuthChannel.InitializeRequest(message);

            return(wr);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="AutoResponsiveRequest"/> class.
        /// </summary>
        /// <param name="request">The request message.</param>
        /// <param name="response">The response that is ready for transmittal.</param>
        /// <param name="securitySettings">The security settings.</param>
        internal AutoResponsiveRequest(IDirectedProtocolMessage request, IProtocolMessage response, ProviderSecuritySettings securitySettings)
            : base(request, securitySettings)
        {
            ErrorUtilities.VerifyArgumentNotNull(response, "response");

            this.response = response;
        }
示例#9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DirectResponseBase"/> class.
        /// </summary>
        /// <param name="responseVersion">The OpenID version of the response message.</param>
        /// <param name="originatingRequest">The originating request.  May be null in case the request is unrecognizable and this is an error response.</param>
        protected DirectResponseBase(Version responseVersion, IDirectedProtocolMessage originatingRequest)
        {
            Contract.Requires <ArgumentNullException>(responseVersion != null);

            this.Version            = responseVersion;
            this.originatingRequest = originatingRequest;
        }
		/// <summary>
		/// Analyzes an incoming request message payload to discover what kind of 
		/// message is embedded in it and returns the type, or null if no match is found.
		/// </summary>
		/// <param name="request">
		/// The message that was sent as a request that resulted in the response.
		/// Null on a Consumer site that is receiving an indirect message from the Service Provider.
		/// </param>
		/// <param name="fields">The name/value pairs that make up the message payload.</param>
		/// <returns>
		/// A newly instantiated <see cref="IProtocolMessage"/>-derived object that this message can
		/// deserialize to.  Null if the request isn't recognized as a valid protocol message.
		/// </returns>
		/// <remarks>
		/// The response messages are:
		/// UnauthorizedTokenResponse
		/// AuthorizedTokenResponse
		/// </remarks>
		public virtual IDirectResponseProtocolMessage GetNewResponseMessage(IDirectedProtocolMessage request, IDictionary<string, string> fields) {
			MessageBase message = null;

			// All response messages have the oauth_token field.
			if (!fields.ContainsKey("oauth_token")) {
				return null;
			}

			// All direct message responses should have the oauth_token_secret field.
			if (!fields.ContainsKey("oauth_token_secret")) {
				Logger.OAuth.Error("An OAuth message was expected to contain an oauth_token_secret but didn't.");
				return null;
			}

			var unauthorizedTokenRequest = request as UnauthorizedTokenRequest;
			var authorizedTokenRequest = request as AuthorizedTokenRequest;
			if (unauthorizedTokenRequest != null) {
				Protocol protocol = fields.ContainsKey("oauth_callback_confirmed") ? Protocol.V10a : Protocol.V10;
				message = new UnauthorizedTokenResponse(unauthorizedTokenRequest, protocol.Version);
			} else if (authorizedTokenRequest != null) {
				message = new AuthorizedTokenResponse(authorizedTokenRequest);
			} else {
				Logger.OAuth.ErrorFormat("Unexpected response message given the request type {0}", request.GetType().Name);
				throw new ProtocolException(OAuthStrings.InvalidIncomingMessage);
			}

			if (message != null) {
				message.SetAsIncoming();
			}

			return message;
		}
示例#11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DirectResponseBase"/> class.
        /// </summary>
        /// <param name="responseVersion">The OpenID version of the response message.</param>
        /// <param name="originatingRequest">The originating request.  May be null in case the request is unrecognizable and this is an error response.</param>
        protected DirectResponseBase(Version responseVersion, IDirectedProtocolMessage originatingRequest)
        {
            ErrorUtilities.VerifyArgumentNotNull(responseVersion, "responseVersion");

            this.Version            = responseVersion;
            this.originatingRequest = originatingRequest;
        }
示例#12
0
        /// <summary>
        /// Creates a web request prepared with OAuth authorization
        /// that may be further tailored by adding parameters by the caller.
        /// </summary>
        /// <param name="endpoint">The URL and method on the Service Provider to send the request to.</param>
        /// <param name="accessToken">The access token that permits access to the protected resource.</param>
        /// <returns>The initialized WebRequest object.</returns>
        /// <exception cref="WebException">Thrown if the request fails for any reason after it is sent to the Service Provider.</exception>
        public IncomingWebResponse PrepareAuthorizedRequestAndSend(MessageReceivingEndpoint endpoint, string accessToken)
        {
            IDirectedProtocolMessage message = this.CreateAuthorizingMessage(endpoint, accessToken);
            HttpWebRequest           wr      = this.OAuthChannel.InitializeRequest(message);

            return(this.Channel.WebRequestHandler.GetResponse(wr));
        }
示例#13
0
        /// <summary>
        /// Initializes a web request for sending by attaching a message to it.
        /// Use this method to prepare a protected resource request that you do NOT
        /// expect an OAuth message response to.
        /// </summary>
        /// <param name="request">The message to attach.</param>
        /// <returns>The initialized web request.</returns>
        internal HttpWebRequest InitializeRequest(IDirectedProtocolMessage request)
        {
            ErrorUtilities.VerifyArgumentNotNull(request, "request");

            PrepareMessageForSending(request);
            return(this.CreateHttpRequest(request));
        }
示例#14
0
        protected virtual HttpResponseMessage CreateFormPostResponse(IDirectedProtocolMessage message, IDictionary <string, string> fields)
        {
            using (StringWriter bodyWriter = new StringWriter(CultureInfo.InvariantCulture))
            {
                StringBuilder hiddenFields = new StringBuilder();
                foreach (var field in fields)
                {
                    hiddenFields.AppendFormat("\t<input type=\"hidden\" name=\"{0}\" value=\"{1}\" />\r\n", HttpUtility.HtmlEncode(field.Key), HttpUtility.HtmlEncode(field.Value));
                }
                bodyWriter.WriteLine(
                    IndirectMessageFormPostFormat,
                    HttpUtility.HtmlEncode(message.Recipient.AbsoluteUri),
                    hiddenFields
                    );
                bodyWriter.Flush();
                HttpResponseMessage response = new HttpResponseMessageWithOriginal(message)
                {
                    StatusCode = HttpStatusCode.OK,
                    Content    = new StringContent(bodyWriter.ToString())
                };
                response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("text/html");

                return(response);
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="AutoResponsiveRequest"/> class.
        /// </summary>
        /// <param name="request">The request message.</param>
        /// <param name="response">The response that is ready for transmittal.</param>
        /// <param name="securitySettings">The security settings.</param>
        internal AutoResponsiveRequest(IDirectedProtocolMessage request, IProtocolMessage response, ProviderSecuritySettings securitySettings)
            : base(request, securitySettings)
        {
            Contract.Requires <ArgumentNullException>(response != null);

            this.response = response;
        }
示例#16
0
        public IDirectResponseProtocolMessage GetNewResponseMessage(IDirectedProtocolMessage request, IDictionary <string, string> fields)
        {
            TestMessage message = (TestMessage)this.GetNewRequestMessage(null, fields);

            message.OriginatingRequest = request;
            return(message);
        }
示例#17
0
        public void ReadFromRequestAuthorizationScattered()
        {
            // Start by creating a standard POST HTTP request.
            var fields = new Dictionary <string, string> {
                { "age", "15" },
            };
            HttpRequestInfo requestInfo = CreateHttpRequestInfo(HttpDeliveryMethods.PostRequest, fields);

            // Now add another field to the request URL
            UriBuilder builder = new UriBuilder(requestInfo.UrlBeforeRewriting);

            builder.Query = "Name=Andrew";
            requestInfo.UrlBeforeRewriting = builder.Uri;
            requestInfo.RawUrl             = builder.Path + builder.Query + builder.Fragment;

            // Finally, add an Authorization header
            fields = new Dictionary <string, string> {
                { "Location", "http://hostb/pathB" },
                { "Timestamp", XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.Utc) },
            };
            requestInfo.Headers.Add(HttpRequestHeader.Authorization, CreateAuthorizationHeader(fields));

            IDirectedProtocolMessage requestMessage = this.channel.ReadFromRequest(requestInfo);

            Assert.IsNotNull(requestMessage);
            Assert.IsInstanceOf <TestMessage>(requestMessage);
            TestMessage testMessage = (TestMessage)requestMessage;

            Assert.AreEqual(15, testMessage.Age);
            Assert.AreEqual("Andrew", testMessage.Name);
            Assert.AreEqual("http://hostb/pathB", testMessage.Location.AbsoluteUri);
        }
		/// <summary>
		/// Reads an access token to find out what data it authorizes access to.
		/// </summary>
		/// <param name="message">The message carrying the access token.</param>
		/// <param name="accessToken">The access token.</param>
		/// <param name="user">The user whose data is accessible with this access token.</param>
		/// <param name="scope">The scope of access authorized by this access token.</param>
		/// <returns>
		/// A value indicating whether this access token is valid.
		/// </returns>
		/// <remarks>
		/// This method also responsible to throw a <see cref="ProtocolException"/> or return
		/// <c>false</c> when the access token is expired, invalid, or from an untrusted authorization server.
		/// </remarks>
		public virtual bool TryValidateAccessToken(IDirectedProtocolMessage message, string accessToken, out string user, out HashSet<string> scope) {
			var accessTokenFormatter = AccessToken.CreateFormatter(this.AuthorizationServerPublicSigningKey, this.ResourceServerPrivateEncryptionKey);
			var token = accessTokenFormatter.Deserialize(message, accessToken);
			user = token.User;
			scope = new HashSet<string>(token.Scope, OAuthUtilities.ScopeStringComparer);
			return true;
		}
示例#19
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>
        /// Gets the message type that best fits the given incoming direct response data.
        /// </summary>
        /// <param name="request">The request message that prompted the response data.</param>
        /// <param name="fields">The data of the incoming message.</param>
        /// <returns>
        /// The message type that matches the incoming data; or <c>null</c> if no match.
        /// </returns>
        /// <exception cref="ProtocolException">May be thrown if the incoming data is ambiguous.</exception>
        protected virtual MessageDescription GetMessageDescription(IDirectedProtocolMessage request, IDictionary <string, string> fields)
        {
            Requires.NotNull(request, "request");
            Requires.NotNull(fields, "fields");

            var matches = (from responseMessageType in this.responseMessageTypes
                           let message = responseMessageType.Key
                                         where message.CheckMessagePartsPassBasicValidation(fields)
                                         let ctors = this.FindMatchingResponseConstructors(message, request.GetType())
                                                     where ctors.Any()
                                                     orderby GetDerivationDistance(ctors.First().GetParameters()[0].ParameterType, request.GetType()),
                           CountInCommon(message.Mapping.Keys, fields.Keys) descending,
                           message.Mapping.Count descending
                           select message).CacheGeneratedResults();
            var match = matches.FirstOrDefault();

            if (match != null)
            {
                return(match);
            }
            else
            {
                // No message type matches the incoming data.
                return(null);
            }
        }
示例#21
0
 /// <summary>
 /// Reads an access token to find out what data it authorizes access to.
 /// </summary>
 /// <param name="message">The message carrying the access token.</param>
 /// <param name="accessToken">The access token's serialized representation.</param>
 /// <returns>The deserialized, validated token.</returns>
 /// <exception cref="ProtocolException">Thrown if the access token is expired, invalid, or from an untrusted authorization server.</exception>
 AccessToken IAccessTokenAnalyzer.DeserializeAccessToken(IDirectedProtocolMessage message, string accessToken)
 {
     Requires.NotNull(message, "message");
     Requires.NotNullOrEmpty(accessToken, "accessToken");
     Contract.Ensures(Contract.Result <AccessToken>() != null);
     throw new NotImplementedException();
 }
示例#22
0
        /// <summary>
        /// Analyzes an incoming request message payload to discover what kind of
        /// message is embedded in it and returns the type, or null if no match is found.
        /// </summary>
        /// <param name="request">The message that was sent as a request that resulted in the response.</param>
        /// <param name="fields">The name/value pairs that make up the message payload.</param>
        /// <returns>
        /// A newly instantiated <see cref="IProtocolMessage"/>-derived object that this message can
        /// deserialize to.  Null if the request isn't recognized as a valid protocol message.
        /// </returns>
        public IDirectResponseProtocolMessage GetNewResponseMessage(IDirectedProtocolMessage request, IDictionary <string, string> fields)
        {
            DirectResponseBase message = null;

            // Discern the OpenID version of the message.
            Protocol protocol = Protocol.V11;
            string   ns;

            if (fields.TryGetValue(Protocol.V20.openidnp.ns, out ns))
            {
                ErrorUtilities.VerifyProtocol(string.Equals(ns, Protocol.OpenId2Namespace, StringComparison.Ordinal), MessagingStrings.UnexpectedMessagePartValue, Protocol.V20.openidnp.ns, ns);
                protocol = Protocol.V20;
            }

            // Handle error messages generally.
            if (fields.ContainsKey(protocol.openidnp.error))
            {
                message = new DirectErrorResponse(protocol.Version, request);
            }

            var associateRequest = request as AssociateRequest;

            if (associateRequest != null)
            {
                if (protocol.Version.Major >= 2 && fields.ContainsKey(protocol.openidnp.error_code))
                {
                    // This is a special recognized error case that we create a special message for.
                    message = new AssociateUnsuccessfulResponse(protocol.Version, associateRequest);
                }
                else if (message == null)
                {
                    var associateDiffieHellmanRequest = request as AssociateDiffieHellmanRequest;
                    var associateUnencryptedRequest   = request as AssociateUnencryptedRequest;

                    if (associateDiffieHellmanRequest != null)
                    {
                        message = new AssociateDiffieHellmanResponse(protocol.Version, associateDiffieHellmanRequest);
                    }

                    if (associateUnencryptedRequest != null)
                    {
                        message = new AssociateUnencryptedResponse(protocol.Version, associateUnencryptedRequest);
                    }
                }
            }

            var checkAuthenticationRequest = request as CheckAuthenticationRequest;

            if (checkAuthenticationRequest != null && message == null)
            {
                message = new CheckAuthenticationResponse(protocol.Version, checkAuthenticationRequest);
            }

            if (message != null)
            {
                message.SetAsIncoming();
            }

            return(message);
        }
示例#23
0
        /// <summary>
        /// HttpRequestMessage转换为IDirectedProtocolMessage,填充HttpRequestMessage参数值
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        protected virtual IDirectedProtocolMessage ReadFromRequestCoreAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            Logger.Channel.DebugFormat("Incoming HTTP request: {0} {1}", request.Method, request.RequestUri.AbsoluteUri);
            var fields = new Dictionary <string, string>();

            fields.AddRange(ParseUrlEncodedFormContentAsync(request, cancellationToken));
            if (fields.Count == 0 && request.Method.Method != "POST")
            {
                fields.AddRange(HttpUtility.ParseQueryString(request.RequestUri.Query).AsKeyValuePairs());
            }
            MessageReceivingEndpoint recipient;

            try
            {
                recipient = request.GetRecipient();
            }
            catch (ArgumentException ex)
            {
                Logger.Messaging.WarnFormat("Unrecognized HTTP request: {0}", ex);
                return(null);
            }
            IDirectedProtocolMessage result = null;

            result = (IDirectedProtocolMessage)this.Receive(fields, recipient);

            return(result);
        }
示例#24
0
        /// <summary>
        /// Prepares to send a request to the Service Provider as the payload of a POST request.
        /// </summary>
        /// <param name="requestMessage">The message to be transmitted to the ServiceProvider.</param>
        /// <returns>The web request ready to send.</returns>
        /// <remarks>
        /// This method is simply a standard HTTP POST request with the message parts serialized to the POST entity
        /// with the application/x-www-form-urlencoded content type
        /// This method satisfies OAuth 1.0 section 5.2, item #2 and OpenID 2.0 section 4.1.2.
        /// </remarks>
        protected virtual HttpWebRequest InitializeRequestAsPost(IDirectedProtocolMessage requestMessage)
        {
            ErrorUtilities.VerifyArgumentNotNull(requestMessage, "requestMessage");

            var serializer = MessageSerializer.Get(requestMessage.GetType());
            var fields     = serializer.Serialize(requestMessage);

            HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(requestMessage.Recipient);

            httpRequest.CachePolicy = this.CachePolicy;
            httpRequest.Method      = "POST";
            httpRequest.ContentType = "application/x-www-form-urlencoded";
            httpRequest.Headers[HttpRequestHeader.ContentEncoding] = PostEntityEncoding.WebName;
            string requestBody = MessagingUtilities.CreateQueryString(fields);

            byte[] requestBytes = PostEntityEncoding.GetBytes(requestBody);
            httpRequest.ContentLength = requestBytes.Length;
            Stream requestStream = this.WebRequestHandler.GetRequestStream(httpRequest);

            try {
                requestStream.Write(requestBytes, 0, requestBytes.Length);
            } finally {
                // We need to be sure to close the request stream...
                // unless it is a MemoryStream, which is a clue that we're in
                // a mock stream situation and closing it would preclude reading it later.
                if (!(requestStream is MemoryStream))
                {
                    requestStream.Dispose();
                }
            }

            return(httpRequest);
        }
示例#25
0
        protected virtual HttpRequestMessage InitializeRequestAsPost(IDirectedProtocolMessage requestMessage)
        {
            var messageAccessor = this.MessageDescriptions.GetAccessor(requestMessage);
            var fields          = messageAccessor.Serialize();
            var httpRequest     = new HttpRequestMessage(HttpMethod.Post, requestMessage.Recipient);

            this.PrepareHttpWebRequest(httpRequest);

            var requestMessageWithBinaryData = requestMessage as IMessageWithBinaryData;

            if (requestMessageWithBinaryData != null && requestMessageWithBinaryData.SendAsMultipart)
            {
                var content = InitializeMultipartFormDataContent(requestMessageWithBinaryData);
                foreach (var field in fields)
                {
                    content.Add(new StringContent(field.Value), field.Key);
                }

                httpRequest.Content = content;
            }
            else
            {
                ErrorUtilities.VerifyProtocol(requestMessageWithBinaryData == null || requestMessageWithBinaryData.BinaryData.Count == 0, MessagingStrings.BinaryDataRequiresMultipart);
                httpRequest.Content = new FormUrlEncodedContent(fields);
            }

            return(httpRequest);
        }
		/// <summary>
		/// Reads an access token to find out what data it authorizes access to.
		/// </summary>
		/// <param name="message">The message carrying the access token.</param>
		/// <param name="accessToken">The access token.</param>
		/// <param name="user">The user whose data is accessible with this access token.</param>
		/// <param name="scope">The scope of access authorized by this access token.</param>
		/// <returns>
		/// A value indicating whether this access token is valid.
		/// </returns>
		bool IAccessTokenAnalyzer.TryValidateAccessToken(IDirectedProtocolMessage message, string accessToken, out string user, out HashSet<string> scope) {
			Requires.NotNull(message, "message");
			Requires.NotNullOrEmpty(accessToken, "accessToken");
			Contract.Ensures(Contract.Result<bool>() == (Contract.ValueAtReturn<string>(out user) != null));

			throw new NotImplementedException();
		}
示例#27
0
        protected virtual HttpResponseMessage PrepareIndirectResponse(IDirectedProtocolMessage message)
        {
            Assumes.True(message != null && message.Recipient != null);
            var messageAccessor = this.messageDescriptions.GetAccessor(message);

            Assumes.True(message != null && message.Recipient != null);
            var fields = messageAccessor.Serialize();
            HttpResponseMessage response = null;
            bool tooLargeForGet          = false;

            if ((message.HttpMethods & HttpDeliveryMethods.GetRequest) == HttpDeliveryMethods.GetRequest)
            {
                bool payloadInFragment = false;
                var  httpIndirect      = message as IHttpIndirectResponse;
                if (httpIndirect != null)
                {
                    payloadInFragment = httpIndirect.Include301RedirectPayloadInFragment;
                }
                response       = this.Create301RedirectResponse(message, fields, payloadInFragment);
                tooLargeForGet = response.Headers.Location.PathAndQuery.Length > this.MaximumIndirectMessageUrlLength;
            }
            if (tooLargeForGet)
            {
                ErrorUtilities.VerifyProtocol(
                    (message.HttpMethods & HttpDeliveryMethods.PostRequest) == HttpDeliveryMethods.PostRequest,
                    MessagingStrings.MessageExceedsGetSizePostNotAllowed);
            }
            if (response == null || tooLargeForGet)
            {
                response = this.CreateFormPostResponse(message, fields);
            }

            return(response);
        }
示例#28
0
        /// <summary>
        /// Encodes an HTTP response that will instruct the user agent to forward a message to
        /// some remote third party using a form POST method.
        /// </summary>
        /// <param name="message">The message to forward.</param>
        /// <param name="fields">The pre-serialized fields from the message.</param>
        /// <returns>The encoded HTTP response.</returns>
        protected virtual UserAgentResponse CreateFormPostResponse(IDirectedProtocolMessage message, IDictionary <string, string> fields)
        {
            ErrorUtilities.VerifyArgumentNotNull(message, "message");
            ErrorUtilities.VerifyArgumentNamed(message.Recipient != null, "message", MessagingStrings.DirectedMessageMissingRecipient);
            ErrorUtilities.VerifyArgumentNotNull(fields, "fields");

            WebHeaderCollection headers      = new WebHeaderCollection();
            StringWriter        bodyWriter   = new StringWriter(CultureInfo.InvariantCulture);
            StringBuilder       hiddenFields = new StringBuilder();

            foreach (var field in fields)
            {
                hiddenFields.AppendFormat(
                    "\t<input type=\"hidden\" name=\"{0}\" value=\"{1}\" />\r\n",
                    HttpUtility.HtmlEncode(field.Key),
                    HttpUtility.HtmlEncode(field.Value));
            }
            bodyWriter.WriteLine(
                indirectMessageFormPostFormat,
                HttpUtility.HtmlEncode(message.Recipient.AbsoluteUri),
                hiddenFields);
            bodyWriter.Flush();
            UserAgentResponse response = new UserAgentResponse {
                Status          = HttpStatusCode.OK,
                Headers         = headers,
                Body            = bodyWriter.ToString(),
                OriginalMessage = message
            };

            return(response);
        }
示例#29
0
        /// <summary>
        /// 重定向
        /// </summary>
        /// <param name="message"></param>
        /// <param name="fields"></param>
        /// <param name="payloadInFragment"></param>
        /// <returns></returns>
        protected virtual HttpResponseMessage Create301RedirectResponse(IDirectedProtocolMessage message, IDictionary <string, string> fields, bool payloadInFragment = false)
        {
            UriBuilder builder = new UriBuilder(message.Recipient);

            if (payloadInFragment)
            {
                builder.AppendFragmentArgs(fields);
            }
            else
            {
                builder.AppendQueryArgs(fields);
            }
            Logger.Http.DebugFormat("Redirecting to {0}", builder.Uri.AbsoluteUri);
            HttpResponseMessage response = new HttpResponseMessageWithOriginal(message)
            {
                StatusCode = HttpStatusCode.Redirect,
                Content    = new StringContent(string.Format(CultureInfo.InvariantCulture, RedirectResponseBodyFormat, builder.Uri.AbsoluteUri))
            };

            response.Headers.Location            = builder.Uri;
            response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("text/html")
            {
                CharSet = "utf-8"
            };
            return(response);
        }
        /// <summary>
        /// Initializes a web request for sending by attaching a message to it.
        /// Use this method to prepare a protected resource request that you do NOT
        /// expect an OAuth message response to.
        /// </summary>
        /// <param name="request">The message to attach.</param>
        /// <returns>The initialized web request.</returns>
        internal HttpWebRequest InitializeRequest(IDirectedProtocolMessage request)
        {
            Requires.NotNull(request, "request");

            ProcessOutgoingMessage(request);
            return(this.CreateHttpRequest(request));
        }
示例#31
0
        /// <summary>
        /// Initializes a new instance of the <see cref="AutoResponsiveRequest"/> class.
        /// </summary>
        /// <param name="request">The request message.</param>
        /// <param name="response">The response that is ready for transmittal.</param>
        /// <param name="securitySettings">The security settings.</param>
        internal AutoResponsiveRequest(IDirectedProtocolMessage request, IProtocolMessage response, ProviderSecuritySettings securitySettings)
            : base(request, securitySettings)
        {
            Requires.NotNull(response, "response");

            this.response = response;
        }
示例#32
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DirectResponseBase"/> class.
        /// </summary>
        /// <param name="responseVersion">The OpenID version of the response message.</param>
        /// <param name="originatingRequest">The originating request.  May be null in case the request is unrecognizable and this is an error response.</param>
        protected DirectResponseBase(Version responseVersion, IDirectedProtocolMessage originatingRequest)
        {
            Requires.NotNull(responseVersion, "responseVersion");

            this.Version            = responseVersion;
            this.originatingRequest = originatingRequest;
        }
示例#33
0
        /// <summary>
        /// Prepares an HTTP request that carries a given message.
        /// </summary>
        /// <param name="request">The message to send.</param>
        /// <returns>
        /// The <see cref="HttpRequest"/> prepared to send the request.
        /// </returns>
        protected override HttpWebRequest CreateHttpRequest(IDirectedProtocolMessage request)
        {
            ErrorUtilities.VerifyArgumentNotNull(request, "request");
            ErrorUtilities.VerifyArgumentNamed(request.Recipient != null, "request", MessagingStrings.DirectedMessageMissingRecipient);

            IDirectedProtocolMessage oauthRequest = request as IDirectedProtocolMessage;

            ErrorUtilities.VerifyArgument(oauthRequest != null, MessagingStrings.UnexpectedType, typeof(IDirectedProtocolMessage), request.GetType());

            HttpWebRequest httpRequest;

            HttpDeliveryMethods transmissionMethod = oauthRequest.HttpMethods;

            if ((transmissionMethod & HttpDeliveryMethods.AuthorizationHeaderRequest) != 0)
            {
                httpRequest = this.InitializeRequestAsAuthHeader(request);
            }
            else if ((transmissionMethod & HttpDeliveryMethods.PostRequest) != 0)
            {
                httpRequest = this.InitializeRequestAsPost(request);
            }
            else if ((transmissionMethod & HttpDeliveryMethods.GetRequest) != 0)
            {
                httpRequest = InitializeRequestAsGet(request);
            }
            else
            {
                throw new NotSupportedException();
            }
            return(httpRequest);
        }
示例#34
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MessageBase"/> class for direct response messages.
        /// </summary>
        /// <param name="protectionRequired">The level of protection the message requires.</param>
        /// <param name="originatingRequest">The request that asked for this direct response.</param>
        protected MessageBase(MessageProtections protectionRequired, IDirectedProtocolMessage originatingRequest)
        {
            ErrorUtilities.VerifyArgumentNotNull(originatingRequest, "originatingRequest");

            this.protectionRequired = protectionRequired;
            this.transport          = MessageTransport.Direct;
            this.originatingRequest = originatingRequest;
        }
        /// <summary>
        /// Reads an access token to find out what data it authorizes access to.
        /// </summary>
        /// <param name="message">The message carrying the access token.</param>
        /// <param name="accessToken">The access token's serialized representation.</param>
        /// <returns>The deserialized, validated token.</returns>
        /// <exception cref="ProtocolException">Thrown if the access token is expired, invalid, or from an untrusted authorization server.</exception>
        public virtual AccessToken DeserializeAccessToken(IDirectedProtocolMessage message, string accessToken)
        {
            var accessTokenFormatter = AccessToken.CreateFormatter(this.AuthorizationServerPublicSigningKey, this.ResourceServerPrivateEncryptionKey);
            var token = new AccessToken();

            accessTokenFormatter.Deserialize(token, accessToken, message, Protocol.access_token);
            return(token);
        }
示例#36
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MessageBase"/> class for direct response messages.
        /// </summary>
        /// <param name="protectionRequired">The level of protection the message requires.</param>
        /// <param name="originatingRequest">The request that asked for this direct response.</param>
        protected MessageBase(MessageProtections protectionRequired, IDirectedProtocolMessage originatingRequest)
        {
            ErrorUtilities.VerifyArgumentNotNull(originatingRequest, "originatingRequest");

            this.protectionRequired = protectionRequired;
            this.transport = MessageTransport.Direct;
            this.originatingRequest = originatingRequest;
        }
示例#37
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MessageBase"/> class.
		/// </summary>
		/// <param name="request">The originating request.</param>
		/// <param name="recipient">The recipient of the directed message.  Null if not applicable.</param>
		protected MessageBase(IDirectedProtocolMessage request, Uri recipient = null) {
			Contract.Requires<ArgumentNullException>(request != null);
			this.originatingRequest = request;
			this.messageTransport = request.Transport;
			this.version = request.Version;
			this.Recipient = recipient;
			this.HttpMethods = HttpDeliveryMethods.GetRequest;
		}
示例#38
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MessageBase"/> class.
		/// </summary>
		/// <param name="request">The originating request.</param>
		/// <param name="recipient">The recipient of the directed message.  Null if not applicable.</param>
		protected MessageBase(IDirectedProtocolMessage request, Uri recipient = null) {
			Requires.NotNull(request, "request");
			this.originatingRequest = request;
			this.messageTransport = request.Transport;
			this.version = request.Version;
			this.Recipient = recipient;
			this.HttpMethods = HttpDeliveryMethods.GetRequest;
		}
示例#39
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MessageBase"/> class for direct response messages.
		/// </summary>
		/// <param name="protectionRequired">The level of protection the message requires.</param>
		/// <param name="originatingRequest">The request that asked for this direct response.</param>
		/// <param name="version">The OAuth version.</param>
		protected MessageBase(MessageProtections protectionRequired, IDirectedProtocolMessage originatingRequest, Version version) {
			Requires.NotNull(originatingRequest, "originatingRequest");
			Requires.NotNull(version, "version");

			this.protectionRequired = protectionRequired;
			this.transport = MessageTransport.Direct;
			this.originatingRequest = originatingRequest;
			this.Version = version;
		}
示例#40
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MessageBase"/> class for direct response messages.
		/// </summary>
		/// <param name="protectionRequired">The level of protection the message requires.</param>
		/// <param name="originatingRequest">The request that asked for this direct response.</param>
		/// <param name="version">The OAuth version.</param>
		protected MessageBase(MessageProtections protectionRequired, IDirectedProtocolMessage originatingRequest, Version version) {
			Contract.Requires<ArgumentNullException>(originatingRequest != null);
			Contract.Requires<ArgumentNullException>(version != null);

			this.protectionRequired = protectionRequired;
			this.transport = MessageTransport.Direct;
			this.originatingRequest = originatingRequest;
			this.Version = version;
		}
		/// <summary>
		/// Reads an access token to find out what data it authorizes access to.
		/// </summary>
		/// <param name="message">The message carrying the access token.</param>
		/// <param name="accessToken">The access token's serialized representation.</param>
		/// <returns>The deserialized, validated token.</returns>
		/// <exception cref="ProtocolException">Thrown if the access token is expired, invalid, or from an untrusted authorization server.</exception>
		public virtual AccessToken DeserializeAccessToken(IDirectedProtocolMessage message, string accessToken) {
			ErrorUtilities.VerifyProtocol(!string.IsNullOrEmpty(accessToken), ResourceServerStrings.MissingAccessToken);
			var accessTokenFormatter = AccessToken.CreateFormatter(this.AuthorizationServerPublicSigningKey, this.ResourceServerPrivateEncryptionKey);
			var token = new AccessToken();
			try {
				accessTokenFormatter.Deserialize(token, accessToken, message, Protocol.access_token);
			} catch (IOException ex) {
				throw new ProtocolException(ResourceServerStrings.InvalidAccessToken, ex);
			}

			return token;
		}
示例#42
0
		/// <summary>
		/// Prepares an HTTP request that carries a given message.
		/// </summary>
		/// <param name="request">The message to send.</param>
		/// <returns>
		/// The <see cref="HttpWebRequest"/> prepared to send the request.
		/// </returns>
		/// <remarks>
		/// This method must be overridden by a derived class, unless the <see cref="Channel.RequestCore"/> method
		/// is overridden and does not require this method.
		/// </remarks>
		protected override HttpWebRequest CreateHttpRequest(IDirectedProtocolMessage request) {
			HttpWebRequest httpRequest;
			if ((request.HttpMethods & HttpDeliveryMethods.GetRequest) != 0) {
				httpRequest = InitializeRequestAsGet(request);
			} else if ((request.HttpMethods & HttpDeliveryMethods.PostRequest) != 0) {
				httpRequest = InitializeRequestAsPost(request);
			} else {
				throw new NotSupportedException();
			}

			return httpRequest;
		}
		/// <summary>
		/// Analyzes an incoming request message payload to discover what kind of
		/// message is embedded in it and returns the type, or null if no match is found.
		/// </summary>
		/// <param name="request">The message that was sent as a request that resulted in the response.</param>
		/// <param name="fields">The name/value pairs that make up the message payload.</param>
		/// <returns>
		/// A newly instantiated <see cref="IProtocolMessage"/>-derived object that this message can
		/// deserialize to.  Null if the request isn't recognized as a valid protocol message.
		/// </returns>
		public IDirectResponseProtocolMessage GetNewResponseMessage(IDirectedProtocolMessage request, IDictionary<string, string> fields) {
			DirectResponseBase message = null;

			// Discern the OpenID version of the message.
			Protocol protocol = Protocol.V11;
			string ns;
			if (fields.TryGetValue(Protocol.V20.openidnp.ns, out ns)) {
				ErrorUtilities.VerifyProtocol(string.Equals(ns, Protocol.OpenId2Namespace, StringComparison.Ordinal), MessagingStrings.UnexpectedMessagePartValue, Protocol.V20.openidnp.ns, ns);
				protocol = Protocol.V20;
			}

			// Handle error messages generally.
			if (fields.ContainsKey(protocol.openidnp.error)) {
				message = new DirectErrorResponse(protocol.Version, request);
			}

			var associateRequest = request as AssociateRequest;
			if (associateRequest != null) {
				if (protocol.Version.Major >= 2 && fields.ContainsKey(protocol.openidnp.error_code)) {
					// This is a special recognized error case that we create a special message for.
					message = new AssociateUnsuccessfulResponse(protocol.Version, associateRequest);
				} else if (message == null) {
					if (OpenIdUtilities.IsDiffieHellmanPresent) {
						var associateDiffieHellmanRequest = request as AssociateDiffieHellmanRequest;
						if (associateDiffieHellmanRequest != null) {
							message = new AssociateDiffieHellmanRelyingPartyResponse(protocol.Version, associateDiffieHellmanRequest);
						}
					}

					var associateUnencryptedRequest = request as AssociateUnencryptedRequest;
					if (associateUnencryptedRequest != null) {
						message = new AssociateUnencryptedResponseRelyingParty(protocol.Version, associateUnencryptedRequest);
					}
				}
			}

			var checkAuthenticationRequest = request as CheckAuthenticationRequest;
			if (checkAuthenticationRequest != null && message == null) {
				message = new CheckAuthenticationResponse(protocol.Version, checkAuthenticationRequest);
			}

			if (message != null) {
				message.SetAsIncoming();
			}

			return message;
		}
示例#44
0
		/// <summary>
		/// Scans the incoming request for an authorization response message.
		/// </summary>
		/// <param name="authorizationState">The authorization.</param>
		/// <param name="response">The incoming authorization response message.</param>
		/// <returns>
		/// The granted authorization, or <c>null</c> if the incoming HTTP request did not contain an authorization server response or authorization was rejected.
		/// </returns>
		internal IAuthorizationState ProcessUserAuthorization(IAuthorizationState authorizationState, IDirectedProtocolMessage response) {
			Requires.NotNull(authorizationState, "authorizationState");
			Requires.NotNull(response, "response");

			EndUserAuthorizationSuccessAccessTokenResponse accessTokenSuccess;
			EndUserAuthorizationSuccessAuthCodeResponse authCodeSuccess;
			if ((accessTokenSuccess = response as EndUserAuthorizationSuccessAccessTokenResponse) != null) {
				UpdateAuthorizationWithResponse(authorizationState, accessTokenSuccess);
			} else if ((authCodeSuccess = response as EndUserAuthorizationSuccessAuthCodeResponse) != null) {
				this.UpdateAuthorizationWithResponse(authorizationState, authCodeSuccess);
			} else if (response is EndUserAuthorizationFailedResponse) {
				authorizationState.Delete();
				return null;
			}

			return authorizationState;
		}
		/// <summary>
		/// Analyzes an incoming request message payload to discover what kind of 
		/// message is embedded in it and returns the type, or null if no match is found.
		/// </summary>
		/// <param name="request">
		/// The message that was sent as a request that resulted in the response.
		/// Null on a Consumer site that is receiving an indirect message from the Service Provider.
		/// </param>
		/// <param name="fields">The name/value pairs that make up the message payload.</param>
		/// <returns>
		/// The <see cref="IProtocolMessage"/>-derived concrete class that this message can
		/// deserialize to.  Null if the request isn't recognized as a valid protocol message.
		/// </returns>
		/// <remarks>
		/// The response messages are:
		/// None.
		/// </remarks>
		public virtual IDirectResponseProtocolMessage GetNewResponseMessage(IDirectedProtocolMessage request, IDictionary<string, string> fields) {
			Logger.OAuth.Error("Service Providers are not expected to ever receive responses.");
			return null;
		}
示例#46
0
		/// <summary>
		/// Prepares the return value for the GetRequest method in the event of an exception.
		/// </summary>
		/// <param name="ex">The exception that forms the basis of the error response.  Must not be null.</param>
		/// <param name="httpRequestInfo">The incoming HTTP request.  Must not be null.</param>
		/// <param name="incomingMessage">The incoming message.  May be null in the case that it was malformed.</param>
		/// <returns>
		/// Either the <see cref="IRequest"/> to return to the host site or null to indicate no response could be reasonably created and that the caller should rethrow the exception.
		/// </returns>
		private IRequest GetErrorResponse(ProtocolException ex, HttpRequestInfo httpRequestInfo, IDirectedProtocolMessage incomingMessage) {
			Contract.Requires<ArgumentNullException>(ex != null);
			Contract.Requires<ArgumentNullException>(httpRequestInfo != null);

			Logger.OpenId.Error("An exception was generated while processing an incoming OpenID request.", ex);
			IErrorMessage errorMessage;

			// We must create the appropriate error message type (direct vs. indirect)
			// based on what we see in the request.
			string returnTo = httpRequestInfo.QueryString[Protocol.Default.openid.return_to];
			if (returnTo != null) {
				// An indirect request message from the RP
				// We need to return an indirect response error message so the RP can consume it.
				// Consistent with OpenID 2.0 section 5.2.3.
				var indirectRequest = incomingMessage as SignedResponseRequest;
				if (indirectRequest != null) {
					errorMessage = new IndirectErrorResponse(indirectRequest);
				} else {
					errorMessage = new IndirectErrorResponse(Protocol.Default.Version, new Uri(returnTo));
				}
			} else if (httpRequestInfo.HttpMethod == "POST") {
				// A direct request message from the RP
				// We need to return a direct response error message so the RP can consume it.
				// Consistent with OpenID 2.0 section 5.1.2.2.
				errorMessage = new DirectErrorResponse(Protocol.Default.Version, incomingMessage);
			} else {
				// This may be an indirect request from an RP that was so badly
				// formed that we cannot even return an error to the RP.
				// The best we can do is display an error to the user.
				// Returning null cues the caller to "throw;"
				return null;
			}

			errorMessage.ErrorMessage = ex.ToStringDescriptive();

			// Allow host to log this error and issue a ticket #.
			// We tear off the field to a local var for thread safety.
			IErrorReporting hostErrorHandler = this.ErrorReporting;
			if (hostErrorHandler != null) {
				errorMessage.Contact = hostErrorHandler.Contact;
				errorMessage.Reference = hostErrorHandler.LogError(ex);
			}

			if (incomingMessage != null) {
				return new AutoResponsiveRequest(incomingMessage, errorMessage, this.SecuritySettings);
			} else {
				return new AutoResponsiveRequest(errorMessage, this.SecuritySettings);
			}
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="DirectResponseBase"/> class.
		/// </summary>
		/// <param name="responseVersion">The OpenID version of the response message.</param>
		/// <param name="originatingRequest">The originating request.  May be null in case the request is unrecognizable and this is an error response.</param>
		protected DirectResponseBase(Version responseVersion, IDirectedProtocolMessage originatingRequest) {
			Requires.NotNull(responseVersion, "responseVersion");

			this.Version = responseVersion;
			this.originatingRequest = originatingRequest;
		}
示例#48
0
		/// <summary>
		/// Prepares to send a request to the Service Provider via the Authorization header.
		/// </summary>
		/// <param name="requestMessage">The message to be transmitted to the ServiceProvider.</param>
		/// <returns>The web request ready to send.</returns>
		/// <remarks>
		/// 	<para>If the message has non-empty ExtraData in it, the request stream is sent to
		/// the server automatically.  If it is empty, the request stream must be sent by the caller.</para>
		/// 	<para>This method implements OAuth 1.0 section 5.2, item #1 (described in section 5.4).</para>
		/// </remarks>
		private HttpWebRequest InitializeRequestAsAuthHeader(IDirectedProtocolMessage requestMessage) {
			var dictionary = this.MessageDescriptions.GetAccessor(requestMessage);

			// copy so as to not modify original
			var fields = new Dictionary<string, string>();
			foreach (string key in dictionary.DeclaredKeys) {
				fields.Add(key, dictionary[key]);
			}
			if (this.Realm != null) {
				fields.Add("realm", this.Realm.AbsoluteUri);
			}

			HttpWebRequest httpRequest;
			UriBuilder recipientBuilder = new UriBuilder(requestMessage.Recipient);
			bool hasEntity = HttpMethodHasEntity(GetHttpMethod(requestMessage));

			if (!hasEntity) {
				MessagingUtilities.AppendQueryArgs(recipientBuilder, requestMessage.ExtraData);
			}
			httpRequest = (HttpWebRequest)WebRequest.Create(recipientBuilder.Uri);
			this.PrepareHttpWebRequest(httpRequest);
			httpRequest.Method = GetHttpMethod(requestMessage);

			httpRequest.Headers.Add(HttpRequestHeader.Authorization, MessagingUtilities.AssembleAuthorizationHeader(Protocol.AuthorizationHeaderScheme, fields));

			if (hasEntity) {
				// WARNING: We only set up the request stream for the caller if there is
				// extra data.  If there isn't any extra data, the caller must do this themselves.
				var requestMessageWithBinaryData = requestMessage as IMessageWithBinaryData;
				if (requestMessageWithBinaryData != null && requestMessageWithBinaryData.SendAsMultipart) {
					// Include the binary data in the multipart entity, and any standard text extra message data.
					// The standard declared message parts are included in the authorization header.
					var multiPartFields = new List<MultipartPostPart>(requestMessageWithBinaryData.BinaryData);
					multiPartFields.AddRange(requestMessage.ExtraData.Select(field => MultipartPostPart.CreateFormPart(field.Key, field.Value)));
					this.SendParametersInEntityAsMultipart(httpRequest, multiPartFields);
				} else {
					ErrorUtilities.VerifyProtocol(requestMessageWithBinaryData == null || requestMessageWithBinaryData.BinaryData.Count == 0, MessagingStrings.BinaryDataRequiresMultipart);
					if (requestMessage.ExtraData.Count > 0) {
						this.SendParametersInEntity(httpRequest, requestMessage.ExtraData);
					} else {
						// We'll assume the content length is zero since the caller may not have
						// anything.  They're responsible to change it when the add the payload if they have one.
						httpRequest.ContentLength = 0;
					}
				}
			}

			return httpRequest;
		}
示例#49
0
		/// <summary>
		/// Analyzes an incoming request message payload to discover what kind of
		/// message is embedded in it and returns the type, or null if no match is found.
		/// </summary>
		/// <param name="request">The message that was sent as a request that resulted in the response.</param>
		/// <param name="fields">The name/value pairs that make up the message payload.</param>
		/// <returns>
		/// A newly instantiated <see cref="IProtocolMessage"/>-derived object that this message can
		/// deserialize to.  Null if the request isn't recognized as a valid protocol message.
		/// </returns>
		IDirectResponseProtocolMessage IMessageFactory.GetNewResponseMessage(IDirectedProtocolMessage request, IDictionary<string, string> fields) {
			Requires.NotNull(request, "request");
			Requires.NotNull(fields, "fields");
			throw new NotImplementedException();
		}
示例#50
0
		/// <summary>
		/// Analyzes an incoming request message payload to discover what kind of
		/// message is embedded in it and returns the type, or null if no match is found.
		/// </summary>
		/// <param name="request">The message that was sent as a request that resulted in the response.</param>
		/// <param name="fields">The name/value pairs that make up the message payload.</param>
		/// <returns>
		/// A newly instantiated <see cref="IProtocolMessage"/>-derived object that this message can
		/// deserialize to.  Null if the request isn't recognized as a valid protocol message.
		/// </returns>
		IDirectResponseProtocolMessage IMessageFactory.GetNewResponseMessage(IDirectedProtocolMessage request, IDictionary<string, string> fields) {
			Contract.Requires<ArgumentNullException>(request != null);
			Contract.Requires<ArgumentNullException>(fields != null);
			throw new NotImplementedException();
		}
示例#51
0
		/// <summary>
		/// Initializes a web request for sending by attaching a message to it.
		/// Use this method to prepare a protected resource request that you do NOT
		/// expect an OAuth message response to.
		/// </summary>
		/// <param name="request">The message to attach.</param>
		/// <returns>The initialized web request.</returns>
		internal HttpWebRequest InitializeRequest(IDirectedProtocolMessage request) {
			Requires.NotNull(request, "request");

			ProcessOutgoingMessage(request);
			return this.CreateHttpRequest(request);
		}
		/// <summary>
		/// Reads an access token to find out what data it authorizes access to.
		/// </summary>
		/// <param name="message">The message carrying the access token.</param>
		/// <param name="accessToken">The access token's serialized representation.</param>
		/// <returns>The deserialized, validated token.</returns>
		/// <exception cref="ProtocolException">Thrown if the access token is expired, invalid, or from an untrusted authorization server.</exception>
		public virtual AccessToken DeserializeAccessToken(IDirectedProtocolMessage message, string accessToken) {
			var accessTokenFormatter = AccessToken.CreateFormatter(this.AuthorizationServerPublicSigningKey, this.ResourceServerPrivateEncryptionKey);
			var token = accessTokenFormatter.Deserialize(message, accessToken, Protocol.access_token);
			return token;
		}
示例#53
0
		internal new void PrepareIndirectResponse(IDirectedProtocolMessage message) {
			base.PrepareIndirectResponse(message);
		}
示例#54
0
		internal new void CreateFormPostResponse(IDirectedProtocolMessage message, IDictionary<string, string> fields) {
			base.CreateFormPostResponse(message, fields);
		}
示例#55
0
		internal new void Create301RedirectResponse(IDirectedProtocolMessage message, IDictionary<string, string> fields, bool payloadInFragment = false) {
			base.Create301RedirectResponse(message, fields, payloadInFragment);
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="CoordinatingHttpRequestInfo"/> class.
		/// </summary>
		/// <param name="message">The message being passed in through a mock transport.  May be null.</param>
		/// <param name="httpMethod">The HTTP method that the incoming request came in on, whether or not <paramref name="message"/> is null.</param>
		internal CoordinatingHttpRequestInfo(IDirectedProtocolMessage message, HttpDeliveryMethods httpMethod)
			: base(GetHttpVerb(httpMethod), message.Recipient) {
			this.message = message;
		}
示例#57
0
		protected override HttpWebRequest CreateHttpRequest(IDirectedProtocolMessage request) {
			throw new NotImplementedException("CreateHttpRequest");
		}
示例#58
0
		/// <summary>
		/// Prepares an HTTP request that carries a given message.
		/// </summary>
		/// <param name="request">The message to send.</param>
		/// <returns>
		/// The <see cref="HttpRequest"/> prepared to send the request.
		/// </returns>
		protected override HttpWebRequest CreateHttpRequest(IDirectedProtocolMessage request) {
			HttpWebRequest httpRequest;

			HttpDeliveryMethods transmissionMethod = request.HttpMethods;
			if ((transmissionMethod & HttpDeliveryMethods.AuthorizationHeaderRequest) != 0) {
				httpRequest = this.InitializeRequestAsAuthHeader(request);
			} else if ((transmissionMethod & HttpDeliveryMethods.PostRequest) != 0) {
				var requestMessageWithBinaryData = request as IMessageWithBinaryData;
				ErrorUtilities.VerifyProtocol(requestMessageWithBinaryData == null || !requestMessageWithBinaryData.SendAsMultipart, OAuthStrings.MultipartPostMustBeUsedWithAuthHeader);
				httpRequest = this.InitializeRequestAsPost(request);
			} else if ((transmissionMethod & HttpDeliveryMethods.GetRequest) != 0) {
				httpRequest = InitializeRequestAsGet(request);
			} else if ((transmissionMethod & HttpDeliveryMethods.HeadRequest) != 0) {
				httpRequest = InitializeRequestAsHead(request);
			} else if ((transmissionMethod & HttpDeliveryMethods.PutRequest) != 0) {
				httpRequest = this.InitializeRequestAsPut(request);
			} else if ((transmissionMethod & HttpDeliveryMethods.DeleteRequest) != 0) {
				httpRequest = InitializeRequestAsDelete(request);
			} else {
				throw new NotSupportedException();
			}
			return httpRequest;
		}
示例#59
0
		/// <summary>
		/// Prepares an HTTP request that carries a given message.
		/// </summary>
		/// <param name="request">The message to send.</param>
		/// <returns>
		/// The <see cref="HttpWebRequest"/> prepared to send the request.
		/// </returns>
		protected override HttpRequestMessage CreateHttpRequest(IDirectedProtocolMessage request) {
			return this.InitializeRequestAsPost(request);
		}
示例#60
0
		/// <summary>
		/// Gets the HTTP method to use for a message.
		/// </summary>
		/// <param name="message">The message.</param>
		/// <returns>"POST", "GET" or some other similar http verb.</returns>
		private static string GetHttpMethod(IDirectedProtocolMessage message) {
			Requires.NotNull(message, "message");

			var signedMessage = message as ITamperResistantOAuthMessage;
			if (signedMessage != null) {
				return signedMessage.HttpMethod;
			} else {
				return MessagingUtilities.GetHttpVerb(message.HttpMethods);
			}
		}