Ejemplo n.º 1
0
        internal static string ConstructSignatureBaseString(ITamperResistantOAuthMessage message, MessageDictionary messageDictionary)
        {
            Requires.NotNull(message, "message");
            Requires.NotNull(message.HttpMethod, "message.HttpMethod");
            Requires.NotNull(messageDictionary, "messageDictionary");
            ErrorUtilities.VerifyInternal(messageDictionary.Message == message, "Message references are not equal.");

            List <string> signatureBaseStringElements = new List <string>(3);

            signatureBaseStringElements.Add(message.HttpMethod.ToString().ToUpperInvariant());

            // For multipart POST messages, only include the message parts that are NOT
            // in the POST entity (those parts that may appear in an OAuth authorization header).
            var encodedDictionary = new Dictionary <string, string>();
            IEnumerable <KeyValuePair <string, string> > partsToInclude = Enumerable.Empty <KeyValuePair <string, string> >();
            var binaryMessage = message as IMessageWithBinaryData;

            if (binaryMessage != null && binaryMessage.SendAsMultipart)
            {
                HttpDeliveryMethods authHeaderInUseFlags = HttpDeliveryMethods.PostRequest | HttpDeliveryMethods.AuthorizationHeaderRequest;
                ErrorUtilities.VerifyProtocol((binaryMessage.HttpMethods & authHeaderInUseFlags) == authHeaderInUseFlags, OAuthStrings.MultipartPostMustBeUsedWithAuthHeader);

                // Include the declared keys in the signature as those will be signable.
                // Cache in local variable to avoid recalculating DeclaredKeys in the delegate.
                ICollection <string> declaredKeys = messageDictionary.DeclaredKeys;
                partsToInclude = messageDictionary.Where(pair => declaredKeys.Contains(pair.Key));
            }
            else
            {
                partsToInclude = messageDictionary;
            }

            // If this message was deserialized, include only those explicitly included message parts (excludes defaulted values)
            // in the signature.
            var originalPayloadMessage = (IMessageOriginalPayload)message;

            if (originalPayloadMessage.OriginalPayload != null)
            {
                partsToInclude = partsToInclude.Where(pair => originalPayloadMessage.OriginalPayload.ContainsKey(pair.Key));
            }

            foreach (var pair in OAuthChannel.GetUriEscapedParameters(partsToInclude))
            {
                encodedDictionary[pair.Key] = pair.Value;
            }

            // An incoming message will already have included the query and form parameters
            // in the message dictionary, but an outgoing message COULD have SOME parameters
            // in the query that are not in the message dictionary because they were included
            // in the receiving endpoint (the original URL).
            // In an outgoing message, the POST entity can only contain parameters if they were
            // in the message dictionary, so no need to pull out any parameters from there.
            if (message.Recipient.Query != null)
            {
                NameValueCollection nvc = HttpUtility.ParseQueryString(message.Recipient.Query);
                foreach (string key in nvc)
                {
                    string escapedKey   = MessagingUtilities.EscapeUriDataStringRfc3986(key);
                    string escapedValue = MessagingUtilities.EscapeUriDataStringRfc3986(nvc[key]);
                    string existingValue;
                    if (!encodedDictionary.TryGetValue(escapedKey, out existingValue))
                    {
                        encodedDictionary.Add(escapedKey, escapedValue);
                    }
                    else
                    {
                        ErrorUtilities.VerifyInternal(escapedValue == existingValue, "Somehow we have conflicting values for the '{0}' parameter.", escapedKey);
                    }
                }
            }
            encodedDictionary.Remove("oauth_signature");

            UriBuilder endpoint = new UriBuilder(message.Recipient);

            endpoint.Query    = null;
            endpoint.Fragment = null;
            signatureBaseStringElements.Add(endpoint.Uri.AbsoluteUri);

            var sortedKeyValueList = new List <KeyValuePair <string, string> >(encodedDictionary);

            sortedKeyValueList.Sort(SignatureBaseStringParameterComparer);
            StringBuilder paramBuilder = new StringBuilder();

            foreach (var pair in sortedKeyValueList)
            {
                if (paramBuilder.Length > 0)
                {
                    paramBuilder.Append("&");
                }

                paramBuilder.Append(pair.Key);
                paramBuilder.Append('=');
                paramBuilder.Append(pair.Value);
            }

            signatureBaseStringElements.Add(paramBuilder.ToString());

            StringBuilder signatureBaseString = new StringBuilder();

            foreach (string element in signatureBaseStringElements)
            {
                if (signatureBaseString.Length > 0)
                {
                    signatureBaseString.Append("&");
                }

                signatureBaseString.Append(MessagingUtilities.EscapeUriDataStringRfc3986(element));
            }

            Logger.Bindings.DebugFormat("Constructed signature base string: {0}", signatureBaseString);
            return(signatureBaseString.ToString());
        }
		internal static string ConstructSignatureBaseString(ITamperResistantOAuthMessage message, MessageDictionary messageDictionary) {
			Requires.NotNull(message, "message");
			Requires.NotNullOrEmpty(message.HttpMethod, "message.HttpMethod");
			Requires.NotNull(messageDictionary, "messageDictionary");
			ErrorUtilities.VerifyInternal(messageDictionary.Message == message, "Message references are not equal.");

			List<string> signatureBaseStringElements = new List<string>(3);

			signatureBaseStringElements.Add(message.HttpMethod.ToUpperInvariant());

			// For multipart POST messages, only include the message parts that are NOT
			// in the POST entity (those parts that may appear in an OAuth authorization header).
			var encodedDictionary = new Dictionary<string, string>();
			IEnumerable<KeyValuePair<string, string>> partsToInclude = Enumerable.Empty<KeyValuePair<string, string>>();
			var binaryMessage = message as IMessageWithBinaryData;
			if (binaryMessage != null && binaryMessage.SendAsMultipart) {
				HttpDeliveryMethods authHeaderInUseFlags = HttpDeliveryMethods.PostRequest | HttpDeliveryMethods.AuthorizationHeaderRequest;
				ErrorUtilities.VerifyProtocol((binaryMessage.HttpMethods & authHeaderInUseFlags) == authHeaderInUseFlags, OAuthStrings.MultipartPostMustBeUsedWithAuthHeader);

				// Include the declared keys in the signature as those will be signable.
				// Cache in local variable to avoid recalculating DeclaredKeys in the delegate.
				ICollection<string> declaredKeys = messageDictionary.DeclaredKeys;
				partsToInclude = messageDictionary.Where(pair => declaredKeys.Contains(pair.Key));
			} else {
				partsToInclude = messageDictionary;
			}

			// If this message was deserialized, include only those explicitly included message parts (excludes defaulted values)
			// in the signature.
			var originalPayloadMessage = (IMessageOriginalPayload)message;
			if (originalPayloadMessage.OriginalPayload != null) {
				partsToInclude = partsToInclude.Where(pair => originalPayloadMessage.OriginalPayload.ContainsKey(pair.Key));
			}

			foreach (var pair in OAuthChannel.GetUriEscapedParameters(partsToInclude)) {
				encodedDictionary[pair.Key] = pair.Value;
			}

			// An incoming message will already have included the query and form parameters
			// in the message dictionary, but an outgoing message COULD have SOME parameters
			// in the query that are not in the message dictionary because they were included
			// in the receiving endpoint (the original URL).
			// In an outgoing message, the POST entity can only contain parameters if they were
			// in the message dictionary, so no need to pull out any parameters from there.
			if (message.Recipient.Query != null) {
				NameValueCollection nvc = HttpUtility.ParseQueryString(message.Recipient.Query);
				foreach (string key in nvc) {
					string escapedKey = MessagingUtilities.EscapeUriDataStringRfc3986(key);
					string escapedValue = MessagingUtilities.EscapeUriDataStringRfc3986(nvc[key]);
					string existingValue;
					if (!encodedDictionary.TryGetValue(escapedKey, out existingValue)) {
						encodedDictionary.Add(escapedKey, escapedValue);
					} else {
						ErrorUtilities.VerifyInternal(escapedValue == existingValue, "Somehow we have conflicting values for the '{0}' parameter.", escapedKey);
					}
				}
			}
			encodedDictionary.Remove("oauth_signature");

			UriBuilder endpoint = new UriBuilder(message.Recipient);
			endpoint.Query = null;
			endpoint.Fragment = null;
			signatureBaseStringElements.Add(endpoint.Uri.AbsoluteUri);

			var sortedKeyValueList = new List<KeyValuePair<string, string>>(encodedDictionary);
			sortedKeyValueList.Sort(SignatureBaseStringParameterComparer);
			StringBuilder paramBuilder = new StringBuilder();
			foreach (var pair in sortedKeyValueList) {
				if (paramBuilder.Length > 0) {
					paramBuilder.Append("&");
				}

				paramBuilder.Append(pair.Key);
				paramBuilder.Append('=');
				paramBuilder.Append(pair.Value);
			}

			signatureBaseStringElements.Add(paramBuilder.ToString());

			StringBuilder signatureBaseString = new StringBuilder();
			foreach (string element in signatureBaseStringElements) {
				if (signatureBaseString.Length > 0) {
					signatureBaseString.Append("&");
				}

				signatureBaseString.Append(MessagingUtilities.EscapeUriDataStringRfc3986(element));
			}

			Logger.Bindings.DebugFormat("Constructed signature base string: {0}", signatureBaseString);
			return signatureBaseString.ToString();
		}