无法使用 Google Directory API Admin SDK 列出用户

Posted

技术标签:

【中文标题】无法使用 Google Directory API Admin SDK 列出用户【英文标题】:Can't list users with Google Directory API Admin SDK 【发布时间】:2013-06-06 16:22:12 【问题描述】:

我正在尝试使用 AdminService 来管理我的域的用户和组,但我遇到了一个简单的请求来获取我域的所有用户。 C#中有代码:

public Users GetAllUsers()

    var provider = new AssertionFlowClient(
        GoogleAuthenticationServer.Description,
        new X509Certificate2(privateKeyPath, keyPassword, X509KeyStorageFlags.Exportable))
    
        ServiceAccountId = serviceAccountEmail,
        Scope = AdminService.Scopes.AdminDirectoryUser.GetStringValue()
    ;

    var auth = new OAuth2Authenticator<AssertionFlowClient>(provider, AssertionFlowClient.GetState);

    m_serviceGroup = new AdminService(new BaseClientService.Initializer()
    
        Authenticator = auth,
    );

    var request = m_serviceUser.Users.List();
    request.Domain = m_domainName;
    return request.Fetch();

当 Fetch() 说:

Code: 403    
Message: Not Authorized to access this resource/api 
Error: Message[Not Authorized to access this resource/api] Location[ - ] Reason[forbidden] Domain[global]

我已按照here 的说明启用了 API 访问,并在域控制面板中授权了我的服务帐户:

[Security]->[Advanced Setting]->[Authentication]->[Manage third party OAuth Client access]

范围:

https://www.googleapis.com/auth/admin.directory.group 
https://www.googleapis.com/auth/admin.directory.user

API 控制面板中也启用了 Admin SDK Service。

我尝试了使用DriveService的代码并成功列出/创建/删除文件没有任何问题,因此代码的身份验证部分应该没问题。我不知道还需要配置什么,或者我的代码是否还有其他问题。

感谢您的帮助。

【问题讨论】:

【参考方案1】:

为我工作。

using Google.Apis.Auth.OAuth2;
using Google.Apis.Admin.Directory.directory_v1;
using Google.Apis.Admin.Directory.directory_v1.Data;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;


namespace ConsoleApplication1




    class Program
    
        static string[] Scopes =  DirectoryService.Scope.AdminDirectoryUserReadonly;
        static string ApplicationName = "API G Suite implementation guid by amit";

        static void Main(string[] args)
        
            UserCredential credential;

            using (var stream =
                new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
            
                string credPath = System.Environment.GetFolderPath(
                    System.Environment.SpecialFolder.Personal);
                credPath = Path.Combine(credPath, ".credentials1/admin-directory_v1-dotnet-quickstart.json");

                credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.Load(stream).Secrets,
                    Scopes,
                    "user",
                    CancellationToken.None,
                    new FileDataStore(credPath, true)).Result;
                Console.WriteLine("Credential file saved to: " + credPath);
            

            // Create Directory API service.
            var service = new DirectoryService(new BaseClientService.Initializer()
            
                HttpClientInitializer = credential,
                ApplicationName = ApplicationName,
            );

            ////// Define parameters of request.
            UsersResource.ListRequest request = service.Users.List();
            request.Customer = "my_customer";
            request.MaxResults = 10;
            request.OrderBy = UsersResource.ListRequest.OrderByEnum.Email;

            ////// List users.
            IList<User> users = request.Execute().UsersValue;
            Console.WriteLine("Users:");
            if (users != null && users.Count > 0)
            
               foreach (var userItem in users)
              
                   Console.WriteLine("0 (1)", userItem.PrimaryEmail,
                       userItem.Name.FullName);
               
            
            else
            
               Console.WriteLine("No users found.");
            
            Console.Read();


        
    

【讨论】:

【参考方案2】:

如页面所述:

管理 API 客户端访问

