Thank you for the response @svickers.. I have tried the tool you linked - I took an exact request that I received from Canvas, including copying all of the received form parameters (except for oauth signature) and it was not providing the same value that Canvas did as the signature. A quick test of the code you provided isn't providing the same thing as Canvas but I'm going to spend some more time looking into it and comparing to what I was trying to use before. I'm _assuming_ that your escape method is similar to this...
/// <summary>
/// The set of characters that are unreserved in RFC 2396 but are NOT unreserved in RFC 3986.
/// </summary>
private static readonly string[] UriRfc3986CharsToEscape = new[] { "!", "*", "'", "(", ")" };
/// <summary>
/// Escapes a string according to the URI data string rules given in RFC 3986.
/// </summary>
/// <param name="value">The value to escape.</param>
/// <returns>The escaped value.</returns>
/// <remarks>
/// The <see cref="Uri.EscapeDataString"/> method is <i>supposed</i> to take on
/// RFC 3986 behavior if certain elements are present in a .config file. Even if this
/// actually worked (which in my experiments it <i>doesn't</i>), we can't rely on every
/// host actually having this configuration element present.
/// </remarks>
internal static string EscapeUriDataStringRfc3986(string value)
{
// Start with RFC 2396 escaping by calling the .NET method to do the work.
// This MAY sometimes exhibit RFC 3986 behavior (according to the documentation).
// If it does, the escaping we do that follows it will be a no-op since the
// characters we search for to replace can't possibly exist in the string.
StringBuilder escaped = new StringBuilder(Uri.EscapeDataString(value));
// Upgrade the escaping to RFC 3986, if necessary.
for (int i = 0; i < UriRfc3986CharsToEscape.Length; i++)
{
escaped.Replace(UriRfc3986CharsToEscape[i], Uri.HexEscape(UriRfc3986CharsToEscape[i][0]));
}
// Return the fully-RFC3986-escaped string.
return escaped.ToString();
}
I'm wondering if I'm missing something that Canvas uses (or, more likely, excludes) in the signing process - and on my end I'm using them. As I understood it, Canvas is supposed to use all of the form values it is going to send (excluding oauth signature) to create the signature. There are no query parameters.
Thanks again for the response - I'm more than happy to provide any information that might help someone guide me here, it's been quite frustrating to try and get help from Canvas :).