記事公開日
最終更新日
【Googleドライブ】管理者必見!マイドライブ内のファイル共有状況を把握する方法

自分のマイドライブの中は誰にも見られない・・・と思っていませんか?
例えばGoogle Workspace(旧G Suite)を使用している会社で、ユーザがマイドライブ内のファイルを他社と共有しっぱなしにしていてセキュリティが不安、なんてことはあるのではないでしょうか。
そしてその共有状況をきちんと把握している、という会社も少ないのではないでしょうか。
私達は日頃、Microsoft Identity Managerを利用してオンプレミスとクラウド(M365とAzureが中心)のID管理をしていますが、その流れで管理者の方からファイルの管理やセキュリティについての不安や要望を時折耳にします。
本記事ではサービスアカウントを使用し、ドメイン内ユーザのマイドライブに対し、中身のフォルダ・ファイル情報(共有情報を含む)を取得する方法、また、共有を解除する方法についてご紹介いたします。
本記事の内容と以前ご紹介したGoogle Admin SDK、.netを利用したGsuiteユーザCRUDを組み合わせれば、共有されたフォルダ・ファイルを容易に把握でき、共有解除することができるので、セキュリティ面の不安は一気に解消できるのではないでしょうか。
[事前準備]
・Google Workspace(旧G Suite)テナント
・Google Workspace(旧G Suite)ユーザライセンス
(Googleドライブにファイルを作成できるアカウントが必要です。)
・Visual Studio (事前に開発環境にインストールしておきます。)
※今回は2019を使用しています。
1.準備(各種設定の実施)
まずは以下の記事の③まで行い、GCPへプロジェクトを作成しましょう。Google Admin SDK、.netを利用したGsuiteユーザCRUD
※プロジェクト名は[SampleSharedFile]にしました。
次にGCPでDrive APIを有効にします。
①GCP画面上部左のハンバーガーアイコンから[APIとサービス]-[ライブラリ]を選択します。

②検索窓へ[Drive API]と入力し、検索結果の[Google Drive API]を選択します。

③[有効にする]を選択します。

次はサービスアカウントを作成します。
このサービスアカウントを使用して、各ユーザで偽装ログインを行い、マイドライブ内の情報を取得することになります。
④GCP画面上部左のハンバーガーアイコンから[APIとサービス]-[認証情報]を選択します。
遷移した画面の上部[認証情報を作成]を選択、[サービスアカウント]を押下します。

⑤以下を入力し、[作成]を押下します。
サービスアカウント名:SVA-SampleSharedFile(※任意名)
サービスアカウントlD:上記サービスアカウント名を入力すると自動でサービスアカウントIDが入ります。任意に設定もできますが、今回は変更しません。

⑥[ロールの選択]を押下するとメニューが出てくるので、[Project]-[オーナー]を選択します。
その後、[続行]を押下します。


⑦そのまま[完了]を押下します。

⑧作成したサービスアカウントが表示されますので、チェックを入れ、編集アイコンを選択します。

⑨[ドメイン全体の委任の表示]を選択して開き、[G Suite ドメイン全体の委任を有効にする]にチェックを入れ、[同意画面のプロダクト名]に任意の名称を入力します。

⑩次に[鍵を追加]-[新しい鍵を作成]を選択します。

Jsonを選択し、[作成]を押下します。

以下ダイアログが表示され、キーファイルがダウンロードされます。
[閉じる]を押下します。

⑪キーができていることを確認し、[保存]を押下します。

サービスアカウントを作成するとOAuth2.0クライアントIDも自動で作成されます。
OAuth2.0クライアントIDのクライアントIDは後に必要になるので記録しておきます。

次はGoogle Workspace側の設定です。
Drive SDKの許可設定を行います。
⑫特権管理者でログインし、以下にアクセスします。
<https://admin.google.com/ac/home>
画面上部左のハンバーガーアイコンから[アプリ]-[Google Workspace]-[ドライブとドキュメント]を選択します。
[機能とアプリケーション]を開き、[Drive SDK]が[オン]になっていることを確認します。
※なっていない場合は[Drive SDK] を開き、[Drive SDK API 経由での Google ドライブへのアクセスをユーザーに許可する]にチェックを入れ、[保存]を押下します。


クライアントからGoogleサービスのデータへアクセスできるよう許可設定を行います。
⑬画面上部左のハンバーガーアイコンから[セキュリティ]を選択します。
[APIの制御]を開き、[ドメイン全体の委任を管理]を選択します。

⑭[新しく追加]を選択します。

以下を入力し、[承認]を押下します。
クライアントID:⑪で記録したクライアントID
OAuthスコープ:以下URLを入力します。
・https://www.googleapis.com/auth/drive
※スコープは使用するAPIによって異なります。
例えばドライブからファイル情報を取得するにはDrive APIのFiles:listを使用しますが、実行に必要なスコープは各リファレンスに記載してあります。
<https://developers.google.com/drive/api/v3/reference/files/list#auth>

