0

problem with signature while REFRESHING accessToken

this signature problem is really big. very effortly i got through this problem and now was able to retrieve the profile and contact response from yahoo...
but now if i use the same method of generating signature in the refresh API, it's giving 'signature invalid' response. I just don't know what to do now...
Just clear one thing:
You people send URL Encoded accessToken. I store it by decoding it.
Now i encode it and make the baseString. Also i encode it and then put it in the parameter.
This thing worked for retrieving contacts etc.
But while refreshing the token, i use the same technique and the signature invalid is coming. Do i have to double encode access Token or what to do??
Is it that i don have to use accTokenSecret while generating signature?
Kindly reply to all these issues about signature..

12 Replies
  • There is a known issue which might be affecting your signature. If you include any empty variables in your signature it will not match the Yahoo signature. For example if you sign http://foo.com/?bar=baz&qux=quux&abc=&def=ghi then Yahoo will remove the variable abc before signing because it is empty. You should make sure that is also true when you create signatures.

    Hope that helps.

    Tom,
    Yahoo! Developer Network
    0
  • QUOTE (sh1mmer @ Jan 26 2009, 12:34 PM) <{POST_SNAPBACK}>
    There is a known issue which might be affecting your signature. If you include any empty variables in your signature it will not match the Yahoo signature. For example if you sign http://foo.com/?bar=baz&qux=quux&abc=&def=ghi then Yahoo will remove the variable abc before signing because it is empty. You should make sure that is also true when you create signatures.

    Hope that helps.

    Tom,
    Yahoo! Developer Network


    Kindly answer all my questions above. Your empty parameter advice was really nice but not applicable in my problem.
    Kindly observe all my problems carefully and please answer all issues.
    Thanks
    ANKIT
    0
  • Hi Ankit,

    there are lots of things that could go wrong with signing a request and it's difficult to answer your questions without seeing the code you are using.

    Would you be able to share the code you are using to sign your requests?

    Thanks
    0
  • //YahooSocialAuthInfo has all the variables required ie. accessToken, Secret, oauth session handle and guid.
    YahooSocialAuthInfo ysai=(YahooSocialAuthInfo)getSNAuthInfo(authData);
    HashMap<String,String> params = new LinkedHashMap<String,String>();
    params.put("oauth_session_handle",ysai.getOauthSessionHandle());
    String requestUrl="https://api.login.yahoo.com/oauth/v2/get_token";
    String responseString=getHTTPTransmitResponseXML(ysai, "GET", requestUrl, params);

    public String getHTTPTransmitResponseXML(YahooSocialAuthInfo ysai,String methodType,String requestUrl, HashMap<String,String> paramMap){

    String responseXML=null;
    if(ysai!=null&&requestUrl!=null){

    String timestamp = String.valueOf(System.currentTimeMillis()/1000);
    String nonce = String.valueOf("OMB"+System.currentTimeMillis());
    String acctoken=ysai.getOauthToken();
    String accSecret=ysai.getOauthTokenSecret();

    HashMap<String,String> headerMap = new LinkedHashMap<String, String>();
    if(paramMap==null)
    paramMap = new LinkedHashMap<String,String>();

    headerMap.put("Accept", "*");

    paramMap.put("oauth_consumer_key", YahooSocialAppInfo.apiKey);
    paramMap.put("oauth_nonce", nonce);
    paramMap.put("oauth_signature_method", "HMAC-SHA1");
    paramMap.put("oauth_timestamp", timestamp);
    paramMap.put("oauth_token", acctoken);
    paramMap.put("oauth_version", "1.0");

    try{
    String baseString = getBaseString(methodType, requestUrl, paramMap);
    log.debug("baseString is : "+baseString);
    String signature = getSignatureHMAC(baseString,YahooSocialAppInfo.sharedSecret+"&"+accSecret).trim();
    paramMap.put("oauth_signature", signature);

    HttpTransmit httpTransmit = new HttpTransmit();
    HttpMessageInfo httpMessageInfo = new HttpMessageInfo();
    HttpProtocolInfo httpProtocolInfo = new HttpProtocolInfo();
    HttpResponseInfo httpResponseInfo = null;

    httpProtocolInfo.setHttpURL(requestUrl);
    SNCommonHelper.setProxy(httpProtocolInfo);
    httpMessageInfo.setMessageContentType("text/plain");
    httpMessageInfo.setHeaderMap(headerMap);
    httpMessageInfo.setParameterMap(paramMap);

    if(methodType.equals("GET")){
    httpResponseInfo = httpTransmit.sendGET(httpProtocolInfo, httpMessageInfo);
    }
    if (httpResponseInfo!= null && httpResponseInfo.statusCode == HttpStatus.SC_OK) {
    log.trace("status code : "+httpResponseInfo.statusCode);
    responseXML = httpResponseInfo.responseBody;
    }
    return responseXML;
    }

    public String getBaseString(String methodType, String url, Map<String, String> params){
    StringBuffer sb = new StringBuffer();
    String paramVal = null;
    boolean isFirst = true;
    StringBuffer baseStrBuff = new StringBuffer();

    baseStrBuff.append(methodType+"&"+escape(url));
    try{
    Collection<String> keySet= params.keySet();
    for (String paramName : keySet) {
    if( isFirst ) isFirst = false;
    else sb.append("&");
    paramVal = escape(params.get(paramName));
    sb.append(paramName+"="+paramVal);
    }
    }catch(Exception ex){
    log.error("Exception is : "+ex,ex);
    }
    log.debug("Query : "+sb.toString());
    if( sb.length()>0 ){
    baseStrBuff.append("&"+escape(sb.toString()));
    }

    return baseStrBuff.toString();
    }


    IM USING these same methods of HTTP transmit and getBaseString in all of my calls. But it's only refusing the signature in the case of REFRESHING TOKEN.
    Kindly suggest
    Thanks
    0
  • QUOTE (Jono @ Jan 27 2009, 09:25 PM) <{POST_SNAPBACK}>
    HashMap<String,String> params = new LinkedHashMap<String,String>();
    params.put("oauth_session_handle",ysai.getOauthSessionHandle());
    String requestUrl="https://api.login.yahoo.com/oauth/v2/get_token";
    String responseString=getHTTPTransmitResponseXML(ysai, "GET", requestUrl, params);

    public String getHTTPTransmitResponseXML(YahooSocialAuthInfo ysai,String methodType,String requestUrl, HashMap<String,String> paramMap){

    <snip>

    paramMap.put("oauth_consumer_key", YahooSocialAppInfo.apiKey);
    paramMap.put("oauth_nonce", nonce);
    paramMap.put("oauth_signature_method", "HMAC-SHA1");
    paramMap.put("oauth_timestamp", timestamp);
    paramMap.put("oauth_token", acctoken);
    paramMap.put("oauth_version", "1.0");

    <snip>


    The problem is the ordering of your parameters. You add oauth_session_handle before adding oauth_consumer_key and oauth_nonce. As a result, since you're using a LinkedHashMap and you're not sorting the keys during your loop, you end up signing the parameters in the wrong order. On the Yahoo! end of things, we're signing them in the correct order, causing a mismatch in the signature.

    There are two possible solutions to this:

    1) Change your code to either maintain the proper ordering of your HashMap (you maintain insertion order, not alphabetic order) or sort the keys before looping over them.

    2) Switch to using an OAuth client library, such as the one provided by OAuth.net (http://oauth.net/code).

    Option #2 is better because there are many other facets of OAuth that your code doesn't address. Unless you feel like fully implementing the OAuth specification to the letter, using an existing library will save you a considerable amount of work and pain.
    0
  • QUOTE (Ryan Kennedy @ Jan 28 2009, 11:08 AM) <{POST_SNAPBACK}>
    The problem is the ordering of your parameters. You add oauth_session_handle before adding oauth_consumer_key and oauth_nonce. As a result, since you're using a LinkedHashMap and you're not sorting the keys during your loop, you end up signing the parameters in the wrong order. On the Yahoo! end of things, we're signing them in the correct order, causing a mismatch in the signature.

    There are two possible solutions to this:

    1) Change your code to either maintain the proper ordering of your HashMap (you maintain insertion order, not alphabetic order) or sort the keys before looping over them.

    2) Switch to using an OAuth client library, such as the one provided by OAuth.net (http://oauth.net/code).

    Option #2 is better because there are many other facets of OAuth that your code doesn't address. Unless you feel like fully implementing the OAuth specification to the letter, using an existing library will save you a considerable amount of work and pain.


    i tried putting session_handle at the end. Still it says .. signature invalid...
    Also Kindly tell me the correct order of signing, as Yahoo is not giving any example of a baseString during refresh API.. Kindly tell me where to place Token and session handle..
    Although i've tried placing them at every possible place, still it's not working.
    Tell me one more thing.. Can we refresh the Token after it has expired
    And during signature creation, do we have to append the expired access_secret with SharedSecret??
    0
  • QUOTE (Jono @ Jan 28 2009, 11:13 PM) <{POST_SNAPBACK}>
    i tried putting session_handle at the end. Still it says .. signature invalid...


    You can't put it at the end, that's still out of order.

    QUOTE (Jono @ Jan 28 2009, 11:13 PM) <{POST_SNAPBACK}>
    Also Kindly tell me the correct order of signing, as Yahoo is not giving any example of a baseString during refresh API.. Kindly tell me where to place Token and session handle..
    Although i've tried placing them at every possible place, still it's not working.


    Yahoo! doesn't specify the correct order of signing, it's part of the OAuth specification.

    QUOTE (Jono @ Jan 28 2009, 11:13 PM) <{POST_SNAPBACK}>
    Tell me one more thing.. Can we refresh the Token after it has expired
    And during signature creation, do we have to append the expired access_secret with SharedSecret??


    Yes, you can refresh the token after it has expired. As for how you do signature creation, you'll need to follow the Scalable OAuth extension specification.
    0
  • QUOTE (Ryan Kennedy @ Feb 5 2009, 01:58 PM) <{POST_SNAPBACK}>
    You can't put it at the end, that's still out of order.

    i've tried putting it everywhere, it says signature invalid. Still you can tell me the order that has to be kept for the base string.

    QUOTE
    Yes, you can refresh the token after it has expired. As for how you do signature creation, you'll need to follow the Scalable OAuth extension specification.


    This Scalable OAuth Link helped. It gave lot of useful information. But Still i've now tried every possible thing. It works for all APIs except the ACCESS TOKEN RENEWABLE API. I'm generating the accessToken initially. It's working properly. So when i'm renewing it, i just have to include session_handle parameter along with it. So why it's not working. Kindly tell me if ACCESS TOKEN RENEWABLE is currently in BETA STAGE of YahooDevelopment or whatever it may be.

    Also there's no example of a baseString for Renewing access Token. Kindly generate one and display here ..

    THANKS A LOT
    0
  • While refreshing through Authorization Header. We pass all parameters in auth header and no parameters are added with the url... so while making basestring for signature, should we add the parameters? How Yahoo uses the Auth Header parameters? do they include in signature making.
    I always get signature invalid error..
    Can't yahoo pass the base string with the error..
    kindly see to this problem..
    0
  • were you able to solve this?

    QUOTE (Ankit B @ Feb 8 2009, 12:23 AM) <{POST_SNAPBACK}>
    While refreshing through Authorization Header. We pass all parameters in auth header and no parameters are added with the url... so while making basestring for signature, should we add the parameters? How Yahoo uses the Auth Header parameters? do they include in signature making.
    I always get signature invalid error..
    Can't yahoo pass the base string with the error..
    kindly see to this problem..
    0
  • QUOTE (teramera @ Mar 3 2009, 12:18 PM) <{POST_SNAPBACK}>
    were you able to solve this?


    Ive been able to successfully refresh the auth token. Here is what you need to take care of
    1. Are you using all the oauth parameters specified here: http://developer.yahoo.com/oauth/guide/oauth-auth-flow.html
    2. Are you generating the signature correctly as mentioned in the spec? For an informal description of the spec and a link of the spec itself, see: http://blog.andydenmark.com/2009/03/how-to...h-consumer.html

    I used the signpost packace available on github by Keppler : http://github.com/kaeppler/signpost

    I had to add my own code though, since signport is OAuth compliant, and Yahoo's "oauth_session_handle" is not part of signpost code. Remember, you will need "oauth_session_handle" as a parameter when creating your signature and as a string inside the "Authorization" header.

    Hope this helps,
    A M
    0
  • Hi Ashok,

    Thanks for the information. It is very useful for other developers.

    Thanks,
    Yu Wang
    0

Recent Posts

in OAuth General Discussion YDN SDKs