Google Calendar API。向某人的日历添加事件会引发错误“错误401:invalid_client”;就在验证时 [英] Google Calendar API. Adding an event to someone calendar throws error "Error 401: invalid_client" just when authenticating

查看:89
本文介绍了Google Calendar API。向某人的日历添加事件会引发错误“错误401:invalid_client”;就在验证时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个C#类库,试图通过使用他/她的电子邮件地址和密码作为凭据将事件添加到某人的日历中。因此,我对其进行了调试,一旦启动,便会在Internet浏览器中打开一个新页面,并显示以下错误:





以下代码:

  //在调用GoogleWebAuthorizationBroker时崩溃。 AuthorizeAsync 
UserCredential凭据= GoogleWebAuthorizationBroker.AuthorizeAsync(
新ClientSecrets
{
ClientId = myGoogleAccount@gmail.com,
ClientSecret = myGoogleAccountPasswordHere,
},
new [] {CalendarService.Scope.Calendar},
System.Environment.UserName,
CancellationToken.None).Result;

//创建服务。
var service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer =凭据,
ApplicationName = Calendar API Sample,
});

为什么会发生此错误? ClientId不是Gmail帐户吗?
为什么还要在Internet浏览器中打开一个新页面?我想在不通过Internet浏览器打开页面的情况下进行身份验证,因为此类类库是从Windows服务调用的,因此我需要在后台进行身份验证。

解决方案

答案:


要将方法插入用户的日历中,您需要用户授予您的应用程序权限才能代表他们执行操作。这是通过带有OAuth2身份验证的Google Cloud Platform(GCP)项目完成的。


更多信息:


每个运行的应用程序并代表Google帐户采取措施用户必须明确定义其权限范围,以使其无法开始执行用户未授予其权限的操作。


例如:如果您授予应用程序创建日历事件的权限,则您不希望它能够执行其他操作,例如阅读电子邮件或下载云端硬盘的内容。


要指定您的应用有权执行的操作,需要向Google注册。正如您已经推断出的问题和评论一样,连接到G Suite API的应用程序所需的客户端ID和客户端密钥不仅是Google帐户的用户名和密码,还包括一个指定的ID-秘密ID对,


OAuth2:


OAuth2是一个特定的授权框架。该框架在


设置OAuth同意屏幕时,您需要提供以下信息:



  • 应用程序类型(公共或内部域) )

  • 应用程序名称

  • 应用程序所需的范围(在下一节中说明)


设置同意屏幕后,您可以下载应用程序的客户端凭据。有了这些,您的应用程序就具有以客户端身份运行的权限,但是访问其资源的每个用户仍必须授予其显式权限,以允许该应用程序这样做。


范围:


在单个API中,可以有许多访问范围-对日历事件具有只读访问权限与对用户拥有的所有日历具有完全读写访问权限大不相同。范围在这里发挥作用。


范围被定义为其同名。也就是说,范围定义了应用程序对服务的访问范围。即使已为项目启用了整个API,也并不意味着您需要使用API​​的所有功能。因此,需要定义范围。


在对用户授予初始请求之前,应在应用程序中定义范围。例如,在C#中(摘自 .NET日历API快速入门):

 //范围定义为字符串数组:
静态字符串[]范围= {CalendarService.Scope.CalendarReadonly};
...
UserCredential凭证;
凭据= GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream)。秘密,
范围,
用户,
CancellationToken.None,
新的FileDataStore(credPath,true))。Result;

存储的访问令牌基于调用中定义的范围。如果调用的方法与令牌授予访问权限的方法的作用域不同,则调用将失败,并显示 403:Unauthorized 错误。所需的范围将需要添加到应用程序中,删除旧的访问令牌,并且用户将需要授予新范围的权限。


服务帐户:


除普通用户外,还有另一种特殊的Google帐户,称为服务帐户。从文档中:


服务帐户是一种特殊的帐户,由应用程序或虚拟机(VM)实例而非个人使用。应用程序使用服务帐户来进行授权的API调用。


