验证来自 Gmail 上下文小工具的签名请求

发布于 2024-09-19 14:51:42 字数 2448 浏览 14 评论 0原文

因此,我使用 gadgets.io.makeRequest(url, callback, params) 从 Gmail 上下文小工具发出请求,并在服务器端验证这些请求。

为了澄清,我在小工具端使用以下 makeRequest 参数:

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;

我已从 https://www.google.com/gadgets/directory/verify
根据 Google 文档,该请求由容器根据 OAuth 签名流程 HMAC-SHA1 方法。

在服务器端,我收到以下请求:

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=643 6223395511631796&opensocial_container=http://mail.google.com& oauth_consumer_key=419336943235&oauth_signature_method=HMAC-SHA1&oauth_signature=bshZj9XOXECdYiyR1J8Etnadv5c=

然后,我根据 Google 应该使用的相同 OAuth 规范签署此请求,但签名不匹配。

我已经尝试使用 2 个不同的库对请求进行签名:

  1. 我们自行开发的 .Net 库,用于对 Gmail IMAP OAuth 授权请求进行签名(它使用相同的签名方法,并且在那里工作得很好)。
  2. 贡献的 opensocial 库之一 (http://code.google.com/p/ opensocial-net-client/

两个库都会生成类似的签名基本字符串。然而,奇怪的是,它们产生不同的签名,并且这些签名都不与 Google 在 oauth_signature 参数中发送的签名匹配!

各位小工具开发人员,我希望你们中有人比我更幸运,并使这个签名验证方法发挥作用。请告诉我我在这里做错了什么。

提前致谢,
布鲁

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 signature verification method work. Please, tell me what I'm doing wrong here.

Thanks in advance,

buru

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

以可爱出名 2024-09-26 14:53:23

丹尼尔斯方法只需稍加改变就可以很好地发挥作用。

  • GetQueryParameters 需要一个实现来检索所有查询参数。 OAuthBase 中的实现仅返回那些不以“oauth_”为前缀的内容

我的主要问题是进行调用的小工具使用 gadgets.io.makeRequest 到“http://myserver.com”,但处理页面是“http://myserver.com” /myserver.com/default.aspx'。由于这种差异,签名无法验证。使用小工具内的 gadgets.io.makeRequest 调用“http://myserver.com/default.aspx”解决了问题。

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.

握住我的手 2024-09-26 14:53:02

我成功地使用了它:

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);
        } 

以及您可以在此处找到的代码:
http://oauth.googlecode.com/svn/code/csharp/OAuthBase.cs

编辑
当通过 get 或 post 发出请求并发送参数时,这不起作用。
问题似乎在于 Gmail 对参数进行排序时,大写字符排在前面。我只使用小写参数,但您可以轻松修复代码以确保大写字母出现在小写字母之前。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文