0

OAuth Request Token URL

Hey Guys, I thought this needed a new thread, because I'm definitely a little further than I was. Just talking about the request token URL, I get an unauthorized message.

I get a 401 unauthorized exception when I try to execute my code. I'll paste the code below

If I try to hit the URL from my browser: https://api.login.yahoo.com/oauth/v2/get_request_token

This webpage is not found.

No webpage was found for the web address: https://api.login.yahoo.com/oauth/v2/get_request_token



Any thoughts? Anyone? Thanks!


Code Paste: (the URL, consumer key and consumer secret are just in a configuration file)
the url im hitting is https://api.login.yahoo.com/oauth/v2/get_request_token, which appends the oauth parameters as seen below

CODE
static void Main(string[] args) {
//Get Request Token

string request_token = get_request_token(
ConfigurationManager.AppSettings["consumer_key"],
ConfigurationManager.AppSettings["consumer_secret"]);

Console.WriteLine(request_token);



Console.WriteLine("Press <Enter> to terminate...");
Console.ReadLine();
}

static string get_request_token(string consumer_key, string consumer_secret) {
OAuth.OAuthBase oauth = new OAuth.OAuthBase();
string url = ConfigurationManager.AppSettings["request_token_url"];
StringBuilder parameters = new StringBuilder();
parameters.Append("?oauth_version="); parameters.Append(HttpUtility.UrlEncode("1.0"));
parameters.Append("&oauth_nonce="); parameters.Append(HttpUtility.UrlEncode(oauth.GenerateNonce()));
parameters.Append("&oauth_timestamp="); parameters.Append(HttpUtility.UrlEncode(oauth.GenerateTimeStamp()));
parameters.Append("&oauth_consumer_key="); parameters.Append(HttpUtility.UrlEncode(consumer_key));
parameters.Append("&oauth_signature="); parameters.Append(HttpUtility.UrlEncode(consumer_secret));
parameters.Append("&oauth_callback="); parameters.Append(HttpUtility.UrlEncode("oob"));
parameters.Append("&oauth_signature_method="); parameters.Append(HttpUtility.UrlEncode("PLAINTEXT"));

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url + parameters.ToString());
request.Method = "GET";
using (WebResponse response = request.GetResponse()) {
using (StreamReader reader = new StreamReader(response.GetResponseStream())) {
return reader.ReadToEnd();
}
}
}

