C# Gmail的OAuth 2.0身份验证适用于Gmail.com域的帐户,但不适用于谷歌应用程序域

C# Gmail的OAuth 2.0身份验证适用于Gmail.com域的帐户,但不适用于谷歌应用程序域,c#,gmail,imap,google-oauth,google-apps,C#,Gmail,Imap,Google Oauth,Google Apps,我有一个C#安装的应用程序,可以通过IMAP访问Gmail。使用传统的IMAP身份验证,它对个人Gmail用户和谷歌应用程序用户都很有效 现在,我使用Google的.NETAPI添加了对OAuth2.0身份验证的支持。这对于普通的Gmail帐户(例如。someone@gmail.com)但对于具有不同域的Google Apps帐户,则失败。系统会提示用户通过web浏览器登录并接受访问,但IMAP身份验证尝试失败,并显示“凭据无效”。对于Google应用程序域,是否需要做一些不同的事情 正如我在

我有一个C#安装的应用程序,可以通过IMAP访问Gmail。使用传统的IMAP身份验证,它对个人Gmail用户和谷歌应用程序用户都很有效

现在,我使用Google的.NETAPI添加了对OAuth2.0身份验证的支持。这对于普通的Gmail帐户(例如。someone@gmail.com)但对于具有不同域的Google Apps帐户,则失败。系统会提示用户通过web浏览器登录并接受访问,但IMAP身份验证尝试失败,并显示“凭据无效”。对于Google应用程序域,是否需要做一些不同的事情


正如我在下面的评论中第一次报道的那样,我在这方面取得了一个小小的突破。最初,我使用用户参数的文本字符串“user”调用GoogleWebAuthorizationBroker.AuthorizeAsync()。这对普通Gmail用户有效,但我发现,对于谷歌应用程序,必须传递授权用户的实际电子邮件地址

有一段时间我认为这就是问题的全部解决方案。但事实证明并非如此。问题是,它现在在内部测试中工作得很好,但在我们的一个beta测试站点上,它通常以同样的方式失败。我只能想到失败的4个可能原因:(1)程序获取了无效的访问令牌,(2)它以某种方式损坏了该令牌,(3)它错误地执行了XOAUTH身份验证,或者(4)它正在使用该令牌对令牌未申请的帐户进行身份验证。我认为谷歌不太可能提供无效的代币,因此(1)可以在很大程度上打折。(2) 和(3)总是可能的,但事实上,这些代码适用于我们自己的几个Gmail和Google应用程序帐户,这使得它们看起来不太可能。客户坚持(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);
...

我仍在为此挣扎,走上了死胡同,变得更加沮丧。我必须纠正我之前说过的一件事:我断言该程序在内部测试中适用于谷歌应用程序域。这是一种错觉;事实上从来没有


有人告诉我,我需要使用一个服务帐户来覆盖域用户。这对我来说似乎很困惑,因为我的程序在任何意义上都不是服务器,但我试过了。而且它并没有像我尝试的那样起作用——但我不能确定我做对了。确认或否定使用服务帐户是正确的策略将大有帮助。

在没有看到您的代码的情况下,我唯一的预感是您没有发送初始客户响应的完整电子邮件地址:


除此之外,显示您的代码可能有助于我们了解问题。

您可能需要检查您的域帐户中是否激活了IMAP/POP;在我工作的公司,出于安全原因,他们限制了这种访问,以下是您应该如何启用它:

在Gmail设置中启用IMAP

登录到Gmail。 单击右上角的齿轮。 选择设置。 单击转发并弹出/IMAP。 选择启用IMAP。 单击保存更改


参考:好主意,谢谢,但这不是问题所在。当IMAP未启用时,Gmail可以发送一个IMAP响应,说“登录为”user@domain.com“已拒绝:[警报]您的帐户未启用IMAP使用。请访问您的Gmail设置页面并启用您的IMAP访问帐户。(失败)下一步就是查看代码(即使只是演示问题的一个小示例)。仅供参考,我的项目GYB是开源的,支持Gmail IMAP OAuth 2.0身份验证。它成功地与gmail.com和谷歌应用程序账户合作:啊哈,我刚刚在看GYB。我会再看一次,看看它是否显示出我遗漏了什么。谢谢这听起来也是个好主意,谢谢。但是,我已经检查并验证了我发送的是完整的电子邮件地址。我会多看一点,然后可能会发布一些代码。顺便说一句,我相信base64中有一个错误,在初始客户端响应的末尾包含一个不应该存在的换行符。请参阅base64上面的描述,“base64编码后,这变成(为清晰起见插入换行符)”我相信你一定误解了那句话。或者我没有清楚地描述我所看到的问题。据我所知,该语句只承认base64字符串在该文档中被拆分为两行。如果您解码base64并查看解码数据的最后一个字符,您将看到上面示例中没有的换行符,如果保留该换行符,将导致身份验证失败。我不得不将此项目搁置几周,但我现在正在重新处理它,并已找出问题所在。我调用了GoogleWebAuthorizationBroker.AuthorizeAsync(),用户参数的文本字符串为“user”(因为这是我在许多示例中看到的)。这对普通Gmail用户有效,但我发现,对于谷歌应用程序,必须传递授权用户的实际电子邮件地址。