通常,您希望为其执行任务或访问资源的每个用户都需要为您的用户提供明确的权限申请这样做。但是,对于G Suite域,您可以将服务帐户用于域-

服务帐户使用一种特殊的服务帐户凭据,该凭据可以在GCP中创建并在您的应用程序中使用。无需创建 UserCredential 对象,而是需要一个 ServiceAccountCredential ,该不需要最终用户参与。


何时在具有域范围委派的用户的名义上运行服务帐户时,需要在委派的凭据中指定该用户的名称,以便应用程序知道要以哪个用户身份运行域中的用户。如果未提供用户,则服务帐户将自己运行代码;


注意:在服务期间,这在某些情况下很有用,但通常不会返回错误,因此可能不清楚为谁运行操作。可以由任何人创建帐户,只能对G Suite域完成域范围的授权,而不能对 @ gmail.com 地址进行授权。所有Gmail帐户用户 必须 都明确授予应用程序代表其运行的权限,如OAuth流程所述。


I希望对您有帮助!


参考文献:





相关问题:



I have a C# class library from which I am trying to add an event to someone calendar just by using his/her email address and password as credentials. So I debug it and once started a new page in the internet browser is open and below error is displayed:

Below the code:

// It crashes when calling GoogleWebAuthorizationBroker.AuthorizeAsync
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                new ClientSecrets
                {
                    ClientId = "myGoogleAccount@gmail.com",
                    ClientSecret = "myGoogleAccountPasswordHere",
                },
                new[] { CalendarService.Scope.Calendar },
                System.Environment.UserName,
                CancellationToken.None).Result;

   // Create the service.
   var service = new CalendarService(new BaseClientService.Initializer()
   {
                HttpClientInitializer = credential,
                ApplicationName = "Calendar API Sample",
   });

Why this error is happening? ClientId is not the gmail account? Also why a new page in internet browser is opened? I want to do authentication without opening a page in the internet browser because this class library is called from a windows service so I need authentication to be done in the background.

解决方案

Answer:

In order to insert methods into a user's Calendar, you need the user to give your application permission to make actions on their behalf. This is done using a Google Cloud Platform (GCP) Project, with OAuth2 Authentication.

More Information:

Each application which runs and takes actions on behalf of a Google account user has to have the scope of its ability well defined so that it can't start doing things that a user hasn't given it permission to do.

For example: if you give an application permission to create Calendar events, you don't want it to be able to do other things such as read your emails or download the contents of your Drive.

In order to designate what your application has the power to do, it needs to be registered with Google. As you have already deduced in your question and comments, the Client ID and Client Secret required by an application connecting to a G Suite API isn't simply the username and password of a Google Account, but a designated ID-secret ID pair which is provided by Google to identify your application.

OAuth2:

OAuth2 is a specific authorisation framework. The framework is defined in RFC 6749 and sets out the process in which a user can authorise an application to access their account. The limit of the authorisation is defined by the scope of the application on authorisation, and can not be changed without explicit re-authorisation by the user.

Before continuing it's worth defining a few important terms here:

User:

A user is the person; the individual that has an account and gives permission for an application to take actions on their behalf.

Client or Application:

A Client or Application is a program which is designed to take actions over HTTP by connecting to a service's API. Applications can be mobile apps, web apps or desktop clients.

Authorisation Server:

An Authorisation server is a server which is separate from the servers that store user resources. It verfies the user's identity and provides a grant which can be used to get an access token to a resource server.

Resource Server:

This is the server where user data is stored. This could be anything from user information to files or emails.

