TokenResponseException:尝试访问Admin SDK Google API时出现401 Unauthorized Exception。

时间:2016-08-08 16:51:46

标签: java google-api google-admin-sdk

我正在尝试通过访问Google Admin SDK API对我的域中的用户进行提取。然而,我获得了401未经授权的例外。下面的代码是我的设置类,其中包含调用API的方法。

 package com.brookfieldres.operations;

   import java.io.File;
   import java.io.IOException;
   import java.security.GeneralSecurityException;
   import java.util.ArrayList;
   import java.util.ResourceBundle;

   import org.apache.log4j.Logger;

   import com.brookfieldres.common.Constants;
   import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
   import com.google.api.client.googleapis.auth.oauth2.GoogleCredential.Builder;
   import com.google.api.services.admin.directory.Directory;
   import com.google.api.services.admin.directory.DirectoryScopes;

    public class GCAuthentication {

        private static final Logger _Log =      Logger.getLogger(GCAuthentication.class.getName()); 

    static ResourceBundle resources =  ResourceBundle.getBundle("Resources"); 

//  public static String serviceAcc = resources.getString("SERVICE_ACC_EMAIL"); 
//  public static String privKeyPath = resources.getString("PRIVATE_KEY_PATH"); 
//  public static String userEmail = resources.getString("ADMIN_ACC"); 



    public static Directory getDirectoryService(String serviceAcc, String privKeyPath, String userEmail) throws IOException, GeneralSecurityException, NullPointerException {

    //  final ArrayList<String> dirScopes = new ArrayList<String>(); 
    //      dirScopes.add(DirectoryScopes.ADMIN_DIRECTORY_USER); 


        Constants.dirScopes = new ArrayList<String>(); 
        Constants.dirScopes.add(DirectoryScopes.ADMIN_DIRECTORY_USER); 
        Constants.dirScopes.add(DirectoryScopes.ADMIN_DIRECTORY_CUSTOMER); 
        Constants.dirScopes.add(DirectoryScopes.ADMIN_DIRECTORY_ORGUNIT);

        GoogleCredential gCreds = new GoogleCredential.Builder()
        .setJsonFactory(Constants.JSON_FACTORY)
        .setTransport(Constants.HTTP_TRANSPORT)
        .setServiceAccountId(serviceAcc)
        .setServiceAccountUser(userEmail)
        .setServiceAccountPrivateKeyFromP12File(new File(privKeyPath))
        .setServiceAccountScopes(Constants.dirScopes)
        .build(); 

        Directory directory = new Directory.Builder(Constants.HTTP_TRANSPORT, Constants.JSON_FACTORY, gCreds).setApplicationName(Constants.APPLICATION_NAME).build(); 

        return directory; 

    }


}

下面的代码是我用来从我的域中提取用户的测试用例:

package com.brookfieldres.library.test;

import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertFalse;

import java.io.IOException;
import java.security.GeneralSecurityException;
import org.junit.After;

import com.brookfieldres.operations.GCAuthentication;
import com.google.api.client.repackaged.com.google.common.base.Strings;
import com.google.api.services.admin.directory.Directory;
import com.google.api.services.admin.directory.model.Customer;
import com.google.api.services.admin.directory.model.User;

public class ExtractionTest { 

@Before 
    public void setUp(){}

@Test
    public void getEmails() throws IOException, NullPointerException, GeneralSecurityException{ 

        try {

            Directory directory = GCAuthentication.getDirectoryService("XXXXXXX", "XXXXXXXX", "XXXXXXX"); 
            System.out.println("The connection to Google is established"); 
            User user1 = directory.users().get("XXXXXXXX@XXXX.ca").execute(); 
            System.out.println("User is pulled."); 

    //      assertFalse(user1 == null); 

    //      if(user1 != null){ 
    //          System.out.println("Name= " + user1.getName());
    //      }

        }catch(NullPointerException e) { 
            e.printStackTrace();
        }catch (IOException e){ 
            e.printStackTrace();
        }catch (GeneralSecurityException e) { 
            e.printStackTrace();
        }


    }

@After
    public void tearDown(){ }

}

最后这是我面临的例外。

The connection to Google is established
com.google.api.client.auth.oauth2.TokenResponseException: 401 Unauthorized
    at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:105)
    at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:287)
    at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:307)
    at com.google.api.client.googleapis.auth.oauth2.GoogleCredential.executeRefreshToken(GoogleCredential.java:384)
    at com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java:489)
    at com.google.api.client.auth.oauth2.Credential.intercept(Credential.java:217)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:868)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
    at com.brookfieldres.library.test.ExtractionTest.getEmails(ExtractionTest.java:36)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

任何帮助都会很高兴!!!

4 个答案:

答案 0 :(得分:3)

基于此thread TokenResponseException:401 Unauthorized 在拥有无效的客户端ID,客户端密码或范围时发生。但也可能是因为刷新令牌过度使用。 Refresh the access token,如果有必要,因为它的寿命有限。如果您的应用需要在单个访问令牌的生命周期之后访问Google API,则可以获取刷新令牌。刷新令牌允许您的应用程序获取新的访问令牌。

检查这些相关的主题:

希望这有帮助!

答案 1 :(得分:0)

尝试删除.credential目录-在本地计算机上创建的目录。这行得通。

答案 2 :(得分:0)

在我的 Intellij IDE 中,它兑现了证书文件,这就是问题所在。因此,如果您要更改Google帐户和凭据文件,还必须删除兑现的凭据。它位于项目目录中的 token / StoredCredential

TokenResponseException: 401 Unauthorized Exception when trying to access Admin SDK Google API.

答案 3 :(得分:0)

在尝试通过服务帐户使用Admin SDK Google API时遇到了同样的问题。

对我来说,这是发生问题的原因,因为我在代码中设置的范围与在我的Google管理控制台中“安全性>高级设置>管理API客户端访问”下设置的范围不匹配。一旦将它们对齐,它们就会开始完美工作。

您还需要为服务帐户启用“域范围委派”吗? (可以通过here完成)