使用OAuth2通过C#中的Google API进行身份验证

时间:2017-02-24 11:26:44

标签: c# azure google-api google-oauth google-api-dotnet-client

我创建了一个控制台应用程序,它使用OAuth2对GoogleAnalyticsApiV4进行身份验证,以查询某些数据。应用程序按预期工作,但我们希望自动化该过程,以便可以安排应用程序每天运行一次。这里的问题是应用程序将托管在azure上,并且用户无法接受第一次运行应用程序时在浏览器中弹出的google的身份验证请求。

在线发帖和googles文档后,我当前的身份验证解决方案是

     try
        {
            var credential = GetCredential().Result;

            using (var svc = new AnalyticsReportingService(
            new BaseClientService.Initializer
            {
                HttpClientInitializer = credential,
                ApplicationName = "Google Analytics API Console"
            }))
        {
           ///// Query some data/////
        } 



static async Task<UserCredential> GetCredential()
{
    using (var stream = new FileStream("client_secret.json",
         FileMode.Open, FileAccess.Read))
    {
        string loginEmailAddress = ConfigurationManager.AppSettings["GoogleUsername"];
        return await GoogleWebAuthorizationBroker.AuthorizeAsync(
            GoogleClientSecrets.Load(stream).Secrets,
            new[] { AnalyticsReportingService.Scope.Analytics },
            loginEmailAddress, CancellationToken.None,
            new FileDataStore("GoogleAnalyticsApiConsole"));
    }
}

只要用户可以输入凭据并接受身份验证请求,此解决方案就可以很好地与Google进行身份验证。不幸的是,只要将应用程序移动到另一台计算机,就需要重新进行身份验证,用户需要再次输入凭据并接受请求。

我一直在寻找一种让用户退出流程的方法,以便应用程序可以在azure上运行,但是在c#中没有找到任何关于如何做到这一点的清楚。

有人可以描述我如何在没有用户的情况下使用谷歌验证我的应用程序,或者指出我的文档方向准确地介绍了该过程。

非常感谢帮助或示例。

1 个答案:

答案 0 :(得分:1)

你有几个选择。

这是您有权访问的帐户吗?如果是,那么您可以使用服务帐户。服务帐户被预先授权您获取服务帐户电子邮件地址,并在帐户级别的Google Analytics管理员中将其添加为用户,并且只要服务帐户有效,服务帐户就可以访问该帐户。无需弹出窗口。我有一些关于如何使用服务帐户here

进行身份验证的示例代码
/// <summary>
    /// Authenticating to Google using a Service account
    /// Documentation: https://developers.google.com/accounts/docs/OAuth2#serviceaccount
    /// </summary>
    /// <param name="serviceAccountEmail">From Google Developer console https://console.developers.google.com</param>
    /// <param name="serviceAccountCredentialFilePath">Location of the .p12 or Json Service account key file downloaded from Google Developer console https://console.developers.google.com</param>
    /// <returns>AnalyticsService used to make requests against the Analytics API</returns>
    public static AnalyticsReportingService AuthenticateServiceAccount(string serviceAccountEmail, string serviceAccountCredentialFilePath)
    {
        try
        {
            if (string.IsNullOrEmpty(serviceAccountCredentialFilePath))
                throw new Exception("Path to the service account credentials file is required.");
            if (!File.Exists(serviceAccountCredentialFilePath))
                throw new Exception("The service account credentials file does not exist at: " + serviceAccountCredentialFilePath);
            if (string.IsNullOrEmpty(serviceAccountEmail))
                throw new Exception("ServiceAccountEmail is required.");

            // These are the scopes of permissions you need. It is best to request only what you need and not all of them
            string[] scopes = new string[] { AnalyticsReportingService.Scope.Analytics };             // View your Google Analytics data

            // For Json file
            if (Path.GetExtension(serviceAccountCredentialFilePath).ToLower() == ".json")
            {
                GoogleCredential credential;
                using (var stream = new FileStream(serviceAccountCredentialFilePath, FileMode.Open, FileAccess.Read))
                {
                    credential = GoogleCredential.FromStream(stream)
                         .CreateScoped(scopes);
                }

                // Create the  Analytics service.
                return new AnalyticsReportingService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "AnalyticsReporting Service account Authentication Sample",
                });
            }
            else if (Path.GetExtension(serviceAccountCredentialFilePath).ToLower() == ".p12")
            {   // If its a P12 file

                var certificate = new X509Certificate2(serviceAccountCredentialFilePath, "notasecret", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);
                var credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail)
                {
                    Scopes = scopes
                }.FromCertificate(certificate));

                // Create the  AnalyticsReporting service.
                return new AnalyticsReportingService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "AnalyticsReporting Authentication Sample",
                });
            }
            else
            {
                throw new Exception("Unsupported Service accounts credentials.");
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine("Create service account AnalyticsReportingService failed" + ex.Message);
            throw new Exception("CreateServiceAccountAnalyticsReportingFailed", ex);
        }
    }

如果这不是你可以做的事情。然后,您应该知道,即使存档中的filedatastore()将您的凭据存储在%appData%中,您只需将该文件与代码一起复制到新服务器上即可。

您还可以使用以下代码将位置移动到%appData%以外的其他位置:

new FileDataStore(@"c:\datastore",true)     

我有一个关于filedatastore如何工作的教程。这里File datastore demystified

将服务帐户预授权给Google Analytics。 Google Analytics(分析)网站的管理员部分。授予它读取权限应该足够了。

enter image description here