开发者

Verifying signed requests from Gmail contextual gadget

So, I'm using gadgets.io.makeRequest(url, callback, params) to make requests from Gmail contextual gadget and verifying these requests on the server side.

To clarify, I'm using the following makeRequest params on the gadget side:

params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.DOM;
params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
params["OAUTH_SERVICE_NAME"] = "HMAC";
params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET;

I've obtained gadget's consumerKey and consumerSecret from https://www.google.com/gadgets/directory/verify

According to Google's documentation, the request is signed by the container according to OAuth signing process HMAC-SHA1 method.

On the server side, I receive the following request:

http://my.dev.machine.com/blapage.aspx?oauth_body_hash=2jmj7l5rSw0yVb/vlWAYkK/YBwk=&opensocial_owner_id=103030060674287937707&opensocial_viewer_id=103030060674287937707&opensocial_app_id=103129310198020657787&opensocial_app_url=http://my.dev.machine.com/gadget.xml&oauth_version=1.0&oauth_timestamp=1284403586&oauth_nonce=6436223395511631796&opensocial_container=http://mail.google.com&oauth_consumer_key=419336943235&oauth_signature_method=HMAC-SHA1&oauth_signature=bshZj9XOXECdYiyR1J8Etnadv5c=

Then I'm signing this request according to the same OAuth specification that Google is supposed to use, but the signatures don't match.

I've already tried signing the request using 2 different libs:

  1. Our home-grown .Net lib, which is used to sign requests for Gmail IMAP OAuth authorization (which uses the same signing method and it works just fine there).
  2. One of the contributed opensocial libs (http://code.google.com/p/opensocial-net-client/)

Both libs produce similar signature base strings. However, weirdly enough, they produce different signatures, and none of these signatures match the one sent by Google in oauth_signature param!

Fellow gadget developers, I hope someone of you was more lucky then me and made this signa开发者_高级运维ture verification method work. Please, tell me what I'm doing wrong here.

Thanks in advance,

buru


I used this successfully:

public Boolean ValidateSignature(String method, Uri url)
        {
            String normalizedUrl, normalizedRequestParameters;

            List<QueryParameter> parameters = new List<QueryParameter>();
            parameters.AddRange(GetQueryParameters(url.Query));

            var sigParam = parameters.Find(p => p.Name == OAuthSignatureKey);
            if (sigParam == null)
                return false;
            var expected = sigParam.Value;

            parameters.Remove(parameters.Find(p => p.Name == OAuthSignatureKey));
            parameters.Sort(new QueryParameterComparer());

            normalizedUrl = string.Format("{0}://{1}", url.Scheme, url.Host);
            if (!((url.Scheme == "http" && url.Port == 80) || (url.Scheme == "https" && url.Port == 443)))
            {
                normalizedUrl += ":" + url.Port;
            }
            normalizedUrl += url.AbsolutePath;
            normalizedRequestParameters = NormalizeRequestParameters(parameters);

            StringBuilder signatureBase = new StringBuilder();
            signatureBase.AppendFormat("{0}&", method.ToUpper());
            signatureBase.AppendFormat("{0}&", UrlEncode(normalizedUrl));
            signatureBase.AppendFormat("{0}", UrlEncode(normalizedRequestParameters));

            HMACSHA1 hmacsha1 = new HMACSHA1();
            hmacsha1.Key = Encoding.ASCII.GetBytes(string.Format("{0}&{1}", UrlEncode(ConsumerSecret), ""));//string.IsNullOrEmpty(tokenSecret) ? "" : UrlEncode(tokenSecret)));

            var computed = GenerateSignatureUsingHash(signatureBase.ToString(), hmacsha1);
            return expected == UrlEncode(computed);
        } 

together with the code you can find here: http://oauth.googlecode.com/svn/code/csharp/OAuthBase.cs

EDIT: when making requests and sending parameters via get or post this did not work. What seems to be the problem is that Gmail sorts the parameters with uppercase characters coming first. I resorted to only use lowercase parameters but you could easily fix the code to make sure uppercase comes before lowercase.


Daniels method works fine with one small change.

  • GetQueryParameters needs an implementation to retrieve all query parameters. The implementation in OAuthBase only returns those not prefixed with 'oauth_'

My main problem was that the Gadget making the call was using gadgets.io.makeRequest to 'http://myserver.com', but the handling page was 'http://myserver.com/default.aspx'. The signature was not validating due to this difference. Calling 'http://myserver.com/default.aspx' using gadgets.io.makeRequest from within the Gadget solved things.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