Google Apps Admin API: need to specify account use

2020-06-30 04:14发布

问题:

I'm creating a Marketplace App that should be able to read all the users of a domain. I request access to these scopes:

https://www.googleapis.com/auth/userinfo.email  
https://www.googleapis.com/auth/userinfo.profile    
https://www.googleapis.com/auth/admin.directory.user.readonly

Then when the 'Universal Navigation Extension' is accessed this happens:

Credential credential = new GoogleCredential.Builder()
        .setTransport(httpTransport)
        .setJsonFactory(jsonFactory)
        .setServiceAccountId(SERVICE_MAIL)
        .setServiceAccountScopes(Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_USER_READONLY))
        .setServiceAccountPrivateKey(privateKey)
        .build();

Directory oauth2 = new Directory.Builder(httpTransport, jsonFactory, null)
        .setHttpRequestInitializer(credential)
        .build();

Directory.Users.List list = oauth2.users().list();
list.setDomain(queryParams.getString("domain"));
Users users = list.execute();

When I run this it returns this error:

{
  "code" : 403,
  "errors" : [ {
    "domain" : "global",
    "message" : "Not Authorized to access this resource/api",
    "reason" : "forbidden"
  } ],
  "message" : "Not Authorized to access this resource/api"
}

But, when I add:

Credential credential = new GoogleCredential.Builder()
    .setServiceAccountUser("<admin-account>@<domain>")
    ...

It works!

But how do I know the admin's email address? Can I make it work without the email address?

回答1:

No. You must have and know the email address of an account allowed to do what your want (typically a superadmin).

I agree that it is quite absurd for some APIs to require this (Admin, Directory, etc.).



回答2:

We have exactly the same "trouble" when trying to determine if an user is domain admin or not. We use the same scopes as you do, similar code (in PHP) as yours:

$email = 'an_user_from_not_our_domain@domain.com';

$config = array(
    'key' => "path/to/private/key",
    'name' => "xxxxxxxxxxxxxxx@developer.gserviceaccount.com",
    'prn' => "app_domain_admin@app_domain.com"
);

$isAdmin = false;

$key     = file_get_contents($config['key']);
$scopes_ = array("https://www.googleapis.com/auth/admin.directory.user.readonly");
$gac     = new Google_AssertionCredentials($config['name'], $scopes_, $key, 'notasecret', 'http://oauth.net/grant_type/jwt/1.0/bearer', $config['prn']);

$client = new Google_Client();
$client->setApplicationName("Test App");
$client->setUseObjects(true);
$client->setAssertionCredentials($gac);

require_once 'GoogleApiClient/contrib/Google_DirectoryService.php';
$directory = new Google_DirectoryService($client);
$user = $directory->users->get($email);

if ($user instanceof Google_User)
    $isAdmin = $user->getIsAdmin();

When we install the app for our own domain only - we can get "isAdmin" value. And when we install the app into other domains it does not work and returns the same "Not Authorized to access this resource/api".

Maybe it's for what Directory API is designed for? I mean, for working with our own domain and not with domains that install our app. Deprecated Provisioning API was allowing to fetch such info. And now we could not determine whether an user is domain administrator or not.



回答3:

Since a few days ago, Google now allows any user to list users in a domain (also including subdomains).

http://googleappsupdates.blogspot.se/2014/09/new-features-in-admin-sdk-custom-user.html

However, this has two limitations which mean that this is not something I can benefit from for my particular use case.

  1. You still need a (active) username to make a request, and how are you going to get that username if you can't list the users? I might have a username from the signup, but that account may be deleted at any time. Still catch 22.

  2. If you are using a non-admin account, you are forced to set viewType to "domain_public", which means you will only be able to see a subset of the available fields. The "suspended" field is not one of them, and you also won't get any suspended users in the response. (documentation available here: https://developers.google.com/admin-sdk/directory/v1/reference/users/list)

I could live with the "suspended" limitation, but since I can't get a list of users without already having a user, this is not helping me.