by
13 Replies
  • I'd like to update this a bit, as I've been hitting my head against a wall all day =)

    if I hit get_request_token, it appears as though I cannot find the file. Or I do not have access to it.

    Firefox complains:
    Firefox can't find the file at https://api.login.yahoo.com/oauth/v2/get_re...th_callback=oob.

    Whereas if I were to hit

    https://api.login.yahoo.com/oauth/v2/request_auth

    I get a nice page asking for a token.

    if I call https://api.login.yahoo.com/oauth/v2/get_token. :

    Firefox can't find the file at https://api.login.yahoo.com/oauth/v2/get_token.


    I'm seeing a pattern,.. is this the result of an error happening within once of these programs? Am I handing in an invalid consumer_key or something? I'd easily fess up to handing in the wrong parameters right now, Ive ammended this a few times, with no change in behavior whatsoever. Exception maybe using POST method, I think it complained that it wasn't supported.

    Anyways, any help with this matter is greatly appreciated.
    0
  • oh, and I forgot to mention, if I change the filename to like a
    or get_request_token_a

    I wont get an error message, but instead just a canned yahoo image, so I do believe I'm hitting the right files.
    0
  • Ok, this is resolved!

    thanks for the earlier input guys
    0
  • can you tell us what was wrong ?

    Thx
    0
  • I can explain what I think the problem is/was.

    I wasn't providing adequate information for the server to respond correctly to me.

    This all started working when I appended "%26" to theend of the oauh_signature since I am using PLAINTEXT.

    I have to admit, this whole OAuth process has thrown me for a loop.

    At the moment, I need to figure out how to send this in HMAC-SHA1 form.

    Anyways, for those who are in my spot, and want to try OAuth in C# in a really ad-hoc manner, here is my code, which I dont back in the least.

    CODEBOX
    namespace oauth {

    /// <summary>
    /// Used to authenticate OAuth to Yahoo Services
    /// </summary>
    public class YahooOAuth {

    /// <summary>
    /// Encoding to use for talking to services
    /// </summary>
    private static Encoding m_encoding;

    /// <summary>
    /// Initialize Static Members
    /// </summary>
    static YahooOAuth() {
    m_encoding = Encoding.ASCII;
    }

    /// <summary>
    /// Consumer Context, generated / updated by responses from yahoo services
    /// </summary>
    public class consumer_context {

    /// <summary>
    /// initialize request qoken response
    /// </summary>
    /// <param name="source">Output from service response</param>
    public consumer_context(string source) {
    refresh(source);
    return;
    }

    /// <summary>
    /// Update Parameters from service response
    /// </summary>
    /// <param name="source">Output from service response</param>
    public void refresh(string source) {
    string[] strTok = source.Split(new string[] { "&" }, StringSplitOptions.RemoveEmptyEntries);
    foreach (string parameter in strTok) {
    string[] pair = parameter.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries);
    typeof(consumer_context).GetProperty(pair[0]) //member names conveniently named from responses
    .SetValue(this, HttpUtility.UrlDecode(pair[1]), null);
    }
    }

    public string oauth_token { get; set; }

    public string oauth_token_secret { get; set; }

    public string oauth_expires_in { get; set; }

    public string xoauth_request_auth_url { get; set; }

    public string oauth_callback_confirmed { get; set; }

    public string oauth_session_handle { get; set; }

    public string xoauth_yahoo_guid { get; set; }

    public string oauth_authorization_expires_in { get; set; }

    }

    /// <summary>
    /// Step 1: Get Request Token,
    ///
    /// </summary>
    /// <param name="consumer_key">Yahoo Application Consumer Key</param>
    /// <param name="consumer_secret">Yahoo Application Consumer Secret</param>
    /// <returns>Token response</returns>
    public static consumer_context get_request_token(string consumer_key, string consumer_secret) {
    OAuthBase oauth = new OAuthBase();
    string url = Resources.url_get_request_token;
    string token_response;
    string timestamp = oauth.GenerateTimeStamp();
    string nonce = oauth.GenerateNonce();

    //Build parameters to post to get_request_token
    StringBuilder parameters = new StringBuilder();
    parameters.Append("oauth_consumer_key="); parameters.Append(consumer_key);
    parameters.Append("&oauth_signature="); parameters.Append(consumer_secret); parameters.Append("%26"); //%26 must be appended for plaintext
    parameters.Append("&oauth_nonce="); parameters.Append(nonce);
    parameters.Append("&oauth_signature_method="); parameters.Append("PLAINTEXT");
    parameters.Append("&oauth_timestamp="); parameters.Append(timestamp);
    parameters.Append("&oauth_version="); parameters.Append("1.0");
    parameters.Append("&oauth_callback="); parameters.Append("oob");
    byte[] data = m_encoding.GetBytes(parameters.ToString());

    //Post Parameters to get_request_token
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    request.ContentLength = data.Length;
    using (Stream request_stream = request.GetRequestStream()) {
    request_stream.Write(data, 0, data.Length);
    request_stream.Flush();
    }
    //Grab response from service
    using (WebResponse response = request.GetResponse()) {
    using (StreamReader reader = new StreamReader(response.GetResponseStream())) {
    token_response = reader.ReadToEnd();
    }
    }

    return new consumer_context(token_response);
    }

    /// <summary>
    /// Get/Refresh Access Token
    /// </summary>
    /// <param name="consumer_key">Yahoo Application Consumer Key</param>
    /// <param name="consumer_secret">Yahoo Application Consumer Secret</param>
    /// <param name="get_request_token">Request Token Obtained</param>
    /// <param name="verifier_token">verifier token manually obtained, may be null</param>
    /// <returns></returns>
    public static consumer_context get_access_token(string consumer_key, string consumer_secret, consumer_context context, string verifier_token) {
    OAuthBase oauth = new OAuthBase();
    string url = Resources.url_get_access_token;
    string token_response;
    string timestamp = oauth.GenerateTimeStamp();
    string nonce = oauth.GenerateNonce();

    string normal_url, normal_parameters,

    signature = oauth.GenerateSignature(
    new Uri(url),
    consumer_key,
    consumer_secret,
    context.oauth_token,
    context.oauth_token_secret,
    "POST",
    timestamp,
    nonce, OAuthBase.SignatureTypes.PLAINTEXT,
    out normal_url,
    out normal_parameters);

    //Build parameters to post to get_request_token
    StringBuilder parameters = new StringBuilder();
    parameters.Append("oauth_consumer_key="); parameters.Append(consumer_key);
    parameters.Append("&oauth_signature_method="); parameters.Append("PLAINTEXT");
    parameters.Append("&oauth_signature="); parameters.Append(signature);
    parameters.Append("&oauth_version="); parameters.Append("1.0");
    if (verifier_token != null) {
    parameters.Append("&oauth_verifier="); parameters.Append(verifier_token);
    } else {
    parameters.Append("&oauth_session_handle="); parameters.Append(context.oauth_session_handle);
    }
    parameters.Append("&oauth_token="); parameters.Append(context.oauth_token);
    parameters.Append("&oauth_timestamp="); parameters.Append(timestamp);
    parameters.Append("&oauth_nonce="); parameters.Append(nonce);

    byte[] data = m_encoding.GetBytes(parameters.ToString());

    //Post Parameters to get_request_token
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    request.ContentLength = data.Length;
    using (Stream request_stream = request.GetRequestStream()) {
    request_stream.Write(data, 0, data.Length);
    request_stream.Flush();
    }
    //Grab response from service
    using (WebResponse response = request.GetResponse()) {
    using (StreamReader reader = new StreamReader(response.GetResponseStream())) {
    token_response = reader.ReadToEnd();
    }
    }
    //Update Consumer Context
    context.refresh(token_response);
    return context;
    }

    }
    }


    This of course has a dependency on OAuthBase, while I figure out how to use it. =)

    The resources, are just the two urls,
    https://api.login.yahoo.com/oauth/v2/get_token
    and
    https://api.login.yahoo.com/oauth/v2/get_request_token

    respectively

    So, as far as OAuth sessions, this works fine.

    I've yet to figure out how to apply this to a service call, but I think it works in the same way,

    Make a web request to the service call url, and add the oauth parameters (as done for get_token),
    except I believe the service call requires it to be encrypted, I dont think I can use PLAINTEXT.

    If anyone wants to review that, or amend/clarify for my understanding, I would be profoundly grateful..
    0
  • Yeah, the bit about appending the %26 is included in Table 4.1 on this page:

    http://developer.yahoo.com/oauth/guide/oau...questtoken.html

    It's because the OAuth spec calls for appending together the consumer secret with the oauth token, separated by '&' and signed by whichever method you choose (plaintext in this case), in order to generate the signature. In your request for the request token, you don't have an oauth token, but you still have to go through all of the steps, ie, append together your consumer secret and a blank oauth token, separated by '&'.

    You're correct that you can't use plaintext signatures when making the actual request to our fantasy services (because we're not running over https), and from personal experience, manually generating the SHA1 signature is a bit tricky. You should really consider using one of the standard OAuth C# libraries (check the libraries page), since those will deal with all of the signing for you and should theoretically work out of the box.

    EDIT: Heh, adding this reply again because I posted under the wrong ID.
    0
  • I really do appreciate your input. I think I'm getting to the point where I can jump in and use one of those libraries.
    I originally tried, but I found them to be very intimidating. Having the opportunity to write something like this has really helped me understand the workflow a little better

    If this were a desktop application, you would still have to authenticate manually each time, storing credentials would be frowned upon, is this right?

    Is there any way to hand the username and password in on step 3? I mean aside from screen scraping.

    Please understand, my question isn't exactly from a convenience perspective, but what if I wanted to have stats pop up on a screen where user input was highly un-optimized for typing, like.. say a TV screen.

    What would the situation be? they sign in through a web app, which stores the tokens and expiry information in a database, which can then be used by the other application when making requests?
    0
  • QUOTE (Sam Coder @ Jun 19 2010, 06:09 AM) <{POST_SNAPBACK}>
    I really do appreciate your input. I think I'm getting to the point where I can jump in and use one of those libraries.
    I originally tried, but I found them to be very intimidating. Having the opportunity to write something like this has really helped me understand the workflow a little better

    If this were a desktop application, you would still have to authenticate manually each time, storing credentials would be frowned upon, is this right?

    Is there any way to hand the username and password in on step 3? I mean aside from screen scraping.

    Please understand, my question isn't exactly from a convenience perspective, but what if I wanted to have stats pop up on a screen where user input was highly un-optimized for typing, like.. say a TV screen.

    What would the situation be? they sign in through a web app, which stores the tokens and expiry information in a database, which can then be used by the other application when making requests?


    Hi Sam Coder,

    I see you've posted this question on another thread. I'm trying to find the answer for you, as I'm not sure what our official policy is. I'll get back to you on this soon.

    Shane
    0
  • QUOTE (Sam Coder @ Jun 19 2010, 06:09 AM) <{POST_SNAPBACK}>
    I really do appreciate your input. I think I'm getting to the point where I can jump in and use one of those libraries.
    I originally tried, but I found them to be very intimidating. Having the opportunity to write something like this has really helped me understand the workflow a little better

    If this were a desktop application, you would still have to authenticate manually each time, storing credentials would be frowned upon, is this right?

    Is there any way to hand the username and password in on step 3? I mean aside from screen scraping.

    Please understand, my question isn't exactly from a convenience perspective, but what if I wanted to have stats pop up on a screen where user input was highly un-optimized for typing, like.. say a TV screen.

    What would the situation be? they sign in through a web app, which stores the tokens and expiry information in a database, which can then be used by the other application when making requests?


    Seems to me like capturing and reusing the user's credentials defeats the main advantage of OAuth, namely the fact that your app never actually sees said credentials and therfore can't abuse or lose them. If you don't want your user to have to authenticate all the time, then see the part of Yahoo's OAuth guide concerning refreshing a token.
    0
  • QUOTE (Shane K @ Jun 22 2010, 07:36 PM) <{POST_SNAPBACK}>
    Hi Sam Coder,

    I see you've posted this question on another thread. I'm trying to find the answer for you, as I'm not sure what our official policy is. I'll get back to you on this soon.

    Shane


    Thanks, sorry about the thread mishap,
    Seems they've both morphed into one need, as I started to realize what it is I should in fact be asking. =)

    and jay, yeah I agree. I think in the other thread I started eluding to this idea of an unlimited token, like that which is used here http://upcoming.yahoo.com/services/api/token_auth.php

    he refresh action is fine, especially on a computer, where if the user is actively using the application, no problems, and if it expires, they simply click a few times, and type the password on the keyboard.

    But when not on a computer, it could prove to be a serious headache, where I would have to have a process refreshing these tokens almost constantly.

    I have two major issues with this,
    1. is this is bound to break some day, with a simple resolution sure..
    2. IMO, it kind of undermines the intent in the first place, but I guess that's for yahoo to decide.

    It may simply be that Yahoo is not the right platform for what I'm trying to do, I know that others provided the functionality I needed, but there are things about the Yahoo Platform that are highly desirable. Much to consider I guess.

    Again, thanks guys.
    0
  • QUOTE (Sam Coder @ Jun 23 2010, 05:47 AM) <{POST_SNAPBACK}>
    ...and if it expires, they simply click a few times, and type the password on the keyboard...


    No. If it expires, your code can refresh the token without requiring the user to do anything. I'm sorry if I'm being a bit forceful about this, but right now it feels as if you are purposely missing my point.
    0
  • Great information. This really helped me out!
    0
  • Jay is absolutely correct.

    Sam Coder, I've replied on your other thread. We can continue this discussion there. I'm going to close this thread.
    0

Recent Posts

in Fantasy Sports API