如何使用服务帐户访问联系人API

时间:2014-05-01 05:02:54

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

我正在升级我的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",
        });

如果有人这样做了,我们将非常感谢您的建议!

2 个答案:

答案 0 :(得分: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
        }

答案 1 :(得分:0)

我在这方面没有得到任何回复所以我只能假设标准客户端库不支持这个。

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

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);
        }