从Windows Azure(ASP.NET MVC)的GMAIL API访问被拒绝访问

问题描述:

从Windows Azure(ASP.NET MVC)中,我遇到了GMAIL API的问题。从Windows Azure(ASP.NET MVC)的GMAIL API访问被拒绝访问

从本地或控制台应用程序一切正常,当我将它移动到我的云服务我得到一个“访问被拒绝”的错误。

很明显,在Google Cloud Platform控制台上,我使用“localhost”和“myurl”来使其工作。

这是我的代码:

UserCredential credential; 

      using (var stream = new FileStream(diskPath + "/Content/client_secret.json", FileMode.Open, FileAccess.Read)) 
      { 
       credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
        GoogleClientSecrets.Load(stream).Secrets, 
        Scopes, 
        "user", 
        CancellationToken.None 
        ); 
      } 

      var service = new GmailService(new BaseClientService.Initializer() 
      { 
       HttpClientInitializer = credential, 
       ApplicationName = ApplicationName, 
      }); 

      var resp = await service.HttpClient.GetStringAsync("https://www.googleapis.com/gmail/v1/users/me/messages?q=\"has:attachment\""); 

我的错误上

await GoogleWebAuthorizationBroker.AuthorizeAsync(
        GoogleClientSecrets.Load(stream).Secrets, 
        Scopes, 
        "user", 
        CancellationToken.None 
        ); 

我有最后一个包从针对的NuGet谷歌API的OAuth(https://www.nuget.org/packages/Google.Apis.Oauth2.v2)。

我在网上看到somebady引用一些access_type =离线参数,但我找不到任何“完全正常”的例子。

为什么我会在本地和Azure之间获得巨大的差异?

最后我发现我的解决方案出了什么问题!

按照本教程中的一切工作正常:

https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth#web-applications-aspnet-mvc

汇总:

Web应用程序(ASP。NET MVC)

Google API支持用于Web服务器应用程序的OAuth 2.0。为了成功运行以下代码,您必须先在Google API控制台中将重定向URI添加到您的项目中。由于您将使用FlowMetadata及其默认设置,因此请将重定向URI设置为your_site/AuthCallback/IndexAsync。

要查找重定向的URI OAuth 2.0凭据,请执行以下操作:

打开API控制台的凭据页。 如果您尚未这样做,请通过单击创建凭证> OAuth客户端ID来创建您的OAuth 2.0凭证。 创建凭证后,通过单击OAuth 2.0客户端ID部分中的客户端ID(针对Web应用程序)来查看或编辑重定向URL。 在您的IDE中创建新的Web应用程序项目之后,为Drive,YouTube或您要使用的其他服务添加正确的Google.Apis NuGet包。然后,添加Google.Apis.Auth.MVC包。以下代码演示了查询Google API服务的ASP.NET MVC应用程序。

1)添加您自己的FlowMetadata实现。

public class AppFlowMetadata : FlowMetadata 
{ 
    private static readonly IAuthorizationCodeFlow flow = 
     new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer 
      { 
       ClientSecrets = new ClientSecrets 
       { 
        ClientId = "PUT_CLIENT_ID_HERE", 
        ClientSecret = "PUT_CLIENT_SECRET_HERE" 
       }, 
       Scopes = new[] { DriveService.Scope.Drive }, 
       DataStore = new FileDataStore("Drive.Api.Auth.Store") 
      }); 

    public override string GetUserId(Controller controller) 
    { 
     // In this sample we use the session to store the user identifiers. 
     // That's not the best practice, because you should have a logic to identify 
     // a user. You might want to use "OpenID Connect". 
     // You can read more about the protocol in the following link: 
     // https://developers.google.com/accounts/docs/OAuth2Login. 
     var user = controller.Session["user"]; 
     if (user == null) 
     { 
      user = Guid.NewGuid(); 
      controller.Session["user"] = user; 
     } 
     return user.ToString(); 

    } 

    public override IAuthorizationCodeFlow Flow 
    { 
     get { return flow; } 
    } 
} 

FlowMetadata是一个包含自己的逻辑来检索用户标识符和正在使用的IAuthorizationCodeFlow的抽象类。

在上面的示例代码中,创建了一个新的GoogleAuthorizationCodeFlow,其中包含正确的作用域,客户机密钥和数据存储。考虑添加您自己的IDataStore实现,例如您可以编写一个使用EntityFramework的实现。

2)实现您自己的控制器,使用Google API服务。以下示例使用DriveService:

public class HomeController : Controller 
{ 
    public async Task IndexAsync(CancellationToken cancellationToken) 
    { 
     var result = await new AuthorizationCodeMvcApp(this, new AppFlowMetadata()). 
      AuthorizeAsync(cancellationToken); 

     if (result.Credential != null) 
     { 
      var service = new DriveService(new BaseClientService.Initializer 
       { 
        HttpClientInitializer = result.Credential, 
        ApplicationName = "ASP.NET MVC Sample" 
       }); 

      // YOUR CODE SHOULD BE HERE.. 
      // SAMPLE CODE: 
      var list = await service.Files.List().ExecuteAsync(); 
      ViewBag.Message = "FILE COUNT IS: " + list.Items.Count(); 
      return View(); 
     } 
     else 
     { 
      return new RedirectResult(result.RedirectUri); 
     } 
    } 
} 

3实现您自己的回调控制器。实施应该是这样的:

public class AuthCallbackController : Google.Apis.Auth.OAuth2.Mvc.Controllers.AuthCallbackController 
{ 
    protected override Google.Apis.Auth.OAuth2.Mvc.FlowMetadata FlowData 
    { 
     get { return new AppFlowMetadata(); } 
    } 
} 

这个例子是谷歌驱动器,但如果你想(像我一样)得到它的工作对GMAIL API,你只是DriveService和GmailService

之间切换

基于此documentation,当您尝试在Visual Studio .NET中调试Web应用程序并且您具有管理权限时,可能会收到Access is denied错误消息。

  • 您登录到您的计算机管理权限:

    问题当满足下列条件为真会发生。

  • 您正在调试Microsoft Visual Studio .NET中的Web应用程序。
  • 您正在使用的操作系统是Microsoft Windows XP Service Pack 2.
  • Microsoft ASP.NET辅助进程帐户不是管理员组的成员。

发生此问题的原因是ASP.NET工作进程在身份验证用户权限后没有模拟客户端。如果工作进程帐户没有此权限,则调试程序无法附加到进程。工作进程帐户通过使用Machine.config文件中的processModel元素进行配置。

您还可以检查此post中给出的解决方法。检查您是否在​​标记内添加了以下标记web.config文件。

<defaultDocument>  
    <files>  
     <add value="Pages/Home.aspx"/>  
    </files>  
</defaultDocument>