谷歌坐标OAuth2与服务帐户

本文关键字:服务 坐标 OAuth2 谷歌 | 更新日期: 2023-09-27 18:19:00

我有一个c#控制台应用程序与谷歌坐标。net库和服务帐户开放认证。

private const string SERVICE_ACCOUNT_EMAIL = "XXX@developer.gserviceaccount.com";
private const string SERVICE_ACCOUNT_PKCS12_FILE_PATH = @"<path-to-private-key-file>'YYY-privatekey.p12";
private const string GOOGLE_COORDINATE_TEAM_ID = "ZZZ";
private CoordinateService BuildService()
{
    X509Certificate2 certificate = new X509Certificate2(SERVICE_ACCOUNT_PKCS12_FILE_PATH, "notasecret", X509KeyStorageFlags.Exportable);
    var provider = new AssertionFlowClient(GoogleAuthenticationServer.Description, certificate){
        ServiceAccountId = SERVICE_ACCOUNT_EMAIL,
        Scope = CoordinateService.Scopes.Coordinate.GetStringValue()
    };
    var auth = new OAuth2Authenticator<AssertionFlowClient>(provider, AssertionFlowClient.GetState);
    return new CoordinateService(new BaseClientService.Initializer(){
        Authenticator = auth
    });
}
//some code that retrieves data from coordinate service
public void DoSomething()
{
    CoordinateService service = BuildService();
    var response = service.Jobs.List(GOOGLE_COORDINATE_TEAM_ID).Fetch();
    ...
}

在从坐标服务检索作业列表时,出现DotNetOpenAuth.Messaging.ProtocolException(内部异常"远程服务器返回一个错误:(400)Bad Request")。使用小提琴手,我设法看到谷歌OAuth服务的响应。JSON响应对象:

{
  "error" : "invalid_grant"
}

我读过一些文章,建议改变本地服务器时间,以匹配谷歌誓言服务器时间。但在改变时间到一边和另一边后,问题仍然是一样的。你能告诉我为什么会这样吗?感谢所有的回复!

谷歌坐标OAuth2与服务帐户

服务帐户不能与Coordinate API一起使用。[这是因为Coordinate API要求经过身份验证的API用户拥有Coordinate许可证,但不可能将Coordinate许可证附加到服务帐户]

您可以使用web服务器流程,请参见下面的示例。

确保更新下面的代码,其中有包含" to update "的注释。

using System; 
using System.Diagnostics; 
using System.Collections.Generic; 
using DotNetOpenAuth.OAuth2; 
using Google.Apis.Authentication.OAuth2; 
using Google.Apis.Authentication.OAuth2.DotNetOpenAuth; 
using Google.Apis.Coordinate.v1; 
using Google.Apis.Coordinate.v1.Data;
namespace Google.Apis.Samples.CoordinateOAuth2
{ 
    /// <summary> 
    /// This sample demonstrates the simplest use case for an OAuth2 service. 
    /// The schema provided here can be applied to every request requiring authentication. 
    /// </summary> 
    public class ProgramWebServer
    { 
        public static void Main (string[] args)
        { 
            // TO UPDATE, can be found in the Coordinate application URL
            String TEAM_ID = "jskdQ--xKjFiFqLO-IpIlg"; 
            // Register the authenticator. 
            var provider = new WebServerClient (GoogleAuthenticationServer.Description);
            // TO UPDATE, can be found in the APIs Console.
            provider.ClientIdentifier = "335858260352.apps.googleusercontent.com";
            // TO UPDATE, can be found in the APIs Console.
            provider.ClientSecret = "yAMx-sR[truncated]fX9ghtPRI"; 
            var auth = new OAuth2Authenticator<WebServerClient> (provider, GetAuthorization); 
            // Create the service. 
            var service = new CoordinateService(new BaseClientService.Initializer()
                       {
                          Authenticator = auth
                       });
            //Create a Job Resource for optional parameters https://developers.google.com/coordinate/v1/jobs#resource 
            Job jobBody = new Job (); 
            jobBody.Kind = "Coordinate#job"; 
            jobBody.State = new JobState (); 
            jobBody.State.Kind = "coordinate#jobState"; 
            jobBody.State.Assignee = "user@example.com"; 

            //Create the Job 
            JobsResource.InsertRequest ins = service.Jobs.Insert (jobBody, TEAM_ID, "My Home", "51", "0", "Created this Job with the .Net Client Library");
            Job results = ins.Fetch (); 
            //Display the response 
            Console.WriteLine ("Job ID:"); 
            Console.WriteLine (results.Id.ToString ()); 
            Console.WriteLine ("Press any Key to Continue"); 
            Console.ReadKey (); 
        }
        private static IAuthorizationState GetAuthorization (WebServerClient client)
        { 
            IAuthorizationState state = new AuthorizationState (new[] { "https://www.googleapis.com/auth/coordinate" }); 
            // The refresh token has already been retrieved offline
            // In a real-world application, this has to be stored securely, since this token
            // gives access to all user data on the Coordinate scope, for the user who accepted the OAuth2 flow
            // TO UPDATE (see below the sample for instructions)
            state.RefreshToken = "1/0KuRg-fh9yO[truncated]yNVQcXcVYlfXg";
            return state;
        } 
    } 
}

刷新令牌可以通过使用OAuth2 Playground来检索:

  • 在api控制台中,添加OAuth Playground URL https://developers.google.com/oauthplayground作为已授权的类中检索刷新令牌时将需要它(auth Playground,下图)
  • 进入OAuth Playground,在浏览器会话中,您的API用户已经过身份验证(此用户需要具有Coordinate许可证)。确保提供您拥有OAuth2客户端ID(设置>使用您自己的OAuth凭据)。否则,您的刷新令牌将绑定到OAuth2游乐场内部OAuth2客户端ID,当您想要使用时将被拒绝使用您自己的客户端id来刷新令牌,以获得访问令牌。
  • 使用范围https://www.googleapis.com/auth/coordinate在步骤1中,点击"授权API"在步骤2中,点击"Exchange Authorization codes"令牌"
  • 在代码中复制刷新令牌。确保安全。
  • 这个刷新令牌不会过期,所以你的应用将保持身份验证。