これで設定は終わりです。次は実装です。
2.実装
(1)まずはVisual Studioで.net coreのコンソールアプリプロジェクトを作成します。※ソリューション、プロジェクト名は[SampleSharedFileApp]にしました。
(2)プロジェクトを右クリックし、[Nugetパッケージの追加]から[Google.Apis.Drive]と検索し、[Google.Apis.Drive.v3]をインストールします。
[変更のプレビュー]ダイアログが表示されますが、そのまま[OK]を押下します。
(3)同様に[Nugetパッケージの追加]から[Google.Apis.Auth]と検索し、[Google.Apis.Auth]をインストールします。
(4)サービスアカウントを作成した際、⑩でダウンロードしたJsonファイルを[cred.json]へリネームし、プロジェクトのフォルダへ移動します。
(5)[cred.json]を右クリックし、[プロパティ]を選択、プロパティペインの[出力ディレクトリにコピー]を[常にコピーする]にする。
ココまでの手順は以前の記事でも似たようなことをしているので参考にしてください。
参考:Google Admin SDK、.netを利用したGsuiteユーザCRUD(※⑮~⑱)
ユーザを指定してマイドライブ内のファイル情報を取得する
では、まずはユーザのマイドライブ内を普通にログインして覗いてみましょう。※通常ユーザ[normal@xxx.work]でログインしています。

以下ファイルがマイドライブ内に存在します。
・TestNotSharedFile
・TestSharedFile
共有のかかっているファイルにはファイル横に以下アイコンが表示されますので、[TestSharedFile]は共有されているファイルということがわかります。

誰と共有されているのか確認するため、ファイルを右クリックし、[共有]を開きます。

