Using OAuth.cs with parameters containing special characters

Oct 8, 2011 at 5:52 PM

Hi,

 

I am using the OAuth.cs file to send requests as a consumer in my C# application. I love the simplicity of it but today I stumbled upon a problem. I want to send some parameters along with my request. So I do it like this:

 

var url = "http://www.domain.com/some/path?foo=" + HttpUtility.UrlEncode("using space");
var authzHeader = oauth.GenerateAuthzHeader(url, "POST");
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.PreAuthenticate = true;
request.AllowWriteStreamBuffering = true;
request.Headers.Add("Authorization", authzHeader);
try
{
	using (var response = (HttpWebResponse)request.GetResponse())
	{
		if (response.StatusCode != HttpStatusCode.OK)
			Console.WriteLine("Error!");
		else
		{
			Stream s = response.GetResponseStream();
			StreamReader sr = new StreamReader(s);
			string str = sr.ReadToEnd();
			U.L(LogLevel.Information, "SERVICE", "Shared song, got response: " + str);
		}
	}
}
catch (WebException exc)
{
	U.L(LogLevel.Error, "SERVICE", "Error while trying to share song: " + exc.Message);
}

Problem is, this seems to make the provider throw me off to the login page, probably because there's something wrong with the signature. The provider is setup following these instructions: http://stakeventures.com/articles/2007/11/26/how-to-turn-your-rails-site-into-an-oauth-provider

I have tried with some different parameters and as long as it's just a-z 0-1 it works. But if I try something like space, colon, slash or any other character that needs to be encoded I'm screwed.

 

So am I doing something wrong in the C# code, is there some bug in the OAuth.cs file (I couldn't find anything) or is it the provider that's behaving strangely?

 

Thanks!

Coordinator
Oct 10, 2011 at 10:12 PM

I don't know, but the obvious place to look is in the Url Encoding.

When connecting to Twitter, the Oauth.cs code works correctly as it is.  I've tested it and it works.  But this could be provider-specific. In other words there could be some flexibility that is built in to Twitter that is not present in your provider.

I cannot remember what the "specification" said about url-encoding the URL before generating the authorization header.  So I looked.  

The OAuth 1.0a spec says:

The signature base string is often the most difficult part of OAuth for newcomers to construct. The signature base string is composed of the HTTP method being used, followed by an ampersand ("&") and then the URL-encoded base URL being accessed, complete with path (but not query parameters), followed by ....

....It goes on in some additional detail about how to create the signature base string.

Looking in the code I wrote for OAuth.cs, the GenerateAuthzHeader does Url-encode the URL before signing it.   But I see you have url-encoded the url before passing it to GenerateAuthzHeader().  (This is actually how I do it when interacting with Twitter, and it's also the way the documentation for OAuth.cs shows to do it)   This would mean the URL gets url-encoded twice, which would be redundant of course.   It could be that Twitter's provider is flexible enough to tolerate the double-pass, and your provider is not. If that is the case, you could test by simply not url-encoding before calling GenerateAuthzHeader().

If that simple test does not work, I'd suggest that you look at where the failure is generated on the server side, in the provider, and trace it back.

 

Coordinator
Oct 10, 2011 at 10:41 PM

I looked again and ran some tests and it seems that the double-encoding should be a non-issue.  It gets run through a the System.Uri class which prevents any double-encoding. I think you could safely eliminate any external Url-encoding of the url, before calling GenerateAuthzHeader(), but I think including it (as I have shown in the documentation for that and other methods) also does not cause a problem.

Coordinator
Oct 11, 2011 at 1:03 AM

Yes, I just tested this, and it works with Twitter whether the status message is url-encoded before calling GenerateAuthzHeader or not.

so, the conclusion is, you should look to your provider, as I said before. 

 

Oct 15, 2011 at 2:28 PM
Edited Oct 15, 2011 at 2:31 PM

Thank you so much for all your help. It turns out that you were right, the problem is how the stuff is encoded. I did find the encoding method provided by OAuth.cs and in the comments it said that one should use that method instead of the built in one. So I changed it and used that method to encode my parameters and now it works. All because of the lower/upper case stuff. :)

However, I did find that swedish characters (åäöÅÄÖ) messed things up a bit. If they were encoded (as they should be according to the RFC) then I got an error from the provider but if I just let them be (added them to the unreservedChars string) then it worked. However, this seem to be a bug in the provider code and not OAuth.cs since the RFC clearly states that åäö should be encoded.
Thanks for your help! Have a sunny day!
/ Christoffer

Creator of Stoffi Music Player
Coordinator
Oct 16, 2011 at 5:55 PM

Christoffer,

I am glad to hear that you solved your problem, and you were able to get some use out of Oauth.cs .

Thanks for letting me know. Good luck.

-Dino