2013-06-18 101 views
1

我有一個C#控制檯應用程序,其中Google Coordinate .Net library和服務帳戶開放式身份驗證。Google協調帶服務帳戶的OAuth2

private const string SERVICE_ACCOUNT_EMAIL = "[email protected]"; 
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)錯誤的請求」)。使用Fiddler我設法看到Google OAuth服務的響應。 JSON響應對象:

{ 
    "error" : "invalid_grant" 
} 

我看了一些文章,建議爲了配合谷歌誓言服務器時更改本地服務器時間。但在改變時間到另一側後,問題仍然是一樣的。 你能給我一些想法,爲什麼發生這種情況? 感謝您的回覆!

回答

1

服務帳戶不能與座標API一起使用。 [這是因爲協調API需要經過認證的API用戶擁有協調許可,但無法將協調許可附加到服務帳戶]

您可以使用Web服務器流程代替,請在下面找到示例。

請務必更新下面的代碼,其中有包含「更新」的註釋。

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 = "[email protected]"; 


      //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遊樂場檢索:

  • API控制檯,添加OAuth園地網址,https://developers.google.com/oauthplayground,爲授權 重定向URI(我們需要的是當我們檢索了 OAuth園地刷新令牌,下同)
  • 轉到OAuth的遊樂場,在具有身份驗證您的API的用戶瀏覽器會話(該用戶需要有一個協調中心許可)。 確保爲您提供自己的OAuth2用戶端ID(設置>使用您自己的OAuth認證) 。 否則,您刷新令牌將被捆綁到了OAuth2操場的 內部OAuth2用戶端ID,當你想使用 與自己的客戶端ID的刷新令牌來獲得訪問令牌將被拒絕。
  • 使用範圍https://www.googleapis.com/auth/coordinate在步驟1中,命中 「授權的API」在第2步,點擊「兌換授權碼 爲令牌」
  • 拷貝到您的代碼中的刷新令牌。保持安全。
  • 該刷新令牌不會過期,因此您的應用程序將保持認證。
+0

非常感謝您的回覆!我試圖找出一些信息約半個星期。也許您可以以某種方式將您的答案添加到Google API協調文檔中。這非常有用! –

+0

您可以指定如何在新的Google.Apis庫中實現它。 –

相關問題