OAuth C# (very) Basic Library

October 17, 2007

I know it took me a while (sorry) but I had a couple things on my plate.

At first I wanted to release a more complete integration of OAuth within ASP.NET, but that will have to wait to the next time frame I can allocate to work on this.

In the meantime, there is some basic C# code in the OAuth code repository which generates the OAuth signature, which is the most complicated thing to implement in the spec (not that it’s that difficult to implement :-) It’s actually quite easy).

To use the C# code, simply do this (based on the samples in the spec):

using OAuth;

OAuthBase oauth = new OAuthBase();

Uri url = new Uri(“http://photos.example.net/photos?file=vacation.jpg&size=original”);

string signature = oauth.GenerateSignature(url, “dpf43f3p2l4k3l03″, “kd94hf93k423kf44″, “nnch734d00sl2jdk”, “pfkkdhi9sl3r4s00″, “GET”, oauth.GenerateTimeStamp(), oauth.GenerateNonce(), OAuthBase.SignatureTypes.HMACSHA1);

After that you can concatenate the relevant query parameters as well as the signature value to the URL and use it.

If you have a different timestamp and/or nonce generation method, you can inherit and override these methods.

If you require a different hashing algorithm other than the default HMAC-SHA1 or the PLAINTEXT (which MUST be used with a secure communication channel such as HTTPS) you can use the “GenerateSignatureBase” method to generate the signature base string and then call “GenerateSignatureUsingHash” passing the signature base and the hash algorithm you are using.

That’s about it. I’ll update when I’ll have some more integrative code.

Be Sociable, Share!

tags: , , , , , , ,
posted in Code, OAuth by Eran Sandler

Follow comments via the RSS Feed | Leave a comment | Trackback URL

  • http://livz.org Steven Livingstone

    Eric – thanks for this. How far along are you with the follow up work?

    I have written an API I wish to protected and was looking into the Amazon, Google, Flickr etc athentication meachanisms and then it hit me as to what OAuth is really useful for!

    I need a client and server OAuth implementation – can your library do this? At first look it seems to be the client side of thing. I don’t know the spec enough to know what the server implementation involves but i’m reading up this weekend.

    Best Wishes,
    Steven

  • http://livz.org Steven Livingstone

    Sorry… Eran :)

  • http://eran.sandler.co.il Eran

    Hi Steven,

    I just want to make sure we are on the same page, meaning, OAuth will be used in your API to enable users/applications/whatever to perform actions on behalf of a certain user without that user actually passing his/her credentials.

    If that is the case, OAuth is exactly for you.

    Regarding the (very basic) library I have written (which is a good time to update to the latest draft ;-) ), the actions it performs, generating the signature, is the hardest and most significant part of OAuth and it can be used in both client and server sides.

    It doesn’t cover the complete workflow in which a user lacking authentication will need to be redirect to a place where it can be authenticated, but that should be fairly easy.

  • http://livz.org Steven Livingstone

    Thanks Eran. That sounds exactly like what i want. For example, to enable site A to embed some javascript which will perform a *write* to my site – i would want that user to be authenticated but don’t like the idea of passing username and password information. I am *very* interested in how this would be implemented in these cases. I see you have some good articles so i’ll need to read them more.

    I also want to do the usually REST API authentication but access from JavaScript via XML/JSON with authentication is part of my use case.

    I was originally going to follow the MS5/HMAC method flickr/google and so on have used but OAuth looks good.

    Thanks for your work on all this! If i get something useful out of this for my site i’ll try and box up and end to end sample and share it.

  • Simon

    Hey Eran,

    Thanks for your OAuth C# library. I’m trying to use it to generate a valid sig for Fire Eagle but no matter what I try, I get the response:

    Here is my code:

    string consumerKey = “XYZ”;
    string consumerSecret = “ABC”;
    Uri uri = new Uri(“https://fireeagle.yahooapis.com/oauth/request_token”);
    OAuthBase oAuth = new OAuthBase();
    string nonce = oAuth.GenerateNonce();
    string timeStamp = oAuth.GenerateTimeStamp();
    string sig = oAuth.GenerateSignature(uri, consumerKey, consumerSecret, string.Empty, string.Empty, “GET”, timeStamp, nonce, OAuth.SignatureTypes.HMACSHA1);

    StringBuilder sb = new StringBuilder(uri.ToString());
    sb.AppendFormat(“?oauth_consumer_key={0}&”, consumerKey);
    sb.AppendFormat(“oauth_nonce={0}&”, nonce);
    sb.AppendFormat(“oauth_timestamp={0}&”, timeStamp);
    sb.AppendFormat(“oauth_signature_method={0}&”, “HMAC-SHA1″);
    sb.AppendFormat(“oauth_version={0}&”, “1.0”);
    sb.AppendFormat(“oauth_signature={0}”, sig);
    Debug.WriteLine(sb.ToString());

    Can you see anything wrong with this?

    Thanks a million!

    Simon

  • Simon

    damn brackets!

    response is

    < err msg=”Invalid OAuth signature.” code=”23″ >

  • http://eran.sandler.co.il Eran

    Hi Simon,

    I didn’t update the C# library to the release spec and the signature algorithm was changed a bit (sorry about that).
    I’ll try to fix the signature method in the next couple of days and I’ll post the updated code.

    Eran

  • Simon

    Thanks Eran, much appreciated

  • http://eran.sandler.co.il Eran

    Hi Simon,

    I’ve checked in the fix. It now generates the right signature as the tests on the spec shows.
    You can grab it from the same location and check it out.

  • Marco

    Hi Eran,

    I have been trying to use the OAuth C# library to validate requests coming from orkut,
    but I never managed to validate a request against the provided signature.
    This is what i am doing:

    X509Certificate2 certificate = new X509Certificate2(@”C:\pub.
    1199819524.-1556113204990931254.cer”);
    RSACryptoServiceProvider rsacp = new RSACryptoServiceProvider();
    string publicKey = certificate.PublicKey.Key.ToXmlString(false);
    rsacp.FromXmlString(publicKey);

    byte[] verify = Encoding.UTF8.GetBytes(baseSignature);

    byte[] signature = Convert.FromBase64String(oauth_signature);
    bool ok = rsacp.VerifyData(verify, ‘SHA1′, signature);
    Console.WriteLine(“Success: {0}”, ok);

    Would you know where am I going wrong?

    Marco

  • http://blog.stevienova.com Steve

    maybe its just me, but using this c# library, the timestamp it generates is incorrect. it comes out with . ex (1208643626.611) – if i cut off the .611, then it works. Otherwise I get invalid signature when doing oauth requests (tested here: http://term.ie/oauth/example/) and with the pownce oauth…

    I changed GetTimeStamp to

    public virtual string GenerateTimeStamp() {
    // Default implementation of UNIX time of the current UTC time
    TimeSpan ts = DateTime.UtcNow – new DateTime(1970, 1, 1, 0, 0, 0, 0);
    string timeStamp = ts.TotalSeconds.ToString();
    timeStamp = timeStamp.Substring(0, timeStamp.IndexOf(“.”));
    return timeStamp;
    }

  • http://eran.sandler.co.il Eran Sandler

    Hi Steve, thanks for the fix.
    Perhaps I was too precise with that time :-)

    I think there is a better way of fixing it instead of substringing the timestamp string, but I’ll look into that and release a fix.

  • http://eran.sandler.co.il Eran Sandler

    Hi Steve,

    I’ve checked in a version that simply casts the double returned from ts.TotalSeconds into an int64 (just in case) so that the “ToString” method will not return a decimal number (only an integer) which is what you need.

    The latest version is checked in so you can get it from the usual place.

  • http://www.propertywala.com Mukesh

    I have an Another Solution For error when request having both post and get data

    http://coderheaven.blogspot.com/2008/08/authenticate-oauth-signature-in-corkut.html

  • memel

    has someone a solution that works in app opensocial, accessing a page in c #?

    the code below (Suggested by Mukesh) always return false.

    if (!string.IsNullOrEmpty(Request["oauth_signature"]))
    {

    string certificateValue = @”—–BEGIN CERTIFICATE—–
    MIIDHDCCAoWgAwIBAgIJAMbTCksqLiWeMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNV
    BAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIG
    A1UEChMLR29vZ2xlIEluYy4xDjAMBgNVBAsTBU9ya3V0MQ4wDAYDVQQDEwVscnlh
    bjAeFw0wODAxMDgxOTE1MjdaFw0wOTAxMDcxOTE1MjdaMGgxCzAJBgNVBAYTAlVT
    MQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChML
    R29vZ2xlIEluYy4xDjAMBgNVBAsTBU9ya3V0MQ4wDAYDVQQDEwVscnlhbjCBnzAN
    BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAseBXZ4NDhm24nX3sJRiZJhvy9eDZX12G
    j4HWAMmhAcnm2iBgYpAigwhVHtOs+ZIUIdzQHvHeNd0ydc1Jg8e+C+Mlzo38OvaG
    D3qwvzJ0LNn7L80c0XVrvEALdD9zrO+0XSZpTK9PJrl2W59lZlJFUk3pV+jFR8NY
    eB/fto7AVtECAwEAAaOBzTCByjAdBgNVHQ4EFgQUv7TZGZaI+FifzjpTVjtPHSvb
    XqUwgZoGA1UdIwSBkjCBj4AUv7TZGZaI+FifzjpTVjtPHSvbXqWhbKRqMGgxCzAJ
    BgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEU
    MBIGA1UEChMLR29vZ2xlIEluYy4xDjAMBgNVBAsTBU9ya3V0MQ4wDAYDVQQDEwVs
    cnlhboIJAMbTCksqLiWeMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEA
    CETnhlEnCJVDXoEtSSwUBLP/147sqiu9a4TNqchTHJObwTwDPUMaU6XIs2OTMmFu
    GeIYpkHXzTa9Q6IKlc7Bt2xkSeY3siRWCxvZekMxPvv7YTcnaVlZzHrVfAzqNsTG
    P3J//C0j+8JWg6G+zuo5k7pNRKDY76GxxHPYamdLfwk=
    —–END CERTIFICATE—–“;

    X509Certificate2 cert = new X509Certificate2(Encoding.ASCII.GetBytes(certificateValue), “”, X509KeyStorageFlags.MachineKeySet);
    System.Collections.Specialized.NameValueCollection queryString = Request.QueryString;
    string signature = Request["oauth_signature"];
    //Base64Decoder decoder = new Base64Decoder(signature.ToCharArray());
    byte[] sign = Convert.FromBase64String(signature);

    String urvl, urlNPAM;

    RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PublicKey.Key;
    OAuth.OAuthBase asd = new OAuth.OAuthBase();
    string url = Request.Url.ToString();
    foreach (string name in Request.Form)
    url += “&” + name + “=” + Request.Form[name];
    Uri reqURi = new Uri(url);
    string signatureBase = asd.GenerateSignatureBase(reqURi, Request["oauth_consumer_key"], “”, “”,
    Request.ServerVariables["REQUEST_METHOD"].ToUpper(), Request["oauth_timestamp"],
    Request["oauth_nonce"], Request["oauth_signature_method"], out urvl, out urlNPAM);
    bool rtn = rsa.VerifyData(
    Encoding.ASCII.GetBytes(signatureBase), “SHA1″, sign);

    Response.Write(rtn);
    }

  • David

    I’m trying it out, but the signatures it is generating are not accepted by the Netflix API…I get a bad request
    I was wondering if I can be of some help to debug it.

  • http://eran.sandler.co.il Eran Sandler

    David, have you looked at this step-by-step tutorial by Jospeh Smarr – http://josephsmarr.com/2008/10/01/using-netflixs-new-api-a-step-by-step-guide/

    It has all the values of each steps that you can compare and see if it all works well.

  • http://sunshinepeacehappyness.blogspot.com/ David Friedman

    Hello Eran!

    Your Oauth Base class gave me a big help! I’ve started only with a portion of the features of OAuth, so Your basic C# was a big help.
    However :), maybe my experience could help others too:
    – Your UrlEncode is not prepared for international characters – i returned to HttpUtiliity.UrlEncode and capitalised the %__ parts
    – QueryParameterComparer used Compare needs the extra (3rd) StringComparison.Ordinal parameter to Order the params in the specified (“lexicographical byte value ordering”) order (all capitalised ABC first, then comes abc).
    thnx,
    {:-D

  • venkata

    hi,

    I am trying to develop an appilication which will contact google using OAuth.

    but i am getting this error message

    signature_invalid
    base_string:GET&https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthGetRequestToken&oauth_consumer_key%3Dwww.frooly.com%26oauth_nonce%3D8841340%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1265201014%26oauth_version%3D1.0%26scope%3Dhttp%253A%252F%252Fwww.google.com%252Fcalendar%252Ffeeds

    I have registered with google and got consumer key and secret also. and the domain is status is Active.

    well my code is able to get the request token from twitter but fails with google. any idea ?

    please help me.

    kind regards,

  • http://eran.sandler.co.il Eran Sandler

    I would suggest to use the signature code from google. I think they have that in their sdk. At first glance this seems to be a signature issue so check the parameters you pass to the signature function.

  • Bobby

    I”m new to OAuth, I understand the idea and the steps necessary to execute the protocol. I’m having a rough time with obtaining the auth token. I can’t get anything but “400 Bad Request” from the Google Analytics server. I know this isn’t a lot of information but does anyone have any ideas?

    I really appreciate it.

  • Matthias

    One little detail: the GenerateTimestamp method currently only works when a dot (.) is used with decimal numbers. When a comma (,) is used the code fails. A workaround would be to use the NumberDecimalProperty of the NumberFormatInfo class, like so:

    ///
    /// Generate the timestamp for the signature
    ///
    ///
    public virtual string GenerateTimeStamp() {
    // Default implementation of UNIX time of the current UTC time
    TimeSpan ts = DateTime.UtcNow – new DateTime(1970, 1, 1, 0, 0, 0, 0);
    string timeStamp = ts.TotalSeconds.ToString();
    timeStamp = timeStamp.Substring(0,
    timeStamp.IndexOf(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator));
    return timeStamp;
    }

  • Deepak

    Another solution is SocialAuth.NET (http://code.google.com/p/socialauth-net/) This library takes care of all handshake with provider and expose methods like Login(), GetProfile() and GetContacts(). Infact it also provides option to use its inbuilt authentication engine using which a site with no authentication can be turned authentication enabled with Yahoo, Google, Facebook and MSN in less than 10 minutes.

  • http://coffeeaddict.myopenid.com/ CoffeeAddict

    Lol easy? Yea when you have the code already readily available for you to use, because it does all the hard part for you (in that OAuthBase.cs). Otherwise even understanding all the combination of what’s going on in that file can get confusing because there are so many parts and things that have to take place in a certain order in order for it to create a correct signature.

    No it’s not easy…if you’re trying to roll your own signature creation methods. Sure, if you’re using code available like the OAuthBase.cs, then it’s “easy” because you aren’t having to do jack. But then again, do I like the code in OAuthBase.cs…depends. I might want to take snippets of it but also roll my own in a different way in terms of syntax.

    This whole OAuth is not easy period. You have to understand all parts even if you’re using code that’s doing all the dirty work for you. I love it when developers through the word “easy” around as if they either bypass the REAL code somehow (by using a framework or such as existing code e.g. OAuthBase.cs) or they say everything is “easy” so as to not seem incapable of doing x,y,z…which to me is stupid that we as developers even have to sit here and try to act like we know everything cause we do not. In other words, devs need to humble themselves to the fact and admit not everything is easy…the truth…especially with OAuth.

    My point is, stop using the term easy so loosely just to try to make yourself look like you’re some genius you’re not.

 
Powered by Wordpress and MySQL. Theme by Shlomi Noach, openark.org