【问题标题】:GoogleCredential created by json private key file (ServiceAccount) - how to set the User to impersonate?由 json 私钥文件(ServiceAccount)创建的 GoogleCredential - 如何将用户设置为模拟?
【发布时间】:2016-07-21 06:49:29
【问题描述】:

刚开始使用 Google API。 在我的 Google Cloud Platform 帐户中,我为域范围的委派创建了一个服务帐户。我为此服务帐户保存了一个 json 格式的私钥文件。

在我的测试应用程序中,我正在创建一个 GoogleCredential 实例:

var credential = 
            GoogleCredential.FromStream(new FileStream("privatekey.json", FileMode.Open, FileAccess.Read))
            .CreateScoped(Scopes);

如何设置我想模拟的用户? 使用 p12 私钥时,我可以执行以下操作:

var credential = new ServiceAccountCredential(
    new ServiceAccountCredential.Initializer("xxx@developer.gserviceaccount.com") //service Account id
    {
       Scopes = Scopes,
       User = "admin@xxx.com" //the user to be impersonated                    
    }.FromCertificate(new X509Certificate2(@"xxx.p12", "notasecret", X509KeyStorageFlags.Exportable)));

但是我如何使用 GoogleCredential 和 json privatkey 文件来“简单”地做到这一点?

亲切的问候

【问题讨论】:

    标签: c# .net google-api google-api-dotnet-client


    【解决方案1】:

    好的,我现在通过从 GoogleCredential 和内部类 DefaultCredentialProvider 内部复制代码解决了这个问题

    using (var fs = new FileStream("key.json", FileMode.Open, FileAccess.Read))
    {
        var credentialParameters =
            NewtonsoftJsonSerializer.Instance.Deserialize<JsonCredentialParameters>(fs);
        if (credentialParameters.Type != "service_account" 
            || string.IsNullOrEmpty(credentialParameters.ClientEmail) 
            || string.IsNullOrEmpty(credentialParameters.PrivateKey))
                throw new InvalidOperationException("JSON data does not represent a valid service account credential.");
        return new ServiceAccountCredential(
            new ServiceAccountCredential.Initializer(credentialParameters.ClientEmail)
            {
                Scopes = Scopes,
                User = _adminUser //the user to be impersonated
            }.FromPrivateKey(credentialParameters.PrivateKey));
    }
    

    如果有人(可能是peleyal)有更好的主意,可以直接通过 GoogleCredential 进行操作,请随时给我一个提示;)

    【讨论】:

    • 谢谢。我想,你只是让我少了 4 个小时的头痛!
    【解决方案2】:

    下面的Javascript,但你可以在#C 中做类似的事情,我敢肯定。

    我使用 client_id 和 client_secret 方法

    function tokenRefresh(){
    
      var uri = "https://accounts.google.com/o/oauth2/token";
    
      var payload =
          {
            'client_id' : 'XXXXXXXX.apps.googleusercontent.com',
            'client_secret' : 'XXXXXXXX',
            'grant_type' : 'refresh_token',
            'content_type' : 'application/x-www-form-urlencoded',
            'refresh_token' : 'XXXXXXXX'
          };
    
      var options = 
          { "method" : "POST",
           "muteHttpExceptions" : false,
           "payload" : payload
          };
    
      var response = UrlFetchApp.fetch(uri, options),
          response_json = JSON.parse(response.getContentText()),
          token = response_json.access_token;
      return(token);
    }
    

    假设您拥有正确的范围权限,这每次都会给您一个新令牌。

    每次您想要访问 API 时都需要附加 access_key(而不是某些 Google 文档中指出的“key=”)

    有关如何获取范围的更多信息,请随时查看我写的内容:http://thisistony.com/blog/googleanalytics/google-analytics-api-oauth-ever-wondered-how-to-get-the-access_token/

    【讨论】:

    • 但我正在尝试使用.net wrapper api。我试图避免直接休息电话。
    【解决方案3】:

    这是一个更简单的方法

    var sac = ServiceAccountCredential.FromServiceAccountData(new FileStream("key.json", FileMode.Open));

    【讨论】:

    • 是的,问题是如何设置要模拟的用户。无论如何,自从 .net 库的 1.28 版以来,这现在是可能的。 var bytes = Encoding.UTF8.GetBytes(_srvAccJson); using (var stream = new MemoryStream(bytes)) { return GoogleCredential.FromStream(stream) .CreateScoped(scopes) .CreateWithUser(userEmail); }
    猜你喜欢
    • 2018-05-26
    • 2015-11-08
    • 1970-01-01
    • 2017-12-12
    • 2022-08-05
    • 1970-01-01
    • 2013-06-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多