7
votes

I am working on implementing an Oauth Api and am discovering there are a few things I am having trouble validating, would love if anyone could provide clarification. Warning I probably will ramble so I will try to mark my questions in bold.

According to the oauth 1.0 spec https://www.rfc-editor.org/rfc/rfc5849, I am lead to believe that the way oauth params are percent encoded for signatures is different then when on the wire. Section 3.6 https://www.rfc-editor.org/rfc/rfc5849#section-3.6 "It is used only in the construction of the signature base string and the "Authorization" header field."

RFC3986 https://www.rfc-editor.org/rfc/rfc3986 This appears to be the percent encoding scheme used in normal requests. However I did not see it give any sort of 'this' maps to 'that' so I am assuming if the character is in the reserved list the hexadecimal equivalent should be used.

Is the only difference that a ' '(Space) is %20 when encoded for signature? The Oauth spec makes reference to this, but I can't honestly find where that is defined in the other specs. It would be awesome if someone could point me to where that is mentioned and how I may have misunderstood it.

Should other white space characters be %20? Where in the spec does that mention that?

Is the conventional UrlEncode fine for form body and query params?

Finally I have some example output that I am looking to validate. I tried to show the difference between the Oauth Signature Encoded character and the Url encoded character. Once again the only differences appear to be the handling of the ' ', '*' and '~'

Char  Oauth  Url
*     %2A     *
~     ~     %7E
%     %25     %25
!     %21     %21
:     %3A     %3A
/     %2F     %2F
=     %3D     %3D
&     %26     %26
+     %2B     %2B
      %20     +
,     %2C     %2C
@     %40     %40
\r\n  %0D%0A  %0D%0A
\n    %0A     %0A
\r    %0D     %0D
"     %22     %22
?     %3F     %3F
(     %28     %28
)     %29     %29
|     %7C     %7C
[     %5B     %5B
]     %5D     %5D
3

3 Answers

1
votes

Although this is an old post would like to state my understanding all the same.

With regard to the percent-encoding as specified in the rfc3986#2.1, the understanding is that all characters other than the unreserved characters are to be escaped.

This means that other than :

  unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"

The rest of the characters are to be encoded.

A sample implementation in java is provided here. Look for the percentEncode method that accepts a String as an argument.

public static String percentEncode(String s)

Additional code samples in other languages can be found here.

1
votes

For JavaScript:

/**
 * encodeURIComponent(str) Unescaped / Reserved characters:
 *
 * Alphabetic, Digit and -_.~!*'()
 *
 * oAuth Unescaped / Reserved characters:
 *
 * Alphabetic, Digit and -_.~
 *
 */

// Encode with !*'()
this.oAuthEncode = function (value) {
  value = encodeURIComponent(value)
  value = value.replace(/!/g, '%21') // !
  value = value.replace(/\*/g, '%2A') // *
  value = value.replace(/'/g, '%27') // '
  value = value.replace(/\)/g, '%29') // )
  value = value.replace(/\(/g, '%28') // (
  return value;
};

// Decode with !*'()
this.oAuthDecode = function (value) {
  value = decodeURIComponent(value)
  value = value.replace(/%21/g, '!') // !
  value = value.replace(/%2A/g, '*') // *
  value = value.replace(/%27/g, '\'') // '
  value = value.replace(/%29/g, ')') // )
  value = value.replace(/%28/g, '(') // (
  return value;
};