サービス アカウントでGoogle Admin Settings APIを使用しようとしていますが、C# コンソール アプリケーションからは成功しません。
私が理解したことから、まず OAuth トークンを取得する必要があります。これには、Google.Apis.Auth.OAuth2.ServiceAccountCredentials を使用するか、JWT アサーションを手動で作成するという 2 つの方法を試しました。
しかし、OAuth トークン (たとえば、maximumNumberOfUsers) を使用して管理者設定 API を呼び出すと、「ドメイン xxx で操作を実行する権限がありません」というメッセージとともに 403 エラーが常に発生します。
同じ HTTP リクエストを作成できるように、作成者がこの API も呼び出すので、GAMをダウンロードしました。GAM wiki で説明されているように、範囲の問題ではないことを確認できるように、すべての手順に従って新しいサービス アカウントと新しい OAuth クライアント ID を作成しました。このスレッドでJay Lee が提案したように、デバッグ モードも有効にしました。スレッドのコメントで説明されているように、私の OAuth トークンではまだ機能しませんが、API への呼び出しは GAM OAuth トークンで成功します。
したがって、OAuthトークン自体に関連しているようです。OAuth トークンの作成中に発生する問題は、「サブ」プロパティ (または ServiceAccountCredentials のユーザー) を指定できないことです。追加すると、「要求されたクライアントは承認されていません」という 403 Forbidden 応答が返されます。トークンの生成中、つまり API を呼び出す前の error_description として。おそらくそれが問題ですが、管理者のメールを使用しているため、修正方法がわかりません。
もう 1 つの可能性は、GAM がサービス アカウントと OAuth クライアントの 2 種類の資格情報を必要とするため、この API が 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」だったようです。ただし、これは Admin Settings API ドキュメント ページのどこにも書かれていません。少なくとも、私は見つけられませんでした。「https://apps-apis.google.com/a/feeds/domain/」も必要ですが、許可されたスコープのリストに既に追加しています。ありがとうジェイ!
編集 2:将来役立つように、ソース コードも更新しました。