使用Google Calendar Feed的DotNetOpenAuth

时间:2010-10-02 08:45:06

标签: c# asp.net oauth dotnetopenauth google-calendar-api

我试图通过使用DotNetOpenAuth从Google获取日历列表几天来绞尽脑汁。

我可以使用DotNetOpenAuth示例成功获取联系人列表。我已使用OpenId + OAuth将其与我的域集成。一切都很好,以获得联系人列表。

所以我从那里修改了代码以尝试检索日历列表,并且我一直收到401 Unauthorized错误。

我知道这是授权,因为我可以获得联系人列表。有没有人有一个代码示例,他们如何使用谷歌DotNetOpenAuth检索日历或日历事件?

由于

更新

感谢您的回复。我已经阅读了所有可以得到的东西。这是我到目前为止所做的事情

第1步:我在GoogleConsumer.cs中创建了一个新的GetCalendarEndPoint

private static readonly MessageReceivingEndpoint GetCalendarEndpoint = new MessageReceivingEndpoint("https://www.google.com/calendar/feeds/default", HttpDeliveryMethods.GetRequest);

第2步:接下来,我在GoogleConsumer.cs中的GetContacts方法之后创建了一个新方法GetCalendars - (重建了dll等)。

    public static XDocument GetCalendars(ConsumerBase consumer, string accessToken, int maxResults/* = 25*/, int startIndex/* = 1*/) {
            if (consumer == null)
            {
                throw new ArgumentNullException("consumer");
            }

            var request = consumer.PrepareAuthorizedRequest(GetCalendarEndpoint, accessToken);
            var response = consumer.Channel.WebRequestHandler.GetResponse(request);
            string body = response.GetResponseReader().ReadToEnd();
            XDocument result = XDocument.Parse(body);
            return result;

第3步:在我的应用程序中,我将ScopeURI从GoogleConsumer修改为日历URI,如下所示

private IAuthenticationRequest GetGoogleRequest()
{
    Realm realm = Request.Url.Scheme + Uri.SchemeDelimiter + Global.GoogleTokenManager.ConsumerKey + "/";
    IAuthenticationRequest authReq = relyingParty.CreateRequest(GoogleOPIdentifier, realm);

    // Prepare the OAuth extension
    string scope = GoogleConsumer.GetScopeUri(GoogleConsumer.Applications.Calendar);
    Global.GoogleWebConsumer.AttachAuthorizationRequest(authReq, scope);

    // We also want the user's email address
    var fetch = new FetchRequest();
    fetch.Attributes.AddRequired(WellKnownAttributes.Contact.Email);
    authReq.AddExtension(fetch);

    return authReq;
}

但是,当我运行应用程序时,我拨打以下电话时会获得401 Unauthorized

 var calendars = GoogleConsumer.GetCalendars(Global.GoogleWebConsumer, State.GoogleAccessToken, 25, 1);

在触发拨打此电话的方法之前,我还检查过State.GoogleAccess令牌是否存在,只需将其显示在我的屏幕上即可。

再次,如果我exectute

var calendars = GoogleConsumer.GetContacs(Global.GoogleWebConsumer, State.GoogleAccessToken, 25, 1);

然后它的工作原理???????谢谢你的帮助。

2 个答案:

答案 0 :(得分:4)

在周末的大部分时间里,我一直在遭受同样的痛苦。

我认为,在充分摆弄Fiddler之后,我找到了原因并找到了一个解决方案,虽然不是很好,但似乎有效。我发现通过将DNOA生成的Uri复制并粘贴到浏览器中,我可以访问日历源,但在尝试编程访问时总是得到401。这显然是因为HttpWebRequest的默认自动重定向行为会丢弃重定向尝试设置的任何cookie。 “联系人”供稿在重定向期间未设置任何Cookie,因此它具有免疫力。

首次请求日历Feed时(即使使用正确构建和签名的OAuth请求),Google也会回复包含Cookie的重定向。如果您没有在Feed请求的同时提供“日历Cookie”,那么当您尝试按照重定向到Feed时,您将获得401 Unauthorized。

这是来自Google的Cookie设置标题:

HTTP/1.1 302 Moved Temporarily
Set-Cookie: S=calendar=y7AlfgbmcqYl0ugrF-Zt9A;Expires=Tue, 10-Jan-2012 03:54:20 GMT;Secure

以下是我正在做的工作:

// wc: WebConsumer
var calRequest = wc.PrepareAuthorizedRequest(erp2, authTokenRsp.AccessToken);
// need to stop redirect to capture calendar cookie token:
calRequest.AllowAutoRedirect = false;
var calResponse = calRequest.GetResponse();
var redirectCookie = calResponse.Headers[System.Net.HttpResponseHeader.SetCookie];

var cookiedCalRequest = wc.PrepareAuthorizedRequest(erp2, authTokenRsp.AccessToken);
cookiedCalRequest.Headers[System.Net.HttpRequestHeader.Cookie] = redirectCookie;
var calFeedResponse = cookiedCalRequest.GetResponse();

答案 1 :(得分:1)

您是否阅读过Google日历数据API文档以确保编写了正确的端点?除了Google通讯录之外,您是否还修改了获取访问令牌的代码以请求访问Google日历?除非您更改,否则示例中的访问令牌仅获取“联系人”权限。