【问题标题】:.NET Google GData Docs API with OAuth 2.0 returning 401.NET Google GData Docs API 与 OAuth 2.0 返回 401
【发布时间】:2011-12-07 10:37:24
【问题描述】:

我目前正在编写一个使用 Google Docs 和 Calendar API 的 .NET WPF 应用程序。我计划在稍后阶段集成一些较新的 API,例如 Tasks,因此我现在想开始使用 OAuth 2.0 做准备。我已经能够获取和存储刷新和访问令牌,并且我已经实现了一些逻辑来在当前令牌过期时检索进一步的访问令牌。但是,我在将文档上传到谷歌文档时遇到了很多麻烦。似乎 GData 客户端库本身并不支持 OAuth 2.0,我不想迁移到较新的客户端库(例如,用于任务),因为在这个阶段我不希望依赖 DotNetOpenAuth。相反,我实现了自己的 OAuth2Authenticator,它添加了所需的 OAuth 2 标头,我将它与 GData ResumableUploader 一起使用。当我尝试使用 ResumableUploader 发送上传文档的请求时,我收到 401 Unauthorized 响应,其中包含消息 Token Invalid - Invalid AuthSub token。

我是这样打电话的:

ResumableUploader ru = new ResumableUploader(512);

Document entry = new Document();
entry.Title = documentName;
entry.MediaSource = new MediaFileSource(localDocumentPath, "application/pdf");
entry.Type = Document.DocumentType.PDF;

Uri createUploadUrl = new Uri("https://docs.google.com/feeds/upload/create-session/default/private/full");
AtomLink link = new AtomLink(createUploadUrl.AbsoluteUri);
link.Rel = ResumableUploader.CreateMediaRelation;
entry.DocumentEntry.Links.Add(link);

ru.Insert(new OAuth2Authenticator("MyApplicationName", "MyAccessToken"), entry.DocumentEntry);

导致此请求(来自 Fiddler):

POST https://docs.google.com/feeds/upload/create-session/default/private/full
HTTP/1.1 Authorization: OAuth sOmeTThing+SomThNig+etc==
Slug: DOC_0108.pdf
X-Upload-Content-Type: application/pdf
X-Upload-Content-Length: 175268
GData-Version: 3.0
Host: docs.google.com
Content-Type: application/atom+xml; charset=UTF-8
Content-Length: 508 Connection: Keep-Alive

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom"
 xmlns:gd="http://schemas.google.com/g/2005"
 xmlns:docs="http://schemas.google.com/docs/2007">
   <title type="text">DOC_0108.pdf</title>
   <link href="https://docs.google.com/feeds/upload/create-session/default/private/full"
    rel="http://schemas.google.com/g/2005#resumable-create-media" />  
   <category term="http://schemas.google.com/docs/2007#pdf"
    scheme="http://schemas.google.com/g/2005#kind" label="pdf" />
</entry>

以及相关的 401 响应:

HTTP/1.1 401 Unauthorized
Server: HTTP Upload Server Built on Sep 27 2011 04:44:57 (1317123897)
WWW-Authenticate: AuthSub realm="http://www.google.com/accounts/AuthSubRequest"
Content-Type: text/html; charset=UTF-8
Content-Length: 38
Date: Thu, 13 Oct 2011 08:45:11 GMT
Pragma: no-cache
Expires: Fri, 01 Jan 1990 00:00:00 GMT
Cache-Control: no-cache, no-store, must-revalidate

Token invalid - Invalid AuthSub token.

我已经在标题中尝试了“授权:OAuth”和“授权:承载”,因为 API 和 OAuth 2.0 文档似乎分开了,我还尝试将令牌附加为查询字符串 (?access_token=和 ?oauth_token=) 但所有这些都给出相同的响应。

我已经浏览了所有我能找到的 Google API 和 OAuth 问题、博客文章、文档,并尝试了多种执行此调用的方法(使用 .NET GData API 的多种实现、REST 客户端 NuGet 包、我自己的 REST客户端实现等),我无法解决这个问题。

任何帮助将不胜感激。

【问题讨论】:

    标签: c# .net gdata oauth-2.0


    【解决方案1】:

    我可以使用 OAuth 获取和创建文档。在通过 Google 进行身份验证以访问 docs 范围后,我将执行以下操作:

    // get the list of available google docs
            RequestSettings settings = new RequestSettings(kApplicationName);
            settings.AutoPaging = false;
            if (settings != null)
            {
                DocumentsRequest request = new DocumentsRequest(settings);
                request.Service.RequestFactory = GetGoogleOAuthFactory();
                Feed<Document> feed = request.GetEverything();
    
                List<Document> all = new List<Document>(feed.Entries);
    
                // loop through the documents and add them from google
                foreach (Document entry in all)
                {
                    // first check to see whether the document has already been selected or not
                    bool found = model.Docs.Any(d => d.GoogleDocID == entry.ResourceId);
                    if (!found)
                    {
                        GoogleDocItem doc = new GoogleDocItem();
                        doc.GoogleDocID = entry.ResourceId;
                        doc.ETag = entry.ETag;
    
                        doc.Url = entry.DocumentEntry.AlternateUri.Content;
                        doc.Title = entry.Title;
                        doc.DocType = entry.Type.ToString();
                        doc.DocTypeID = entry.Type;
    
                        if (entry.ParentFolders.Count == 0)
                        {
                            // add the doc to the list
                            model.AvailableDocs.Add(doc);
    
                            // if the doc is a folder, get the children
                            if (doc.DocTypeID == Document.DocumentType.Folder)
                            {
                                AddAllChildrenToFolder(ref doc, entry, all);
                            }
                        }
                    }
                }
            }
    
    public GOAuthRequestFactory GetGoogleOAuthFactory()
        {
            // build the base parameters
            OAuthParameters parameters = new OAuthParameters
            {
                ConsumerKey = kConsumerKey,
                ConsumerSecret = kConsumerSecret
            };
    
            // check to see if we have saved tokens and set
            var tokens = (from a in context.GO_GoogleAuthorizeTokens select a);
            if (tokens.Count() > 0)
            {
                GO_GoogleAuthorizeToken token = tokens.First();
                parameters.Token = token.Token;
                parameters.TokenSecret = token.TokenSecret;
            }
    
            // now build the factory
            return new GOAuthRequestFactory("anyname", kApplicationName, parameters);
        }
    

    我在这里发布了我的授权示例:.net - Google / OAuth 2 - Automatic logon。 DocumentsRequest 来自 Google 的 .NET 二进制文件。虽然我还没有使用它创建新文档,但我确实使用类似的类来创建日历项目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-13
      • 2011-11-01
      • 2018-07-01
      • 2014-03-27
      • 2012-09-29
      • 2020-06-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多