2

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

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

4

2 回答 2

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
        }
于 2015-05-07T17:13:04.390 回答
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);
        }
    
于 2014-05-06T03:38:40.703 回答