How can I impersonate a user of AppEngine java application operating in G-Suite domain?

点点圈 提交于 2021-02-07 12:12:55

问题


My standard AppEngine application needs to perform changes in a Google Sheet documents (among others).

To achieve this, I need to obtain a credential for service account, and somehow configure that it should act in behalf of a user.

This method allows gives me default service account credentials:

private static GoogleCredential getDefaultServiceAccountCredential() throws IOException {
    return GoogleCredential.getApplicationDefault()
        .createScoped(MY_SCOPES);
}

but it does not work in behalf of a user.

Following code is similar, uses other (non-default) service account, but still no impersonation happens:

private static GoogleCredential getNonDefaultServiceAccountCredential() throws IOException {
    return GoogleCredential.fromStream(IncomingMailHandlerServlet.class.getResourceAsStream("/tokens/anoher-e6351a8c5b91.json"))
        .createScoped(MY_SCOPES);
}

For impersonation, Google Docs (and many SO advices) mentions how to do it with use of PKCS12 file; however, that file can only be read as PrivateKey on installed application and not on AppEngine.

Is there any way to obtain impersonated credential for java application running in AppEngine? Or, is there a trick to read from a File on AppEngine?

Note that, for all service accounts that I tried, I configured them with role Owner and with DwD (Domain-wide delegation). Is there anything else to configure?


回答1:


The GoogleCredential reference offers a sample to

also use the service account flow to impersonate a user in a domain that you own. This is very similar to the service account flow above, but you additionally call GoogleCredential.Builder.setServiceAccountUser(String)

 public static GoogleCredential createCredentialForServiceAccountImpersonateUser(
      HttpTransport transport,
      JsonFactory jsonFactory,
      String serviceAccountId,
      Collection<String> serviceAccountScopes,
      File p12File,
      String serviceAccountUser) throws GeneralSecurityException, IOException {
    return new GoogleCredential.Builder().setTransport(transport)
        .setJsonFactory(jsonFactory)
        .setServiceAccountId(serviceAccountId)
        .setServiceAccountScopes(serviceAccountScopes)
        .setServiceAccountPrivateKeyFromP12File(p12File)
        .setServiceAccountUser(serviceAccountUser)
        .build();
  }

There are multiple options on how to access a file from App Engine Standard. Below, you have two options explained:


Option 1: the p12File (credentials file) is an App Engine Standard resource file. Check this answer to see how to access such files, code-wise. I strongly recommend this approach because

These files are only available to your code on a read-only basis and not for traffic serving.

File f = new File("path/below/my/project/directory/credentials.json");

and the appengine-web.xml should define the resource files:

<resource-files>
  <include path="path/below/my/project/directory/credentials.json"/>
</resource-files>


Option 2: the credentials file is in Cloud Storage. This document explains how to reach files in Cloud Storage from App Engine Standard. But I believe it's too much of a hassle. I provided this option as well because I have mentioned it.

来源:https://stackoverflow.com/questions/49341317/how-can-i-impersonate-a-user-of-appengine-java-application-operating-in-g-suite

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!