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

时间:2017-04-02 21:30:41

标签: c# asp.net azure 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 = offline参数,但我找不到任何“完全正常”的例子。

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

2 个答案:

答案 0 :(得分:0)

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

  

满足以下条件时会出现问题:

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

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

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

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

答案 1 :(得分:0)

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

按照本教程,一切正常:

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

汇总:

Web应用程序(ASP.NET MVC)

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

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

在API控制台中打开“凭据”页面。 如果您还没有这样做,请点击创建凭据&gt;创建您的OAuth 2.0凭据。 OAuth客户端ID。 创建凭据后,通过单击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(); }
    }
}

此示例适用于Google云端硬盘,但如果您希望(正如我所做)使其适用于GMAIL API,则只需在DriveService和GmailService之间切换