C# 调用日历API时出错:主体必须是电子邮件地址

C# 调用日历API时出错:主体必须是电子邮件地址,c#,google-calendar-api,C#,Google Calendar Api,我们在一年多前编写了一个软件,用于同步谷歌日历上的事件。它从2018年3月开始工作,但本月它突然停止在我们和客户使用的每个Gsuite实例上工作 问题是,我们使用服务帐户通过google CalendarAPI v3访问日历资源事件。 使用服务帐户凭据进行身份验证后,对于每个服务调用,我们现在都会遇到以下错误: 错误:\“无效的\u请求\”,说明:\“主体必须是电子邮件地址\”,Uri:\“\” 我在任何地方都找不到关于这个问题的答案,这听起来像是谷歌服务的政策改变,但我不能确定这一点。 谷歌A

我们在一年多前编写了一个软件,用于同步谷歌日历上的事件。它从2018年3月开始工作,但本月它突然停止在我们和客户使用的每个Gsuite实例上工作

问题是,我们使用服务帐户通过google CalendarAPI v3访问日历资源事件。 使用服务帐户凭据进行身份验证后,对于每个服务调用,我们现在都会遇到以下错误:

错误:\“无效的\u请求\”,说明:\“主体必须是电子邮件地址\”,Uri:\“\”

我在任何地方都找不到关于这个问题的答案,这听起来像是谷歌服务的政策改变,但我不能确定这一点。 谷歌API似乎在抱怨服务帐户电子邮件,这实际上不是一封真正有效的电子邮件。其格式如下:

mydomain.com(客户id)313...@resource.calendar.google.com

您认为问题是否与服务帐户电子邮件地址有关? 为什么它在四月份之前就开始工作,现在却停止工作了

一种可能的解决方案尚未尝试:

我知道可以对服务帐户使用“委托”。 如果我尝试使用有效的用户电子邮件并将其委托给我的服务帐户,会发生什么情况

/* function I use to authenticate my service account to Google Calendar
* service. serviceAccount is the email (Principal not working?) and json is 
* the key generated for him.
*/
public void bindCalendarService(string json, string serviceAccount)
    {
        var cr = Newtonsoft.Json.JsonConvert.DeserializeObject<PersonalServiceAccountCred>(json);
        ServiceAccountCredential xCred = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(cr.client_id, cr.token_uri)
        {
            Scopes = new string[] {
                CalendarService.Scope.Calendar,
            },
            User = serviceAccount
        }.FromPrivateKey(cr.private_key));

        CalendarService calendarService = new CalendarService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = xCred
        });
        this.calendarService = calendarService;
    }
/*用于向谷歌日历验证我的服务帐户的函数
*服务。serviceAccount是电子邮件(主体不工作?),json是
*为他生成的密钥。
*/
public void bindCalendarService(字符串json、字符串serviceAccount)
{
var cr=Newtonsoft.Json.JsonConvert.DeserializeObject(Json);
ServiceAccountCredential xCred=新ServiceAccountCredential(新ServiceAccountCredential.Initializer(cr.client\u id,cr.token\u uri)
{
作用域=新字符串[]{
CalendarService.Scope.Calendar,
},
用户=服务帐户
}.FromPrivateKey(cr.private_key));
CalendarService CalendarService=新的CalendarService(新的BaseClientService.Initializer()
{
HttpClientInitializer=xCred
});
this.calendarService=calendarService;
}

您需要在google帐户安全上授予对不安全应用的访问权限, 试试这个:
如果它不起作用,请与我联系。

您需要在google帐户安全上授予对不安全应用的访问权限, 试试这个:
如果它不起作用,请和我谈谈。

我今天用另一种方法解决了这个问题

1) 我试图执行授权,就像上面解释的那样: 它起作用了

2) 在没有授权的情况下,我通过以下方式更改了我的方法:

var credentialParameters=NewtonsoftJsonSerializer.Instance.Deserialize(json)

它甚至以这种方式工作。 为什么上面的代码在1年后停止工作仍然是一个谜

希望它能帮助别人
谢谢

我今天用另一种方法解决了这个问题

1) 我试图执行授权,就像上面解释的那样: 它起作用了

2) 在没有授权的情况下,我通过以下方式更改了我的方法:

var credentialParameters=NewtonsoftJsonSerializer.Instance.Deserialize(json)

它甚至以这种方式工作。 为什么上面的代码在1年后停止工作仍然是一个谜

希望它能帮助别人 谢谢

        ServiceAccountCredential xCred = new ServiceAccountCredential(
            new ServiceAccountCredential.Initializer(**credentialParameters.ClientEmail**)
            {
                Scopes = new string[] {
                    CalendarService.Scope.Calendar
                },
                User = serviceAccount,         // service account's email
            }.FromPrivateKey(credentialParameters.PrivateKey));