【发布时间】:2014-02-13 17:39:56
【问题描述】:
我有一个通过 IMAP 访问 Gmail 的 C# 安装应用程序。使用传统的 IMAP 身份验证,它既适用于个人 Gmail 用户,也适用于 Google Apps 用户。
我现在使用 Google 的 .Net API 添加了对 OAuth 2.0 身份验证的支持。这对于普通的 Gmail 帐户(例如某人@gmail.com)非常有效,但对于具有不同域的 Google Apps 帐户却失败了。系统会提示用户通过 Web 浏览器登录并接受访问,但 IMAP 身份验证尝试失败并显示“凭据无效”。对于 Google Apps 域,是否需要做一些不同的事情?
正如我在下面的评论中首次报道的那样,我在这方面取得了一些小突破。最初,我使用用户参数的文字字符串“user”调用 GoogleWebAuthorizationBroker.AuthorizeAsync()(因为这是我在许多示例中看到的)。这适用于普通 Gmail 用户,但我发现,对于 Google Apps,必须传递授权用户的实际电子邮件地址。
有一段时间我认为这是解决问题的全部方法。然而事实证明并非如此。问题是它现在在内部测试中运行良好,但在我们拥有的一个 beta 站点上经常以同样的方式失败。我只能想到 4 个可能的失败原因:(1)程序获得了无效的访问令牌,(2)它以某种方式破坏了该令牌,(3)它错误地执行了 XOAUTH 身份验证或(4)它是使用token对未申请token的账户进行认证。我认为谷歌不太可能提供无效的令牌,因此(1)可以在很大程度上打折。 (2) 和 (3) 总是可能的,但代码适用于我们自己的多个 Gmail 和 Google Apps 帐户的事实使它们看起来不太可能。而客户坚持认为(4)并非如此。所以我仍然感到困惑。
早期有人建议我发布我的一些代码,我现在准备这样做。以下是执行身份验证的 C# 函数的开始:
private void AuthenticateXOAuth2(string strUsername, string strAccessToken)
{
uint uStatus = 0;
// The SASL XOAUTH2 initial client response has the following format:
//
// base64("user=" {User} "^Aauth=Bearer " {Access Token} "^A^A")
string strInitialClientResponse = "user=" + strUsername + "\x1" + "auth=Bearer " + strAccessToken + "\x1\x1";
byte[] vbInitialClientResponse = Encoding.UTF8.GetBytes(strInitialClientResponse);
string strBase64InitialClientResponse = System.Convert.ToBase64String(vbInitialClientResponse);
string strCommand = "AUTHENTICATE XOAUTH2 " + strBase64InitialClientResponse;
SendCommand(strCommand);
...
我仍在为此苦苦挣扎,走上死胡同,变得更加沮丧。我必须纠正我之前说过的一件事:我断言该程序在内部测试中适用于 Google Apps 域。这是一种错觉。它实际上从来没有。
有人告诉我,我需要使用服务帐户来覆盖域用户。这对我来说似乎令人费解,因为我的程序在任何意义上都不是服务器,但我试过了。它并没有像我尝试的那样工作——但我不能确定我做对了。确认或否定使用服务帐户是正确的策略会大有帮助。
【问题讨论】:
标签: c# gmail imap google-oauth google-apps