【问题标题】:How to access contacts API with Service Account如何使用服务帐户访问联系人 API
【发布时间】:2014-05-01 05:02:53
【问题描述】:

我正在升级我的 Marketplace 应用程序以支持新的 Marketplace api 和 OAUTH 2。

我已经成功迁移了大多数 API,但卡在了联系人 API 上。在之前的市场版本中,我们使用 2LO 和客户端密钥/客户端密钥在 Google Apps 域中进行身份验证。我的理解是,在当前版本中执行此操作的唯一方法是使用服务帐户和 OAuth 2。

基于 V3 日历 API,我假设是这样的(尽管联系人 API 不支持我所看到的) -

        ServiceAccountCredential credential = new ServiceAccountCredential(
           new ServiceAccountCredential.Initializer(serviceAccountEmail)
           {
               Scopes = new[] { "https://www.google.com/m8/feeds" },
               User = "admin@domain.co"
           }.FromCertificate(certificate));

        var service = new ContactsService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
            ApplicationName = "Contact API Sample",
        });

如果有人这样做,您的建议将不胜感激!

【问题讨论】:

    标签: google-contacts-api google-apps-marketplace service-accounts


    【解决方案1】:

    我知道这个问题已得到解答,但添加了一个不需要 AssertionFlowClient 或特定版本的 DotNetOpenAuth 的替代方案。这允许您使用与原始问题相同的 ServiceAccountCredential 代码(即,使用相同的方法查询用户的 gmail)

    感谢您跟进您自己的帖子,它帮助我找到了这个解决方案!

        private static ServiceAccountCredential GenerateCred(IEnumerable<string> scopes, string delegationUser)
        {
            var certificate = new X509Certificate2(certLocation, certPassword, X509KeyStorageFlags.Exportable);
            var credential = new ServiceAccountCredential(
                new ServiceAccountCredential.Initializer(serviceAccountEmail)
                {
                    Scopes = scopes,
                    User = delegationUser
                }.FromCertificate(certificate));
            return credential;
        }
    
            var credential = GenerateCred(new[] { "https://www.googleapis.com/auth/contacts.readonly" }, userToDelegate);
    
            //Get the token for this scope and user
            await credential.RequestAccessTokenAsync(new CancellationToken());
    
            //use the token to initalize the request
            var rs = new RequestSettings(projectName)
            {
                OAuth2Parameters = new OAuth2Parameters()
                {
                    AccessToken = credential.Token.AccessToken
                }
            };
    
            var request = new ContactsRequest(rs);
            Feed<Contact> f = request.GetContacts();
            foreach (var c in f.Entries)
            {
                //process each contact
            }
    

    【讨论】:

      【解决方案2】:

      嗯,我没有得到任何回应,所以我只能假设标准客户端库不支持这个。

      我根据以下帖子提出了一种解决方法,用于电子邮件访问。

      http://www.limilabs.com/blog/oauth2-gmail-imap-service-account

      您需要关注他的帖子并注意以下几点:

      • 这必须使用他指定的 DotNetOpenAuth 版本。最新版本将无法使用。
      • 您只需要他的 AssertionFlowClient 类,这些类可以添加到我在此处提供的以下代码中:

            X509Certificate2 certificate = new X509Certificate2(
                serviceAccountCertPath,
                serviceAccountCertPassword,
                X509KeyStorageFlags.Exportable);
        
            AuthorizationServerDescription server = new AuthorizationServerDescription
            {
                AuthorizationEndpoint = new Uri("https://accounts.google.com/o/oauth2/auth"),
                TokenEndpoint = new Uri("https://accounts.google.com/o/oauth2/token"),
                ProtocolVersion = ProtocolVersion.V20,
            };
        
            AssertionFlowClient provider = new AssertionFlowClient(server, certificate)
            {
                ServiceAccountId = serviceAccountEmail,
                Scope = string.Join(" ", new[] { "https://mail.google.com/", "https://www.google.com/m8/feeds/" }),
                ServiceAccountUser = userEmail,
            };
        
            IAuthorizationState grantedAccess = AssertionFlowClient.GetState(provider);
        
            RequestSettings rs = new RequestSettings("iLink");
            rs.OAuth2Parameters = new OAuth2Parameters();
            rs.OAuth2Parameters.AccessToken = grantedAccess.AccessToken;
            rs.OAuth2Parameters.RefreshToken = null;
            rs.OAuth2Parameters.ClientId = null;
            rs.OAuth2Parameters.ClientSecret = null;
            rs.OAuth2Parameters.RedirectUri = null;
        
            ContactsRequest cr = new ContactsRequest(rs);
            Feed<Contact> f = cr.GetContacts();
            foreach (var c in f.Entries)
            {   
                Response.Write(c.Name.FullName);
            }
        

      【讨论】:

        猜你喜欢
        • 2021-12-08
        • 2022-07-14
        • 2020-04-13
        • 2022-01-15
        • 1970-01-01
        • 1970-01-01
        • 2014-02-01
        • 2018-10-06
        • 2013-08-30
        相关资源
        最近更新 更多