【问题标题】:How to retrieve Google group membership with a service account?如何使用服务帐户检索 Google 群组成员资格?
【发布时间】:2021-10-09 22:49:19
【问题描述】:

我正在尝试使用服务帐户在后台进程中检索/更新 Google 群组成员资格,但在执行查询时出现此错误。如何将这些权限添加到服务帐号?

Google.GoogleApiException: 'Google.Apis.Requests.RequestError
Not Authorized to access this resource/api [403]
Errors [
    Message[Not Authorized to access this resource/api] Location[ - ] Reason[forbidden] Domain[global]
]
'

C#代码:

using FileStream fileStream = File.OpenRead(@"key.json");
GoogleCredential googleCredential = GoogleCredential.FromStream(fileStream)
    .CreateScoped("https://www.googleapis.com/auth/admin.directory.group.member");
BaseClientService.Initializer initializer = new()
{
    HttpClientInitializer = googleCredential,
    ApplicationName = "My App",
};
DirectoryService service = new(initializer);
MembersResource.ListRequest listRequest = service.Members.List("my-group@example.com");
Members members = await listRequest.ExecuteAsync();

【问题讨论】:

    标签: c# google-admin-sdk service-accounts google-directory-api


    【解决方案1】:

    谢谢,我已经更改了这些行,现在可以使用了!

    GoogleCredential googleCredential = GoogleCredential.FromStream(fileStream)
        .CreateScoped("https://www.googleapis.com/auth/admin.directory.group.member")
        .CreateWithUser("my-user@example.com");
    

    【讨论】:

      【解决方案2】:

      您似乎必须使用setServiceAccountUser,这在基于 JSON 的凭据中不受支持。你可以这样构建它:

      import static com.google.api.client.googleapis.util.Utils.getDefaultJsonFactory;
      import static com.google.api.client.googleapis.util.Utils.getDefaultTransport;
      
      private static final String APPLICATION_NAME = "AnyAppName";
      
      private final List<String> SCOPES = ImmutableList.of(
              DirectoryScopes.ADMIN_DIRECTORY_GROUP_MEMBER, DirectoryScopes.ADMIN_DIRECTORY_USER, DirectoryScopes.ADMIN_DIRECTORY_GROUP);
      
      private Directory service;
      
      @PostConstruct
      void init() throws GeneralSecurityException, IOException {
          GoogleCredential credential;
          try (InputStream is = new FileInputStream("./config/client_secret.json")) {
              credential = GoogleCredential.fromStream(is);
          }
          GoogleCredential credentialWithUser = new GoogleCredential.Builder()
                  .setTransport(getDefaultTransport())
                  .setJsonFactory(getDefaultJsonFactory())
                  .setServiceAccountUser("admin@yourdomain.ru")  // <--- mail of domain's admin
                  .setServiceAccountId(credential.getServiceAccountId())
                  .setServiceAccountScopes(SCOPES)
                  .setServiceAccountPrivateKey(credential.getServiceAccountPrivateKey())
                  .setServiceAccountPrivateKeyId(credential.getServiceAccountPrivateKeyId())
                  .setTokenServerEncodedUrl(credential.getTokenServerEncodedUrl()).build();
      
          service = new Directory.Builder(getDefaultTransport(), getDefaultJsonFactory(), credentialWithUser).setApplicationName(APPLICATION_NAME).build();
      }
      
      public void members() throws IOException {
         Members members = service.members().list("groupName@yourdomain.ru").execute();
         System.out.println(members);
      }
      

      参考:

      【讨论】: