internal IDictionary <string, string> Serialize(IMessage message)
        {
            ErrorUtilities.VerifyArgumentNotNull(message, "message");

            var messageDescription = MessageDescription.Get(this.messageType, message.Version);
            var messageDictionary  = new MessageDictionary(message);

            // Rather than hand back the whole message dictionary (which
            // includes keys with blank values), create a new dictionary
            // that only has required keys, and optional keys whose
            // values are not empty.
            var result = new Dictionary <string, string>();

            foreach (var pair in messageDictionary)
            {
                MessagePart partDescription;
                if (messageDescription.Mapping.TryGetValue(pair.Key, out partDescription))
                {
                    if (partDescription.IsRequired || partDescription.IsNondefaultValueSet(message))
                    {
                        result.Add(pair.Key, pair.Value);
                    }
                }
                else
                {
                    // This is extra data.  We always write it out.
                    result.Add(pair.Key, pair.Value);
                }
            }

            return(result);
        }
示例#2
0
        /// <summary>
        /// Verifies that all required message parts are initialized to values
        /// prior to sending the message to a remote party.
        /// </summary>
        /// <param name="message">The message to verify.</param>
        /// <exception cref="ProtocolException">
        /// Thrown when any required message part does not have a value.
        /// </exception>
        private static void EnsureValidMessageParts(IProtocolMessage message)
        {
            Debug.Assert(message != null, "message == null");

            MessageDictionary  dictionary  = new MessageDictionary(message);
            MessageDescription description = MessageDescription.Get(message.GetType(), message.Version);

            description.EnsureMessagePartsPassBasicValidation(dictionary);
        }
        /// <summary>
        /// Ensures that all message parameters that must be signed are in fact included
        /// in the signature.
        /// </summary>
        /// <param name="signedMessage">The signed message.</param>
        private static void EnsureParametersRequiringSignatureAreSigned(ITamperResistantOpenIdMessage signedMessage)
        {
            // Verify that the signed parameter order includes the mandated fields.
            // We do this in such a way that derived classes that add mandated fields automatically
            // get included in the list of checked parameters.
            Protocol protocol = Protocol.Lookup(signedMessage.Version);
            var      partsRequiringProtection = from part in MessageDescription.Get(signedMessage.GetType(), signedMessage.Version).Mapping.Values
                                                where part.RequiredProtection != ProtectionLevel.None
                                                select part.Name;

            ErrorUtilities.VerifyInternal(partsRequiringProtection.All(name => name.StartsWith(protocol.openid.Prefix, StringComparison.Ordinal)), "Signing only works when the parameters start with the 'openid.' prefix.");
            string[] signedParts   = signedMessage.SignedParameterOrder.Split(',');
            var      unsignedParts = from partName in partsRequiringProtection
                                     where !signedParts.Contains(partName.Substring(protocol.openid.Prefix.Length))
                                     select partName;

            ErrorUtilities.VerifyProtocol(!unsignedParts.Any(), OpenIdStrings.SignatureDoesNotIncludeMandatoryParts, string.Join(", ", unsignedParts.ToArray()));
        }
        /// <summary>
        /// Reads name=value pairs into an OAuth message.
        /// </summary>
        /// <param name="fields">The name=value pairs that were read in from the transport.</param>
        /// <param name="message">The message to deserialize into.</param>
        /// <exception cref="ProtocolException">Thrown when protocol rules are broken by the incoming message.</exception>
        internal void Deserialize(IDictionary <string, string> fields, IMessage message)
        {
            ErrorUtilities.VerifyArgumentNotNull(fields, "fields");
            ErrorUtilities.VerifyArgumentNotNull(message, "message");

            // Before we deserialize the message, make sure all the required parts are present.
            MessageDescription.Get(this.messageType, message.Version).EnsureMessagePartsPassBasicValidation(fields);

            try {
                foreach (var pair in fields)
                {
                    IDictionary <string, string> dictionary = new MessageDictionary(message);
                    dictionary[pair.Key] = pair.Value;
                }
            } catch (ArgumentException ex) {
                throw ErrorUtilities.Wrap(ex, MessagingStrings.ErrorDeserializingMessage, this.messageType.Name);
            }
            message.EnsureValidMessage();
        }
        /// <summary>
        /// Gets the value to use for the openid.signed parameter.
        /// </summary>
        /// <param name="signedMessage">The signable message.</param>
        /// <returns>
        /// A comma-delimited list of parameter names, omitting the 'openid.' prefix, that determines
        /// the inclusion and order of message parts that will be signed.
        /// </returns>
        private string GetSignedParameterOrder(ITamperResistantOpenIdMessage signedMessage)
        {
            ErrorUtilities.VerifyArgumentNotNull(signedMessage, "signedMessage");

            Protocol protocol = Protocol.Lookup(signedMessage.Version);

            MessageDescription description = MessageDescription.Get(signedMessage.GetType(), signedMessage.Version);
            var signedParts = from part in description.Mapping.Values
                              where (part.RequiredProtection & System.Net.Security.ProtectionLevel.Sign) != 0 &&
                              part.GetValue(signedMessage) != null
                              select part.Name;
            string prefix = Protocol.V20.openid.Prefix;

            ErrorUtilities.VerifyInternal(signedParts.All(name => name.StartsWith(prefix, StringComparison.Ordinal)), "All signed message parts must start with 'openid.'.");

            if (this.opSecuritySettings.SignOutgoingExtensions)
            {
                // Tack on any ExtraData parameters that start with 'openid.'.
                List <string> extraSignedParameters = new List <string>(signedMessage.ExtraData.Count);
                foreach (string key in signedMessage.ExtraData.Keys)
                {
                    if (key.StartsWith(protocol.openid.Prefix, StringComparison.Ordinal))
                    {
                        extraSignedParameters.Add(key);
                    }
                    else
                    {
                        Logger.DebugFormat("The extra parameter '{0}' will not be signed because it does not start with 'openid.'.", key);
                    }
                }
                signedParts = signedParts.Concat(extraSignedParameters);
            }

            int    skipLength   = prefix.Length;
            string signedFields = string.Join(",", signedParts.Select(name => name.Substring(skipLength)).ToArray());

            return(signedFields);
        }