The authorisation flow has already been well documented, but for the sake of this scenario we can abstract it down to the following steps:

  • An Application wishes to take an action on a resource server on behalf of a user.
  • The Application makes an authorisation request to the user. This is generally presented as a login page for the account for which the application is accessing.
  • The user logs in to their account and is presented with an OAuth consent screen - this contains information such as the application's name, and the list of tasks that it is requesting authorisation for. These are often generic, and will say something like See and download all your Google Drive files or View and edit events on all your calendars. This allows the user to know what they are authorising before they confirm.
  • An Authorisation Grant is given to the application.
  • The Application provides the obtained authorisation grant along with its assigned client credentials to an authorisation server.
  • On verifying that both the user's grant and the client's credentials are correct, the authorisation server returns an access token which can be used to access the requested and approved resources. Note: This is normally all handled by your client library for whichever language you use.
  • The Application can now make a request to the resource server, providing the access token obtained from the authorisation flow. It is at this point that the permitted resources can be accessed.

Google Cloud Platform Projects:

A GCP project what Google sees as your application. The registration for your application is required to be able to obtain the client ID and client secret which your application will need in order to get an access token in the authorisation flow. In the GCP console you can set up all the required services that your application needs. Each API you wish to use has to be enabled for your application, as there are many Google services with APIs and they are disabled by default.

Once a GCP Project has been created, you can use the API Library (From the ≡ > APIs & Services > Library menu item on the left) to find and enable the API. Note that for your use case you will want to enable the Google Calendar API and not the CalDAV API.

You will also need to set up a consent screen before obtaining credentials for your application. An OAuth consent screen is what your users will be presented with in the first step of the OAuth flow:

When setting up your OAuth consent screen, you will need to provide the following information:

  • Application type (public or internal to your domain)
  • Application name
  • The scopes that your application needs (explained in the next section)

After the consent screen has been set up, you can download the client credentials for your application. With these, your application has permission to run as a client, but each user that has their resources accessed will still have to give their explicit permission to allow the application to do so.

Scopes:

Within a single API there can be many scopes of access - having read-only access to calendar events is vastly different to having complete read-write access to all calendars that a user owns. This is where scopes come into play.

A scope is defined as its namesake; that is to say, a scope defines the scope of access an application has to a service. Even though an entire API has been enabled for a project doesn't mean that you need to use all features of the API. For this reason, scopes need to be defined.

Scopes are defined in the application itself before making the initial request for the user grant. In C#, for example (taken from the .NET Calendar API Quickstart):

// scopes are defined as an array of strings:
static string[] Scopes = { CalendarService.Scope.CalendarReadonly };
...
UserCredential credential;
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.Load(stream).Secrets,
                    Scopes,
                    "user",
                    CancellationToken.None,
                    new FileDataStore(credPath, true)).Result;

The access token that is stored is based on the scopes that were defined in the call. If a method is called which needs a different scope to those which the token grants access to, the call will fail with a 403: Unauthorized error. The required scope will need to be added to the application, the old access token deleted and the user will need to grant permission for the new scopes.

Service Accounts:

As well as regular users, there is another special type of Google account called a Service Account. From the documentation:

A service account is a special kind of account used by an application or a virtual machine (VM) instance, not a person. Applications use service accounts to make authorized API calls.

Normally, every user for whom you wish to perform tasks or access resources needs to give explicit permission for your application to do so. For G Suite domains, however, you can use a service account with domain-wide delegation to complete tasks on behalf of users without the requirement.

Service accounts use a special kind of service-account credential which can be created in GCP and used in your application. Rather than making a UserCredential object, a ServiceAccountCredential is needed which doesn't require involvment by an end user.

When running a service account on behalf of a user with domain-wide delegation, the name of the user needs to be specified in the delegated credentials so the application knows which user in the domain to run as. If a user is not provided, the service account will run the code as itself; which is useful in some cases but often times will not return an error and so it may not be clear for whom the operation was run.

Note: While Service Accounts can be created by anyone, domain-wide delegation of authority can only be accomplished for a G Suite domain, and not @gmail.com addresses. All Gmail account users must give explicit permission for an application to run on thier behalf as set out by the OAuth flow.

I hope this is helpful to you!

References:


Related Questions:

这篇关于Google Calendar API。向某人的日历添加事件会引发错误“错误401:invalid_client”;就在验证时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