使用Google+ for Domains API列出的圈子在access_denied中失败

时间:2013-11-09 12:48:37

标签: google-api google-plus google-apps

这是杀了我的!我正在尝试使用域范围委派列出我域中用户的Google Plus圈子。这应该是谷歌开发人员api的例子。

我在Google的云控制台中设置了一个应用程序,在那里启用了Google+ for Domains API并创建了服务器证书。

然后,我在Google Apps管理控制台中添加了范围。

我的代码:

package com.MYDOMAIN.plus;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.List;

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.services.plusDomains.PlusDomains;
import com.google.api.services.plusDomains.model.Circle;
import com.google.api.services.plusDomains.model.CircleFeed;

public class PlusHelper {

    // Fill in the following values based upon the previous steps
    private static final String SERVICE_ACCOUNT_EMAIL = "39578475189-vefb22ohjt9dahloahfsp9h9bol7r6ie@developer.gserviceaccount.com";
    private static final String SERVICE_ACCOUNT_PKCS12_FILE_PATH =
        "/Users/kees/Documents/workspace/MYDOMAINPlus/2a282bbacf8895b821e7cf662a98de4d65e38b2a-privatekey.p12";
    private static final String USER_EMAIL = "kees@MYDOMAIN.com";

    // List the scopes your app requires. These must match the scopes
    // registered in the Admin console for your Google Apps domain.
    private static final List<String> SCOPE = Arrays.asList(
                "https://www.googleapis.com/auth/plus.circles.read");

    private static PlusDomains authenticate(final String userEmail) throws GeneralSecurityException, IOException {
      System.out.println(String.format("Authenticate the domain for %s", userEmail));

      HttpTransport httpTransport = new NetHttpTransport();
      JsonFactory jsonFactory = new JacksonFactory();

      // Setting the sub field with USER_EMAIL allows you to make API calls using the special keyword
      // "me" in place of a user id for that user.
      GoogleCredential credential = new GoogleCredential.Builder()
          .setTransport(httpTransport)
          .setJsonFactory(jsonFactory)
          .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
          .setServiceAccountScopes(SCOPE)
          .setServiceAccountUser(USER_EMAIL)
          .setServiceAccountPrivateKeyFromP12File(
              new java.io.File(SERVICE_ACCOUNT_PKCS12_FILE_PATH))
          .build();

      // Create and return the authorized API client
      PlusDomains service = new PlusDomains.Builder(httpTransport, jsonFactory, credential).setApplicationName("PlusSync").build();
      return service;
    }

    public static void main(String[] args) {
            /** Global Drive API client. */
            PlusDomains plusDomains;
            try {
                plusDomains = PlusHelper.authenticate(USER_EMAIL);
                PlusDomains.Circles.List listCircles = plusDomains.circles().list(USER_EMAIL);
                listCircles.setMaxResults(5L);
                CircleFeed circleFeed = listCircles.execute();
                List<Circle> circles = circleFeed.getItems();

                // Loop until no additional pages of results are available.
                while (circles != null) {
                  for (Circle circle : circles) {
                    System.out.println(circle.getDisplayName());
                  }

                  // When the next page token is null, there are no additional pages of
                  // results. If this is the case, break.
                  if (circleFeed.getNextPageToken() != null) {
                    // Prepare the next page of results
                    listCircles.setPageToken(circleFeed.getNextPageToken());

                    // Execute and process the next page request
                    circleFeed = listCircles.execute();
                    circles = circleFeed.getItems();
                  } else {
                    circles = null;
                  }
                }
            } catch (GeneralSecurityException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }



    }
}

这会导致此错误:

com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
{
  "error" : "access_denied"
}
    at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:105)
    at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:332)
    at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:352)
    at com.google.api.client.googleapis.auth.oauth2.GoogleCredential.executeRefreshToken(GoogleCredential.java:269)
    at com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java:454)
    at com.google.api.client.auth.oauth2.Credential.intercept(Credential.java:215)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:854)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
    at com.MYDOMAIN.plus.PlusHelper.main(PlusHelper.java:60)

有没有人有任何想法?它杀了我,因为我之前在另一个域上工作了这个!

顺便说一下,我的代码和堆栈跟踪中的“MYDOMAIN”显然取代了实际的域名。

1 个答案:

答案 0 :(得分:1)

在太多摆弄之后找到了答案。似乎在新的云控制台中,证书的客户端ID与OAuth框中的客户端ID不同。我做了什么来解决这个问题:下载证书的JSON。此json包含client_id值,该值与云控制台中的客户端ID不同。使用管理API面板中JSON的客户端ID来授权范围,它将起作用!