使用服务帐户身份验证访问 Google Calendar API

Posted

技术标签:

【中文标题】使用服务帐户身份验证访问 Google Calendar API【英文标题】:Access Google Calendar API using Service Account Authentication 【发布时间】:2017-03-01 20:08:20 【问题描述】:

我能够使用.NET Quickstart 教程访问 Google 日历 API,效果很好!

该教程的问题在于它使用了Open Authentication or OAuth2。我想使用Service Account Authentication 来做同样的事情。

(https://support.google.com/googleapi/answer/6158857?hl=en)

谁能举例说明如何使用服务帐户密钥文件访问我的日历?

我也尝试过使用Google Calendar API Authentication with C# 教程,但无法完成。

【问题讨论】:

【参考方案1】:

我很好奇为什么您第一次尝试使用服务帐户教程没有成功。哪里错了?有错误吗?

记住服务帐户不是你。该服务帐户有其自己的 Google 日历帐户,因此如果您尝试阅读您的“个人日历”之一,它将无法正常工作。您将不得不与服务帐户共享您的个人日历。

这是另一个使用Json service account key file 的示例。

string[] scopes = new string[]  CalendarService.Scope.Calendar ;
GoogleCredential credential;
using (var stream = new FileStream(serviceAccountCredentialFilePath, FileMode.Open, FileAccess.Read))

    credential = GoogleCredential.FromStream(stream)
                     .CreateScoped(scopes);


// Create the Calendar service.
var service = new CalendarService(new BaseClientService.Initializer()

    HttpClientInitializer = credential,
    ApplicationName = "Calendar Authentication Sample",
);

【讨论】:

这(和你的博客文章)对我有很大帮助。最后让我的应用程序使用服务帐户向 Google Calendar API 进行身份验证。谢谢! 嗨。有关如何“...与服务帐户共享您的个人日历”的任何提示。我很难把这个放在一起。请指教 获取服务帐户电子邮件地址并与它共享您的日历,就像您共享任何其他用户一样。做的时候记下日历ID。它现在将获得预先批准 是的。我正在这样做。我去了我的日历,“添加朋友的日历”并输入了服务电子邮件。然后我得到这个错误:无法添加日历“mobile-armour-test-key@mobilearmourtest.iam.gserviceaccount.com”您无权访问mobile-armour-test-key@mobilearmourtest.iam.gserviceaccount.com的日历跨度> 基本上,我添加了一个新项目,启用了日历 API,然后添加了一个“服务帐户”凭据。然后我将其配置为具有“域范围的委派”。我尝试了 .json 和 .p12 方式与 api 交互。代码没有错误,但“我的日历”中没有任何内容。【参考方案2】:

试试这个。第一个 Create a service account 可以在您的 Google 开发控制台中找到。

有关实施的参考,请在此处查看DalmTo's blogpost 了解如何使用服务帐户。

这是一个sn-p:

var certificate = new X509Certificate2(keyFile, "notasecret", X509KeyStorageFlags.Exportable);
try
   ServiceAccountCredential credential = new ServiceAccountCredential(
      new ServiceAccountCredential.Initializer(serviceAccountEmail)
      
          Scopes = scopes
      .FromCertificate(certificate));

   //Create the service.
   DriveService service = new DriveService(new BaseClientService.Initializer()
   
      HttpClientInitializer = credential,
      ApplicationName = "Drive API Sample"
   );
   return service;

catch (Exception ex)

    Console.WriteLine(ex.InnerException);
    return null;

【讨论】:

【参考方案3】:

对于任何想解决这个问题但需要NodeJS 解决方案的人,您可以通过以下方式登录使用具有域范围委派权限的服务帐户作为特定用户

const auth = new google.auth.JWT(    // use JWT instead of GoogleAuth 
    subject: "me@mycompany.com",      // specify subject (user whose context you want to operate in)
    keyFile: "service-account-key.json",
    scopes: [
        "https://www.googleapis.com/auth/calendar.events",
        "https://www.googleapis.com/auth/calendar.readonly"
    ],
)

【讨论】:

【参考方案4】:

访问此链接有完整的工作项目谷歌服务帐户身份验证与谷歌日历事件插入方法你必须更改你的 json 私钥和你的凭据只有 https://github.com/CodeForget/Google-Service-Account-Authentication

here json key file othentication as well p12 authentication both

ServiceAccountAuthentication.cs

using Google.Apis.Calendar.v3;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using Google.Apis.Calendar.v3.Data;

namespace GoogleSamplecSharpSample.Calendarv3.Auth




    public static class ServiceAccountExample
    

        /// <summary>
        /// Authenticating to Google calender using a Service account
        /// Documentation: https://developers.google.com/accounts/docs/OAuth2#serviceaccount
        /// </summary>
        /// Both param pass from webform1.aspx page on page load
        /// <param name="serviceAccountEmail">From Google Developer console https://console.developers.google.com/projectselector/iam-admin/serviceaccounts </param>
        /// <param name="serviceAccountCredentialFilePath">Location of the .p12 or Json Service account key file downloaded from Google Developer console https://console.developers.google.com/projectselector/iam-admin/serviceaccounts </param>
        /// <returns>AnalyticsService used to make requests against the Analytics API</returns>

        public static CalendarService AuthenticateServiceAccount(string serviceAccountEmail, string serviceAccountCredentialFilePath, string[] scopes)
        
            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.");

                // For Json file
                if (Path.GetExtension(serviceAccountCredentialFilePath).ToLower() == ".json")
                
                    GoogleCredential credential;
                    //using(FileStream stream = File.Open(serviceAccountCredentialFilePath, FileMode.Open, FileAccess.Read, FileShare.None))


                    using (var stream = new FileStream(serviceAccountCredentialFilePath, FileMode.Open, FileAccess.Read))
                    
                        credential = GoogleCredential.FromStream(stream)
                             .CreateScoped(scopes).CreateWithUser("xyz@gmail.com");//put a email address from which you want to send calendar its like (calendar by xyz user )
                    

                    // Create the  Calendar service.
                    return new CalendarService(new BaseClientService.Initializer()
                    
                        HttpClientInitializer = credential,
                        ApplicationName = "Calendar_Appointment event Using Service Account Authentication",
                    );
                
                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  Calendar service.
                    return new CalendarService(new BaseClientService.Initializer()
                    
                        HttpClientInitializer = credential,
                        ApplicationName = "Calendar_Appointment event Using Service Account Authentication",

                    );
                
                else
                
                    throw new Exception("Something Wrong With Service accounts credentials.");
                

            
            catch (Exception ex)
                            
                throw new Exception("Create_Service_Account_Calendar_Failed", ex);
            
        


    

添加 webform.aspx 并将此代码放在 webform.aspx.cs

using System;
using Google.Apis.Calendar.v3;
using GoogleSamplecSharpSample.Calendarv3.Auth;
using Google.Apis.Calendar.v3.Data;

namespace CalendarServerToServerApi

    public partial class WebForm1 : System.Web.UI.Page
    
        // create event which you want to set using service account authentication 
        Event myEvent = new Event
        
            Summary = "Visa Counselling",
            Location = "Gurgaon sector 57",
            Start = new EventDateTime()
            
                DateTime = new DateTime(2017, 10, 4, 2, 0, 0),
                TimeZone = "(GMT+05:30) India Standard Time"
            ,
            End = new EventDateTime()
            
                DateTime = new DateTime(2017, 10, 4, 2, 30, 0),
                TimeZone = "(GMT+05:30) India Standard Time"
            
            //,
            // Recurrence = new String[] 
            //"RRULE:FREQ=WEEKLY;BYDAY=MO"
            //
            //,
            // Attendees = new List<EventAttendee>()
            // 
            // new EventAttendee()  Email = "Srivastava998@gmail.com" 
            //
        ;

        protected void Page_Load(object sender, EventArgs e)
        

        


        public void Authenticate(object o, EventArgs e)
        
            string[] scopes = new string[] 
     CalendarService.Scope.Calendar //, // Manage your calendars
    //CalendarService.Scope.CalendarReadonly // View your Calendars
 ;
            string cal_user = "calenderID@gamil.com"; //your CalendarID On which you want to put events
            //you get your calender id "https://calendar.google.com/calendar"
            //go to setting >>calenders tab >> select calendar >>Under calender Detailes at Calendar Address:

            string filePath = Server.MapPath("~/Key/key.json");
            var service = ServiceAccountExample.AuthenticateServiceAccount("xyz@projectName.iam.gserviceaccount.com", filePath, scopes);
            //"xyz@projectName.iam.gserviceaccount.com" this is your service account email id replace with your service account emailID you got it .
            //when you create service account https://console.developers.google.com/projectselector/iam-admin/serviceaccounts

            insert(service, cal_user, myEvent);

        



        public static Event insert(CalendarService service, string id, Event myEvent)
        
            try
            
                return service.Events.Insert(myEvent, id).Execute();

            
            catch (Exception ex)
            
                Console.WriteLine(ex.Message);
                return null;
            
        


    

【讨论】:

您知道如何在普通的 HTTP 身份验证或日历 API 调用中实现用户上下文 .CreateWithUser("xyz@gmail.com") 吗? (或在 NodeJS 库中)

以上是关于使用服务帐户身份验证访问 Google Calendar API的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Google Apps 脚本中使用服务帐户对 Google 表格进行身份验证

PHP Google 服务帐户身份验证日历 API

使用 Json 文件进行 Google 服务帐户身份验证

使用 Google Apps 帐户登录时,在 Android 上对 Google Play 游戏服务进行身份验证会导致错误

在 Chrome 扩展程序中使用 Google 帐户进行服务器端身份验证

Google Home 授权代码和使用 Google 帐户进行身份验证