AdminSettings API с использованием служебной учетной записи в консольном приложении C#
Я пытаюсь использовать API настроек администратора Google с учетной записью службы безуспешно из консольного приложения C#.
Из того, что я понял, я сначала должен получить токен OAuth. Для этого я успешно опробовал 2 метода: используя Google.Apis.Auth.OAuth2.ServiceAccountCredentials или создав вручную утверждение JWT.
Но когда я вызываю API настроек администратора с токеном OAuth (например, MaximumNumberOfUsers), я всегда получаю сообщение об ошибке 403 с сообщением "Вы не авторизованы для выполнения операций над доменом xxx".
Я загрузил GAM, так как автор также называет этот API, чтобы я мог составлять те же HTTP-запросы. Как объяснено в GAM wiki, я выполнил все шаги, чтобы создать новую учетную запись службы и новый идентификатор клиента OAuth, чтобы быть уверенным, что это не проблема области. Я также активировал режим отладки, как предложено Джей Ли в этой теме. Как объяснено в комментариях к ветке, он все еще не работает с моим токеном OAuth, но вызов API завершается успешно с токеном GAM OAuth.
Похоже, это связано с самим токеном OAuth. Проблема, которую я получаю при создании токена OAuth, заключается в том, что я не могу указать свойство "sub" (или User для ServiceAccountCredentials). Если я добавлю его, я получу 403 Запрещенный ответ с "Запрошенный клиент не авторизован". как error_description при создании токена, т.е. перед вызовом API. Так что, возможно, это проблема, но я не вижу, как это исправить, поскольку я использую электронную почту администратора.
Другая возможность состоит в том, что для этого API необходимы учетные данные клиента OAuth, поскольку для GAM требуются учетные данные 2 разных типов: учетная запись службы и клиент OAuth. Поскольку я могу использовать только учетные данные учетной записи службы в моем проекте, я боюсь, что застряну, если это так...
Я не вижу других вариантов, и я застрял с ними обоими, поэтому любая помощь приветствуется. Спасибо!
Мой код:
public static string GetEnterpriseUsersCount()
{
string domain = MYDOMAIN;
string certPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
certPath = certPath.Substring(0, certPath.LastIndexOf("\\") + 1) + "GAMCreds.p12";
var certData = File.ReadAllBytes(certPath);
X509Certificate2 privateCertificate = new X509Certificate2(certData, "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(SERVICE_ACCOUNT_EMAIL)
{
Scopes = new[] { "https://apps-apis.google.com/a/feeds/domain/" },
User = ADMIN_EMAIL
}.FromCertificate(privateCertificate));
Task<bool> oAuthRequest = credential.RequestAccessTokenAsync(new CancellationToken());
oAuthRequest.Wait();
string uri = string.Format("https://apps-apis.google.com/a/feeds/domain/2.0/{0}/general/maximumNumberOfUsers", domain);
HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
if (request != null)
{
request.Method = "GET";
request.Headers.Add("Authorization", string.Format("Bearer {0}", credential.Token.AccessToken));
// Return the response
using (WebResponse response = request.GetResponse())
{
using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
return sr.ReadToEnd();
}
}
}
return null;
}
Изменить: я сосредоточился на областях, как рекомендовано Джеем Ли ниже, и кажется, что отсутствующей областью действия было " https://www.googleapis.com/auth/admin.directory.domain". Однако нигде это не написано на странице документации API настроек администратора. По крайней мере, я не нашел это. Требуется также https://apps-apis.google.com/a/feeds/domain/ но я уже добавил его в список разрешенных областей. Спасибо, Джей!
Редактировать 2: я также обновил исходный код, чтобы он мог помочь в будущем.
1 ответ
Вам необходимо предоставить клиентскому идентификатору своей учетной записи службы доступ к API настроек администратора. Следуйте инструкциям делегирования всего домена Drive, кроме sub в правильной правильной области. Тогда вы можете установить sub= без ошибки.