gpt4 book ai didi

.net - 如何使用服务帐户向Google v3 api进行身份验证

转载 作者:行者123 更新时间:2023-12-04 04:30:50 25 4
gpt4 key购买 nike

我在这里遵循了示例代码:
https://code.google.com/p/google-api-dotnet-client/wiki/OAuth2#Service_Accounts

授权失败:
DotNetOpenAuth.Messaging.ProtocolException:发送直接消息或获取响应时发生错误。

内部异常是System.Net.WebException:远程服务器返回错误:(400)错误的请求。响应主体为空,响应URI为https://accounts.google.com/o/oauth2/token

在下面的响应中,您将看到特定的错误是invalid_grant。

这是我的代码:

var certificate = new X509Certificate2(CertificatePath, "notasecret", X509KeyStorageFlags.Exportable);
var provider = new AssertionFlowClient(GoogleAuthenticationServer.Description, certificate)
{
ServiceAccountId = "<...>@developer.gserviceaccount.com",
Scope = CalendarService.Scopes.Calendar.GetStringValue()
};

var authenticator = new OAuth2Authenticator<AssertionFlowClient>(provider, AssertionFlowClient.GetState);

var calendarService =
new CalendarService(new BaseClientService.Initializer()
{
Authenticator = authenticator
});

var eventList = calendarService.Events.List("<id of the calendar>").Execute();

证书和ServiceAccountId是正确的。我已三重检查,并已采取很好的措施重新生成了证书。在用于创建服务帐户的google开发人员帐户的API控制台中,已打开Goog​​le Calendar API。此帐户不属于Google Apps域。

我还使用指定的AssertionFlowClient的ServiceAccountUser属性对此进行了测试。我现在认为这是必需的-在通过手动创建的JWT对CalendarService进行的成功测试中(请参见下面的OAuth token 的手动创建),尝试在不包含prn属性的情况下创建 token 时收到404错误。 claim (即不包括ServiceAccountUser)。

Google Apps域配置

在Google Apps域中,我已授予对该服务帐户的日历的访问权限。

客户名称:[snip] .apps.googleusercontent.com

API范围:
  • 日历(读/写)https://www.google.com/calendar/feeds/
  • 日历(读写)https://www.googleapis.com/auth/calendar

  • 已安装NuGet软件包
  • Google.Apis(1.5.0-beta)
  • Google.Apis.Calendar.v3(1.5.0.59-beta)
  • Google.Apis.Authentication(1.5.0-beta)

  • 请求和响应
    POST https://accounts.google.com/o/oauth2/token HTTP/1.1
    Content-Type: application/x-www-form-urlencoded; charset=utf-8
    User-Agent: DotNetOpenAuth/4.0.0.11165
    Host: accounts.google.com
    Cache-Control: no-store,no-cache
    Pragma: no-cache
    Content-Length: 606
    Connection: Keep-Alive

    grant_type=assertion&assertion_type=http%3A%2F%2Foauth.net%2Fgrant_type%2Fjwt%2F1.0%2Fbearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI5NzUzOTk3NzMyNi01NHFvMXY4OW5iZTk4dGNlbGIycWY0cDdjNThzYjhmMkBkZXZlbG9wZXIuZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNjb3BlIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vYXV0aC9jYWxlbmRhciIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTM3OTU5MTA4MywiaWF0IjoxMzc5NTg3NDgzfQ.Ls_sv40MfB8MAD92JFcFiW5YYoRytQ3e2PA8RV_hn4FJfVHDo6uCSunN7950H2boO6LfX9EMrpjaf8ZyNyHyrQucQaWwfIFD6F2FpnqlcNkzXoqWMCwkt-k-8ypGMSZfFCEkhw8QOrlIPFZb6qx61689n08G9tZMTzHGYc2b8Gk

    经过仔细检查,该断言似乎正确,在此处进行解码:
    {"alg":"RS256","typ":"JWT"}{"iss":"97539977326-54qo1v89nbe98tcelb2qf4p7c58sb8f2@developer.gserviceaccount.com","scope":"https://www.googleapis.com/auth/calendar","aud":"https://accounts.google.com/o/oauth2/token","exp":1379591083,"iat":1379587483}
    HTTP/1.1 400 Bad Request
    Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    Pragma: no-cache
    Expires: Fri, 01 Jan 1990 00:00:00 GMT
    Date: Thu, 19 Sep 2013 10:44:42 GMT
    Content-Type: application/json
    X-Content-Type-Options: nosniff
    X-Frame-Options: SAMEORIGIN
    X-XSS-Protection: 1; mode=block
    Server: GSE
    Alternate-Protocol: 443:quic
    Content-Length: 31

    {
    "error" : "invalid_grant"
    }

    手动创建OAuth token 作品

    为了确认我的设置是否正确,我使用google-oauth-jwt(此处为 https://github.com/extrabacon/google-oauth-jwt)手动创建了 token 。我能够使用与上面的代码相同的属性成功创建 token 。创建 token 并将其用于自定义IAuthenticator后,我就可以从目标Google Apps域中用户的日历中成功检索事件。因此,如果您想知道,可以使用服务帐户访问 日历!

    这是IAuthenticator实现,它仅添加了Authorization header :
    public class Authenticator : IAuthenticator
    {
    public void ApplyAuthenticationToRequest(System.Net.HttpWebRequest request)
    {
    request.Headers.Add(HttpRequestHeader.Authorization, "Bearer <token here>");
    }
    }

    最佳答案

    自询问此问题以来,我不确定是否有所更改,但Google日历实际上确实支持服务帐户。

    设置与Google Calendar API一起使用的服务帐户时,您只需要获取服务帐户的电子邮件地址。转到Google日历网站。找到“日历设置”,然后转到“日历”选项卡,找到要访问的日历,然后单击“共享:编辑设置”,就像添加个人电子邮件地址一样添加服务帐户电子邮件地址。这将使该服务帐户具有与您与任何其他用户共享该帐户相同的访问权限。

    string[] scopes = new string[] {
    CalendarService.Scope.Calendar, // Manage your calendars
    CalendarService.Scope.CalendarReadonly // View your Calendars
    };

    var certificate = new X509Certificate2(keyFilePath, "notasecret", X509KeyStorageFlags.Exportable);

    ServiceAccountCredential credential = new ServiceAccountCredential(
    new ServiceAccountCredential.Initializer(serviceAccountEmail) {
    Scopes = scopes
    }.FromCertificate(certificate));

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

    Google Calendar API Authentication C#抓取的代码

    关于.net - 如何使用服务帐户向Google v3 api进行身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18869304/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com