使用Google日历API库在.NET 7 C#中使用凭据模拟用户创建Google日历事件。

huangapple go评论57阅读模式
英文:

Create Google Calendar Event With Credentials To Impersonate User with Google Calendar API Library .NET 7 C#

问题

在.NET 7中,如果在ServiceAccountCredential.Initializer(original.Id)块中未指定用户,我的日历事件可以创建而不会出现错误。但如果我像下面所示指定了用户,我会收到以下错误:

> 错误:unauthorized_client,
> 描述:客户端未经授权使用此方法检索访问令牌,或客户端未被授权获取任何请求的范围。

我的服务帐户具有域范围的委托,通过OAuth2允许的日历范围,并且我已特别授予了SA对用户日历的访问权限(当我尝试对未明确授予访问权限的帐户进行操作时,根本无法创建日历条目)。

如何获取服务帐户模拟域内终端用户所需的适当凭据?

将此进展归功于creating-a-serviceaccountcredential-for-a-user-from-a-systems-account

以前的答案似乎不适用于最新版本。

在我的API代码中,调用身份验证服务然后创建事件:

Google.Apis.Calendar.v3.CalendarService CS = await SA.AuthenticateServiceAccountSO();

var result = CS.Events.Insert((Event)newEvent, clientemail).Execute();

Service AuthenticateServiceAccountSO()中:

public async Task<CalendarService> AuthenticateServiceAccountSO()
{
    await Task.Delay(1);
    string? serviceAccountCredentialFilePath = _config.GetValue<string>("ServiceAccountFilePath");
    string? ClientEmail = _config.GetValue<string>("TestingUserAccountEmail");
    
    string[] scopes = new string[] { CalendarService.Scope.Calendar };
    
    ServiceAccountCredential original = (ServiceAccountCredential)GoogleCredential.FromFile(serviceAccountCredentialFilePath).UnderlyingCredential;
    
    var initializer = new ServiceAccountCredential.Initializer(original.Id)
                          {
                              User = ClientEmail,
                              Key = original.Key,
                              Scopes = scopes
                          };
    
    var credential = new ServiceAccountCredential(initializer);
    
    CalendarService service = new(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "Calendar_Appointment event Using Service Account Authentication"
                });
    
    return service;
}
英文:

In .NET 7, without specifying a User in the

ServiceAccountCredential.Initializer(original.Id)

block, my calendar event can be created with no errors. But if I specify a user as shown below, I get this error:

> Error: unauthorized_client,
> Description: Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested.

My service account has domain-wide delegation, allowed scope of
calendar via OAuth2, and I have specifically granted the SA access to the user's calendar (when I try on accounts that have not specifically granted access, I can't create a calendar entry at all).

How do I get appropriate credentials for the service account to impersonate the end user within my domain?

Credit for getting this far to creating-a-serviceaccountcredential-for-a-user-from-a-systems-account

Previous answers don't seem to be working on latest release.

In my API code, which calls the authentication service then creates the event:

Google.Apis.Calendar.v3.CalendarService CS = await SA.AuthenticateServiceAccountSO();

var result = CS.Events.Insert((Event)newEvent, clientemail).Execute();

In Service AuthenticateServiceAccountSO():

public async Task&lt;CalendarService&gt; AuthenticateServiceAccountSO()
{
    await Task.Delay(1);
    string? serviceAccountCredentialFilePath = _config.GetValue&lt;string&gt;(&quot;ServiceAccountFilePath&quot;);
    string? ClientEmail = _config.GetValue&lt;string&gt;(&quot;TestingUserAccountEmail&quot;);
    
    string[] scopes = new string[] { CalendarService.Scope.Calendar };
    
    ServiceAccountCredential original = (ServiceAccountCredential)GoogleCredential.FromFile(serviceAccountCredentialFilePath).UnderlyingCredential;
    
    var initializer = new ServiceAccountCredential.Initializer(original.Id)
                          {
                              User = ClientEmail,
                              Key = original.Key,
                              Scopes = scopes
                          };
    
    var credential = new ServiceAccountCredential(initializer);
    
    CalendarService service = new(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = &quot;Calendar_Appointment event Using Service Account Authentication&quot;
                });
    
    return service;
}

答案1

得分: 1

你目前只复制了服务帐号凭据的一小部分 - 特别是没有 KeyId。但无论如何,你可以更简单地完成所有操作:

var credential = GoogleCredential.FromFile(serviceAccountCredentialFilePath)
    .CreateScoped(CalendarService.Scope.Calendar)
    .CreateWithUser(ClientEmail);
英文:

You're currently copying relatively little of the service account credential - in particular, there's no KeyId. But you can do it all much more simply anyway:

var credential = GoogleCredential.FromFile(serviceAccountCredentialFilePath)
    .CreateScoped(CalendarService.Scope.Calendar)
    .CreateWithUser(ClientEmail);

huangapple
  • 本文由 发表于 2023年2月19日 01:12:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/75494993.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定