I am trying to do an extract of users in my domain by accessing the Google Admin SDK API. I am however given a 401 unauthorized exception. The code below is my settings class that contains my method to call the 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;
}
}
The code below is my test case that i am using to pull users from my domain:
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(){ }
}
and Finally here is the exception that i am faced with.
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)
Any help would be gladly appreciated!!!
Based from this thread, TokenResponseException: 401 Unauthorized occurs when having an invalid client ID, client secret or scopes. But it could also be due to refresh token overuse. Refresh the access token, if necessary since it have limited lifetimes. If your application needs access to a Google API beyond the lifetime of a single access token, it can obtain a refresh token. A refresh token allows your application to obtain new access tokens.
Check these related threads:
- Java Google Contacts API Access Service Account Authentication which states that another possible source for a "401 Unauthorized" exception is leaving the
credential.refreshToken()
away. The call is necessary to write the access-code into the reference. - Always get TokenResponseException: 401 Unauthorized.
Hope this helps!
try deleting .credential directory - which is created in your local machine. this works.
来源:https://stackoverflow.com/questions/38834654/tokenresponseexception-401-unauthorized-exception-when-trying-to-access-admin-s