[xxx@qes.co.jp]と共有されていることがわかります。(私のメールアドレスで共有をかけています。)
ではこの[normal@xxx.work]のマイドライブ内の情報をプログラムから取得するにはどうすればよいでしょうか。
Visual Studioに戻りましょう。[Program.cs]を以下に書き換えます。
using Google.Apis.Auth.OAuth2; using Google.Apis.Drive.v3; using Google.Apis.Services; using System; using System.Collections.Generic; using System.IO; namespace SampleSharedFileApp { class Program { private static string[] Scopes = {DriveService.Scope.Drive}; private static ICredential Credential; static void Main(string[] args) { // 認証 string credFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "cred.json"); using (var stream = new FileStream(credFile, FileMode.Open, FileAccess.Read)) { Credential = GoogleCredential.FromStream(stream) .CreateScoped(Scopes) .CreateWithUser("normal@xxx.work") // ★ここにマイドライブ内を見たいユーザのメールアドレスを記載します。 .UnderlyingCredential; } // マイドライブ情報取得 var service = new DriveService(new BaseClientService.Initializer() { HttpClientInitializer = Credential }); string nextPageToken = string.Empty; do { FilesResource.ListRequest request = service.Files.List(); request.Fields = "*"; request.Q = "trashed = false"; request.PageToken = nextPageToken; var ret = request.Execute(); IList<Google.Apis.Drive.v3.Data.File> files = ret.Files; if (files != null && files.Count > 0) { foreach (var fileItem in files) { Console.WriteLine(string.Format("メールアドレス(ファイルオーナー):{0}", fileItem.Owners[0].EmailAddress)); Console.WriteLine(string.Format("ファイル名:{0}", fileItem.Name)); Console.WriteLine(string.Format("ファイルID:{0}", fileItem.Id)); Console.WriteLine(string.Format("ファイル種別:{0}", fileItem.MimeType)); if (fileItem.Permissions != null) { foreach (var perm in fileItem.Permissions) { Console.WriteLine("-----"); Console.WriteLine(string.Format("共有者:{0}", perm.EmailAddress)); Console.WriteLine(string.Format("共有ID:{0}", perm.Id)); Console.WriteLine(string.Format("共有種別:{0}", perm.Type)); Console.WriteLine(string.Format("共有者権限:{0}", perm.Role)); Console.WriteLine("-----"); } } Console.WriteLine(string.Format("************************\r\n")); // 改行 } } if (!string.IsNullOrEmpty(ret.NextPageToken)) { nextPageToken = ret.NextPageToken; } else { nextPageToken = string.Empty; } } while (!string.IsNullOrEmpty(nextPageToken)); return; } } }
コード解説
定義部
ここは⑭で許可したスコープを指定します。複数指定も可能です。その場合は⑭でもスコープを追加することになります。今回は1つのスコープで大丈夫です。
private static string[] Scopes = {DriveService.Scope.Drive};
認証部
⑩でダウンロードしたキーを読み込み、認証を行っています。[CreateWithUser]へユーザのメールアドレスを指定することで、そのユーザとして認証が行われます。
(ですので、今回は[normal@xxx.work]を指定しています。)
string credFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "cred.json");
string credFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "cred.json");
using (var stream = new FileStream(credFile, FileMode.Open, FileAccess.Read))
{
Credential = GoogleCredential.FromStream(stream)
.CreateScoped(Scopes)
.CreateWithUser("normal@xxx.work") // ★ここにユーザのメールアドレスを記載します。
.UnderlyingCredential;
}
ドライブ情報取得部
DriveServiceオブジェクトを作成、リクエストパラメータを設定したうえ、API[Files.List()]を実行しています。[Files.List()]はドライブ内のファイル情報を一覧で取得するAPIです。
特にリクエストパラメータで指定しない限り、認証しているユーザのマイドライブ内のファイル一覧が取得します。
[Files.List()]へ指定できるリクエストパラメータ、スコープ等詳細情報は以下を参考にしてください。
<https://developers.google.com/drive/api/v3/reference/files/list>
今回は[trashed = false]を指定してゴミ箱内のファイルは取得対象外とし、Fields[*]指定で取得できるファイル情報全てを取得しています。
それでは実行してみましょう。
赤枠に注目してみると、 [TestShareFile]が[xxx@qes.co.jp]と共有されていることがわかります。

このように人のマイドライブ内でもファイル情報を取得することができます。
また、コンソールに出力している情報はほんの一部です。
取得可能なファイル情報は以下を参考にしてください。多くの情報を得られることがわかります。
<https://developers.google.com/drive/api/v3/reference/files#resource>
共有されているファイルの共有を解除する
上でファイルの共有状況がわかりました。次は共有を解除してみましょう。
[Program.cs]のforeach部を以下のように書き換えてください。
foreach (var fileItem in files) { Console.WriteLine(string.Format("メールアドレス(ファイルオーナー):{0}", fileItem.Owners[0].EmailAddress)); Console.WriteLine(string.Format("ファイル名:{0}", fileItem.Name)); Console.WriteLine(string.Format("ファイルID:{0}", fileItem.Id)); Console.WriteLine(string.Format("ファイル種別:{0}", fileItem.MimeType)); if (fileItem.Permissions != null) { foreach (var perm in fileItem.Permissions) { Console.WriteLine("-----"); Console.WriteLine(string.Format("共有者:{0}", perm.EmailAddress)); Console.WriteLine(string.Format("共有ID:{0}", perm.Id)); Console.WriteLine(string.Format("共有種別:{0}", perm.Type)); Console.WriteLine(string.Format("共有者権限:{0}", perm.Role)); Console.WriteLine("-----"); } } Console.WriteLine(string.Format("************************\r\n")); // 改行 }
↓
↓
↓
foreach (var perm in fileItem.Permissions)
{
Console.WriteLine("-----");
Console.WriteLine(string.Format("共有者:{0}", perm.EmailAddress));
Console.WriteLine(string.Format("共有ID:{0}", perm.Id));
Console.WriteLine(string.Format("共有種別:{0}", perm.Type));
Console.WriteLine(string.Format("共有者権限:{0}", perm.Role));
Console.WriteLine("-----");
if (perm.Role != "owner")
{
PermissionsResource.DeleteRequest req = service.Permissions.Delete(fileItem.Id, perm.Id);
req.Execute();
Console.WriteLine(string.Format("■共有者:{0}の共有を解除しました。", perm.EmailAddress));
}
}
コード解説
ファイルの共有を解除するAPI[Permissions.Delete()]を実行しています。[Permissions.Delete()]へは、上で取得したファイルのID、共有IDを引数で指定します。
【補足】
権限が[owner]のものは解除できません。[owner]は一人しか設定できず、言葉通りそのファイルの持ち主なので解除しようとするとエラーになってしまいます。
参考までにAPI情報を記載します。
<https://developers.google.com/drive/api/v3/reference/permissions/delete>
では実行してみましょう。

さて、解除できているのでしょうか。[normal@xxx.work]でログインしてみてみましょう。

[TestSharedFile]の アイコンが消えています!
念の為ファイルを右クリックして[共有]を開いてみます。
[xxx@qes.co.jp]との共有が解除されていますね。

最後に
本記事ではユーザのマイドライブに対して、ファイル情報を取得する方法、ファイルの共有解除をする方法についてご紹介しました。では、マイドライブと同様に共有ドライブに対しても情報取得できるのか、共有解除できるのか、と考える方もおられるかと思います。
できます。ただし、少し工夫が必要です。
共有ドライブについてはまたいずれご紹介するとして、今回はここまでとさせていただきます。
今回ご紹介した内容はもちろん、追加の要望(画面やログ取得など)を加え、案件として対応させていただくことも可能です。
その他にもQESでは様々なアプリケーションの開発・導入を行っております。
私共が提供するサービス・ソリューションにつきましてはこちらに掲載しております。
また、現在Power Platform に力を入れて取り組んでいます。Power Apps等のPower Platformについては、こちらをご覧ください。
システム開発・構築でお困りの問題や弊社が提供するサービス・ソリューションにご興味を抱かれましたら、是非一度お問い合わせください。
・このブログで参照されている、G suite、Google Workspace、GCP、Googleロゴ、その他のGoogle製品およびサービスは、Google LLCの商標です。
・このブログで参照されている、Active Directory、Office 365、Windows Azure、Visual Studio、その他のマイクロソフト製品およびサービスは、米国およびその他の国におけるマイクロソフトの商標または登録商標です。