MySpace Open Platform

A Place For Developers

Welcome Developers!

in

Welcome!

in

OAuth, getting it to work

Last post 10-26-2009 3:08 PM by killer10. 26 replies.
Page 1 of 2 (27 items) 1 2 Next >
Sort Posts: Previous Next
  • 03-10-2008 5:19 PM

    OAuth, getting it to work

    No doubt there's a lot of confusion in getting OAuth to work; it doesn't help that you're probably debugging against a boolean output.  Thought I'd share my fustrations and "tips" on how I was able to get it working, in the hopes of saving someone from jumping off a bridget :)   Some of this is from other posts, some is original. 

    Cheers,
    Kevin

    Helpful links:

    Definitions:

    • Consumer Key - Application URI, looks like http://www.myspace.com/123456789 - but you need to url encode it so that it's recieved like: http%3A%2F%2Fwww.myspace.com%123456789
    • Consumer Secret - Security Key, looks like  079b72r9z9884e17b6504f723a179c23
    • OAuth Token - Is a request paramater, is indexed by "oauth_token" (ie, Request.params["oauth_token"]
    • OAuth Token Secret - this is an empty string,  ""

    Consume key & consumer secret are both found in the My Apps / App Details page.  Never share the consumer secret key with anyone ;) 

    Pseudocode:
    (found in many formums)

    string generatedStr = @"your generated string here";  (samples below)
    string key = UrlEncode(string.Format("{0}&{1}", UrlEncode(consumerSecret), UrlEncode(tokenSecret)));
    HashAlgorithm hashAlgorithm = new HMACSHA1(Encoding.UTF8.GetBytes(key));
    string computedHash = Convert.ToBase64String(hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(str))));
    return computedHash.compareTo(sentHash) == 0;

    Cryptography Basics

    The goal is to compute a hash that matches the hash provided by the MySpace server...

    Keep in mind that purpose of this execise (of signing the request) - to keep the middle man out.  The spec allows no room for errors (even if it's not published correctly), and all generated strings are case senstivie.  In the .Net platform, that means the default UrlEncode function actually generates the wrong case!!  So, yes, your generated string & keys have to be exact...

    Debugging:

    • Remove as much abstraction as possible, including environment, etc. Start with the OAuth tool, which will allow you to work against a constant set of paramaters.
      • use realistic values (yet keep them simple)
      • Set the version to 1.0 (server does anyways)
      • Take the string generated output (see sample base string & sample signature) and get it to work in your algorithm first!

    Sample Base String:
    GET&http%3A%2F%2Fapi.myspace.com%2Fmystuff%2Fdynamic.aspx&oauth_consumer_key%3Dhttp%253A%252F%252Fwww.myspace.com%252F330069419%26oauth_nonce%3D987654321%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1205192397%26oauth_token%3DoauthToken%26oauth_version%3D1.0

    Signature:
    azN0BCWSkoCyfDAMrl5JLpgSSac=

    • Pain points so far - generating the

      EXACT

       base string as the OAuth tool! 
    • The generated base string includes whitespace (none), and casing (may not be correct if using system libraries).  This is by far the hardest part, so don't bother moving forward without being able to replicating the generated string.
    • I'd suggest using a tool like Beyond Compare (or other visual diff tool), where you split each line up by the = sign (encoded %26), so you can truly compare paramater by paramater.  It has to be exact!
    • I also had to double encode the consumer key to match the OAuth Tool's base string.
    • Do not drop empty variables (ie, if a paramater is empty / null, you still need to include it)
    • The normalized request paramaters are as follows:
      • start with all org paramaters provide
      • remove all OAuth paramaters except those needed by myspace (needed: OAuthVersionKey, OAuthNonceKey, OAuthTimestampKey, OAuthSignatureMethodKey, OAuthConsumerKeyKey, OAuthTokenKey)
      • sort remaining paramaters alphabetically, numbers first, 0 before 1
      • Unconfirmed: "(" and ")" characters may need to be encoded, this is true for other cryto projects i've done in the past.  I've seen forum posts stating as much.
    • Each portion of the string is url encoded; not the entire string:
      • httpMethod.ToUpper() + "&" + UrlEncode(url) + "&" + UrlEncode(normalizedRequestParamaters)
    • Once you have a matching base string, now try to generate a signature.  The pseudocode to generate your own signature is above.  Keep a look out for encoding (UTF8). 
    • A sample key should match the following format: "079b72r9z9884e17b6504f723a179c23&" (note the trailing "&")
    • If you don't have the OAuth signature, then you've already gone wrong; no need to consider other environmental problems.  Repeat debugging until you get this far. 
      • double, tripple, check your base generated string to the one provided by the OAuth tool.
    • From here, it's time to move against the MySpace server.  It shouldn't be too hard, other then each request will be different from the previous - that is, the timestamp will always be different, so you can no longer hard code anything; all variables must come from the request that originated at MySpace.
    • Also, consider that the OAuth tool, even with the same variables that the myspace server send, will generate a different signature.  This is because there are extra paramaters, that can not be input into the OAuth tool (ie, viewer_id, owner_id, etc). So it's time to leave it behind  :)
    • At this time, you're flying somewhat blind.  But, as long as you can normalize your parameters properly, you should be OK... But:
    • Certain characters (?, &, (, ), %, etc) may cause problems - try them in the OAuth tool to see if you can get an exact match with your generated string & signature.

    OK, that's it for now.  Hopefully this thread will remain useful / grow with time.  I can say, that OAuth is possible, but it's important to get the simple steps working first...

    Good luck!
    ~Kevin

     

    Filed under: ,
  • 03-10-2008 10:28 PM In reply to

    Re: OAuth, getting it to work

    Pretty nice guide..

    The best solution, however, would probably be to download the OAuth library for your language of choice at http://oauth.net/code/ and work with that instead of developing your own.

    For example, to validate a request using the PHP library, this is all you need:

    $sig = OAuthRequest::from_request()->build_signature(new OAuthSignatureMethod_HMAC_SHA1(), new OAuthConsumer("yourconsumerkey", "yoursecuritykey"), new OAuthToken(null,null));
     
  • 03-11-2008 1:49 AM In reply to

    • Daniel
    • Not Ranked
    • Joined on 02-05-2008
    • Posts 7

    Re: OAuth, getting it to work

    Great post! 

  • 03-11-2008 8:22 AM In reply to

    Re: OAuth, getting it to work

    phil:

    The best solution, however, would probably be to download the OAuth library for your language of choice at http://oauth.net/code/ and work with that instead of developing your own.

    I totally agree - if the language of choice has a library that works.  While php is well built out, many other languages including C#, java, python and others are still lacking libraries that work as well as you'd hope...

    Cheers,
    Kevin

  • 03-11-2008 2:33 PM In reply to

    Re: OAuth, getting it to work

    the ruby lib works fine
  • 03-11-2008 4:54 PM In reply to

    • Fay
    • Top 500 Contributor
    • Joined on 02-21-2008
    • Posts 20

    Re: OAuth, getting it to work

     I am making the following call (data has been masked) to REST API. However I got 400 invalid OAuth Access token.  Where can I request an access token?

    http://api.myspace.com/v1/users/33315717?oauth_consumer_key=http%3A%2F%2Fwww.myspace.com%2FMY_APPS%2Fmytest&oauth_nonce=-4970176026448551021&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1205278504&oauth_token=null&oauth_version=1.0&oauth_signature=zC7RXlTfra%2BgAaafGtoQcApY2F8%3D


    HTTP/1.x 400 Invalid OAuth access token.
    Cache-Control: private
    Content-Length: 116
    Content-Type: application/xml; charset=utf-8
    Server: Microsoft-IIS/6.0
    X-Server: e4ee8138493bb3550f621724183cf1308b06e90a077f4704
    Date: Tue, 11 Mar 2008 23:35:05 GMT

    Filed under:
  • 03-11-2008 5:41 PM In reply to

    • Fay
    • Top 500 Contributor
    • Joined on 02-21-2008
    • Posts 20

    Re: OAuth, getting it to work

     I tried the same resource URL on OAuth Tool, now I am getting error 401 even tought the user installed the app:

     

    <error xmlns="api-v1.myspace.com"><statuscode>401</statuscode><message>User has not installed the current application.</message></error> 

    Filed under:
  • 03-12-2008 12:55 AM In reply to

    Re: OAuth, getting it to work

    If you're having trouble using the PHP oAuth library to validate signed POST requests tonight... try copying the data from GET to POST. Something like this:

    <?php 

     require_once('OAuth.php');

    $secret = 'xxxxxxxxxx';
    $consumer = "http://www.myspace.com/xxxxxxxxx";

    foreach( $_GET as $key => $val )
            if( !isset( $_POST[ $key ] ) )
                        $_POST[ $key ] = $val;

    $sig = OAuthRequest::from_request()->build_signature(
                                new OAuthSignatureMethod_HMAC_SHA1(),
                                new OAuthConsumer( $consumer, $secret),
                                new OAuthToken(null,null)
                       );       
                      
    if( $sig != $_GET['oauth_signature'] ) exit();   

    ?> 

     

     

  • 03-12-2008 2:24 AM In reply to

    Re: OAuth, getting it to work

    Wait, isn't that how it works? I always assumed that even if you used Method.POST (.6 or .7) the OAuth stuff still only came over in the querystring (because it wasn't part of the data you were trying to post, it's just authentication). You means it's supposed to be a part of the POST data?

    Wow. That explains, like, alot. Now I feel dumb.

  • 03-12-2008 6:20 PM In reply to

    • Smart
    • Top 75 Contributor
    • Joined on 02-05-2008
    • Posts 54

    Re: OAuth, getting it to work

    Is it just me or is the OAuth token always empty?

     According to the OAuth 1.0 spec, your supposed to be able to query the ServiceProvider for it...

  • 03-12-2008 6:56 PM In reply to

    Re: OAuth, getting it to work

    It's just you! Just YOU!

    No, it's everyone. While the specs says that's a possibility, it's not one that MySpace has openned up yet, mostly because, on a certain level, RESTful services shouldn't require tokens or session keys; they're stateless, so Authentication across them is always a one-shot deal.

    Also, on a not-so-philosophical level, it says so in the ToS.

  • 03-13-2008 2:14 PM In reply to

    • Giri
    • Top 500 Contributor
    • Joined on 02-05-2008
    • Posts 12

    Re: OAuth, getting it to work

     Is there a Ruby OAuth example validating the request coming from Myspace?

     

  • 03-15-2008 11:30 AM In reply to

    Re: OAuth, getting it to work

    Smart:

    Is it just me or is the OAuth token always empty?

     According to the OAuth 1.0 spec, your supposed to be able to query the ServiceProvider for it...

    Hi Smart,

    It is empty, but you still need to include it (as an empty string) as part of the signature.  I'd still suggest queying it from the request, just in case it changes in the future. 

    Cheers,
    Kevin

  • 03-16-2008 7:02 AM In reply to

    • Giri
    • Top 500 Contributor
    • Joined on 02-05-2008
    • Posts 12

    Re: OAuth, getting it to work

     Found the excellent OAuth ruby gem that has validation built in. Was doing manually following OAuth spec before but with the

    gem it is just 3 lines of code! Ping me if you want the recipe.

  • 03-26-2008 9:44 AM In reply to

    • Drums
    • Not Ranked
    • Joined on 03-25-2008
    • Posts 3

    Re: OAuth, getting it to work

     I found that php isn't registering the GET param that's empty at the beginning of the request that I saw coming in from myspace to my server from in my access logs.  Myspace seem to be adding =& to the start of the query string and including it in the request signing. The following code snippet will properly set the empty query param and should then get the signing correct.

    if(preg_match('/\?=&/', $_SERVER['REQUEST_URI']))
    {
        $_GET[''] = '';
    }

    I also found that my mod_rewrite routing adds some params to the query string, so hense needed to unset those before doing the OAuth code.

    Filed under:
Page 1 of 2 (27 items) 1 2 Next >