开发者可以向 Google 注册他们的网络应用程序和其他 API 客户端,以便访问 Google 服务(如日历)中的数据。您可以授权这些 注册客户访问您的用户数据无需您的用户单独同意或提供他们的密码。了解更多

服务帐户需要根据用户的行为进行操作,因此在初始化客户端时需要分配 ServiceAccountUser。

    var provider = new AssertionFlowClient(
        GoogleAuthenticationServer.Description,
        new X509Certificate2(privateKeyPath, keyPassword, X509KeyStorageFlags.Exportable))
        
            ServiceAccountId = serviceAccountEmail,
            Scope = AdminService.Scopes.AdminDirectoryUser.GetStringValue(),
            ServiceAccountUser = domainManangerEmail
        ;

编辑:不推荐使用 AssertionFlowClient,以下应该可以工作:

var cert = new X509Certificate2(privateKeyPath, keyPassword, X509KeyStorageFlags.Exportable);
var serverCredential = new ServiceAccountCredential(
    new ServiceAccountCredential.Initializer(serviceAccountEmail)
        
            Scopes = new []DirectoryService.Scope.AdminDirectoryUser,
            User = domainManagerAccountEmail
        .FromCertificate(cert));
var dirService = new DirectoryService(new BaseClientService.Initializer()
        
            HttpClientInitializer = serverCredential
        );

【讨论】:

这对我不起作用,当我添加 ServiceAccountUser(他是域超级用户)时,它会出错:协议异常:发送直接消息或获取响应时发生错误。底层 oauth 响应是: 1f "error" : "access_denied" 0 找到我的答案... 2LO 是必需的。 developers.google.com/drive/… 我疯了吗? AssertionFlowClient 未安装在我能找到的任何 nuget 安装的谷歌 API 中。 我完全按照上面的方法做了,但是得到了Error:"unauthorized_client", Description:"Unauthorized client or scope in request.", Uri:"" ......任何想法 @Ody,您是否启用了 API 访问权限并授予您正在使用的帐户的权限?【参考方案3】:

这段代码对我有用


static void GettingUsers()
 
  String serviceAccountEmail = "xxxxxxx@developer.gserviceaccount.com";
  var certificate = new X509Certificate2(@"xxxxx.p12", "notasecret", X509KeyStorageFlags.Exportable);
  ServiceAccountCredential credential = new ServiceAccountCredential(
  new ServiceAccountCredential.Initializer(serviceAccountEmail)
  
  Scopes = new[]  DirectoryService.Scope.AdminDirectoryUser,
  User = "your USER",  
  .FromCertificate(certificate));
  var service = new DirectoryService(new BaseClientService.Initializer()
  
  HttpClientInitializer = credential,
  ApplicationName = "name of your app",
  );

  var listReq = service.Users.List();
  listReq.Domain = "your domain";
  Users allUsers = listReq.Execute();
  int counter = 0;
  foreach(User myUser in allUsers.UsersValue)
    Console.WriteLine("*" + myUser.PrimaryEmail);
     counter++;


Console.WriteLine(counter);
Console.ReadKey();

欲了解更多信息,请查看Directory API: Users list。 有限制和配额。

【讨论】:

【参考方案4】:

我们需要提供我们正在使用超级管理员或正确权限的服务 ID 才能通过此错误。

希望这会有所帮助。 -Venu Murthy

【讨论】:

以上是关于无法使用 Google Directory API Admin SDK 列出用户的主要内容,如果未能解决你的问题,请参考以下文章

周末 Google Directory API 发生了啥变化/中断?

Google_Service_Directory - (403) 无权访问此资源/api

使用 Google Directory API 未找到组织单元

尝试使用 Google Directory API 和服务帐户身份验证时收到错误“未授权访问此资源/api”

NodeJS:无法使用服务帐户访问 Gmail API

是否可以仅使用字符串中的 api 键从 Directory API 获取用户列表?