如何 oAuth 和 SOAP?

Posted

技术标签:

【中文标题】如何 oAuth 和 SOAP?【英文标题】:HOW TO oAuth and SOAP? 【发布时间】:2011-12-21 14:14:47 【问题描述】:

帮助! 我正在尝试升级可能的程序以支持 Google 在 AdWords 中使用的新 oAuth。 使用我的网站,我可以为我的用户创建 accessToken 和 accessTokenSecret 并将其存储在我的数据库中。

我的问题是当我稍后尝试使用这些凭据发出肥皂请求时。

我需要从网站部分保存哪些信息?到目前为止,我只保存了 accessToken 和 accessTokenSecret。还有什么吗? 如何使用 accessToken、accessTokenSecret 以及我保存的其他内容来发出 SOAP 请求? (请尽可能“低级”,“只在请求标头中使用它们”对我没有帮助)。

关于我的过程的一些信息:

不使用 Google 的客户端库(开销太大,到目前为止我不需要它们)。 在我正在使用的服务上使用使用 VS2005 WSDL 自动生成的 SOAP 代码。 C# 代码。

任何帮助将不胜感激。 谢谢!

================================================ ========================================= 按照建议,我已通过以下方式扩展 GetWebRequest:

protected override WebRequest GetWebRequest(Uri uri)
        
            WebRequest request = base.GetWebRequest(uri);

            String token = "XXXXXXXXXXX";//a valid token - changed for here.
            String secret = "XXXXXXXXXXXX";//a valid secret - changed for here.
            String consumerKey = "anonymous";
            String consumerSecret = "anonymous";
            String sigMet = "HMAC-SHA1";
            String oauth_timestamp = ((DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1).Ticks) / (1000 * 10000)).ToString();
            String oauth_nonce = Guid.NewGuid().ToString();

            Parameter[] paramArray = new Parameter[]
                                        new Parameter("oauth_consumer_key", consumerKey),
                                        new Parameter("oauth_token", token),
                                        new Parameter ("oauth_signature_method", sigMet),
                                        new Parameter ("oauth_timestamp", oauth_timestamp),
                                        new Parameter ("oauth_nonce", oauth_nonce)
                                        ;

            String oauth_signature = CreateHMACSHA1Signature(
                                        request.Method,
                                        uri,
                                        paramArray,
                                        consumerSecret,
                                        secret
                                        );

            request.Headers.Add(
                            "Authorization: OAuth " +
                            "realm=\"" + "https://www.google.com/" + "\"," +
                            "oauth_consumer_key=\"" + Parameter.EncodeParameterString(consumerKey) + "\"," +
                            "oauth_token=\"" + Parameter.EncodeParameterString(token) + "\"," +
                            "oauth_signature_method=\"" + Parameter.EncodeParameterString(sigMet) + "\"," +
                            "oauth_signature=\"" + Parameter.EncodeParameterString(oauth_signature) + "\"," +
                            "oauth_timestamp=\"" + Parameter.EncodeParameterString(oauth_timestamp) + "\"," +
                            "oauth_nonce=\"" + Parameter.EncodeParameterString(oauth_nonce) + "\""
                        );

            return request;
        

CreateHMACSHA1Signature 函数与 OAuthGetRequestTokenOAuthAuthorizeToken 使用的函数相同。但与 SOAP 一起使用时,出现以下错误: System.Web.Services.Protocols.SoapException: AuthenticationError.OAUTH_TOKEN_HEADER_INVALID @ Service[ServicedAccountService.get]

知道为什么吗?

【问题讨论】:

【参考方案1】:

我已经在Google Ads API, C#, SOAP request with new oAuth 1.0? 的.NET 客户端库的上下文中回答了这个问题。但要在 NoClientLibrary 上下文中回答您的问题,

    除了 OAuth 访问密钥和密钥之外,您只需要使用者密钥。

    您需要像请求普通的 OAuth 保护资源一样对请求进行签名。然后将签名放入 SOAP Web 请求的 Authorization HTTP 标头(不是 SOAP 标头)中。但是,获取 SOAPHttpClientProtocol 对象的底层 HttpWebRequest 并不是那么简单。您需要扩展 SOAPHttpClientProtocol 对象,覆盖受保护的 GetWebRequest 方法并在此阶段设置 OAuth 标头:类似于:

    protected override WebRequest GetWebRequest(Uri uri) 
      WebRequest request = base.GetWebRequest(uri);
      string oAuthHeader = SignTheRequestAndGetTheOAuthHeader(request);
      if (!string.IsNullOrEmpty(oAuthHeader)) 
         request.Headers["Authorization"] = oAuthHeader;
      
      return request;
    
    

这也意味着您必须手动修改自动生成的代码来更改存根服务类的基类,从长远来看,您不会享受太多。此外,如果您不知道如何正常请求受 OAuth 保护的资源,相关文档位于 http://oauth.net/core/1.0/#anchor13。

现在,在 .NET 客户端库中已经为您解决了这些问题。该库并不难使用,http://code.google.com/p/google-api-adwords-dotnet/wiki 有足够的 wiki 文章来指导您。我建议您使用 .NET 客户端库,但如果您选择不这样做,以下是您在采用 NoClientLibrary 路线时应注意的陷阱列表:http://code.google.com/p/google-api-adwords-dotnet/wiki/NoClientLibrary。

我还想提一下,AdWords API 官方论坛位于 http://groups.google.com/group/adwords-api?pli=1,我经常在那里回答开发人员的问题。如果您有任何后续问题,请随时在那里提问,我很乐意回答您的问题。

干杯, 阿纳什

【讨论】:

复习“code.google.com/p/google-api-adwords-dotnet/wiki/…”我看到那里有很多解释。如果只有关于如何创建“oAuth”的解释就像他们解释如何创建“AuthToken”一样,每件事都很棒。 嘿,听从您的建议,我似乎能够将我的 oauth 添加到请求中。但我收到 OAUTH_TOKEN_HEADER_INVALID 错误,我无法理解为什么。有什么想法吗?谢谢! 我现在正在度假,但我会在度假回来后添加 NoClientLibrary OAuth 版本。 FWIW,这是 OAuth code.google.com/apis/accounts/docs/OAuth_ref.html 的参考。唯一的区别是您的 AdWords API 范围不同。 如果您已正确完成所有签名,则 OAUTH_TOKEN_HEADER_INVALID 可能是因为您的范围不匹配。对于沙盒,它应该是adwords-sandbox.google.com/api/adwords,而对于生产帐户,它应该是adwords.google.com/api/adwords。【参考方案2】:

成功!!!

我很好地发现了问题所在,而且只是偶然。 创建签名时,我使用 request.method 作为方法参数。 问题在于,此时方法是“GET”,但 SOAP 机制会将其更改为“POST”(因此它可以传递 SOAP 参数),这导致我的签名不起作用。

我唯一需要做的就是改变:

String oauth_signature = CreateHMACSHA1Signature(
    request.Method,
    ...
    )

到:

String oauth_signature = CreateHMACSHA1Signature(
    "POST",
    ...
    )

【讨论】:

以上是关于如何 oAuth 和 SOAP?的主要内容,如果未能解决你的问题,请参考以下文章

Delphi 7 SOAP 身份验证和会话 ID 如何

如何使用 C# 发送/接收 SOAP 请求和响应?

REST 何时/如何取代 SOAP [关闭]

如何在PHP中传递SOAP标头和Body作为参数

如何通过 AFNetworking 和 NSUrlSession 调用 SOAP Web 服务

JAVA 如何解析soap