本篇文章更新時間:2025/01/18
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知。
一介資男的 LINE 社群開站囉!歡迎入群聊聊~
如果本站內容對你有幫助,歡迎使用 BFX Pay 加密貨幣 或 新台幣 贊助支持。
Google Workspace 作為企業日常工作工具的解決方案是真的很方便。不過一但企業使用人數到達一定規模後,相關控管的需求隨之而來,真的就不能只是用了而已。
現在人都習慣直接開雲端硬碟的檔案來使用,然後分享給外部人士可能也是直接權限全開,只要有連結就看得到內容。
更不用說同個瀏覽器多個 Google 帳號登入的公私帳號混用情況下,有時候還不是用公司的信箱來處理公務。針對這個問題其實也真的不是使用者的錯,這個算是公司層級需要去顧慮的,也是目前 Chrome 也還有的問題(無法同一個瀏覽器指定哪個帳號為角色預設認定)。
總之,接手這樣可能檔案權限各種混亂的情境,第一件事就是要先想辦法全面性的調整。
Google Workspace Admin 的工具中,在 稽核與調查 中可以調到使用者對 Drive 的各種操作紀錄,第一步可以先從這邊來做觀察,與設定報告通知,在第一時間內有人打開檢視權限都可以收到通知,近一步展開調查。
那原本已經權限大開的檔案怎辦?
Admin 這邊並未開放任何可以管理或觀看到使用者信件或檔案的權限,這部分需要透過整合 App 的 全網域委派 來下手了。
內容目錄
前置準備
- 需要有 Google Workspace Admin 總管理員權限的賬號
- 需要開通 Google Cloud Platform(GCP) 服務與有權限能進一步開通 Drive API 與 Admin API
Google Cloud Platform 端的設定
先在 GCP 上開一個專案,然後到 API 和服務
中開啟 Google Drive API
與 Admin SDK API
這兩個。
再來到 憑證
的分頁,建立一個 服務帳戶
,然後把 Workspace 管理者的帳號授予權限。
建立過程中會產生一組接下來程式會需要用到的登錄識別檔案,要好好保存不能外流。
建立完成後回到這個服務帳戶的編輯頁面,看到進階設定處點開,會發現一個 網域層級委派
的區塊,先是複製上方提供的 用戶端 ID
然後點擊查看 Workspace 管理控制台,如下圖:
Google Workspace Admin 端的設定
接著來到 Admin 端介面,要先到 安全性 > API 控制項 >
全網域委派 這裡,新增 API 用戶端
,把剛剛複製的 用戶端 ID
貼上去,並把下方的權限授權給這個用戶:
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/drive.metadata.readonly
https://www.googleapis.com/auth/admin.directory.user.readonly
到這邊就完成接下來開發上需要的存取控制權限了~
撈取全公司 Workspace 使用者的方法
這邊我使用 PHP 開發,需要先行安裝 [Google API Client](composer require google/apiclient) 的函式庫
composer require google/apiclient
然後取的全部使用者的程式碼片段如下:
setSubject('[email protected]'); // 替代此用戶進行操作
$client->setAuthConfig($service_account_file); // 設定服務帳戶金鑰
$client->addScope([Google\Service\Drive::DRIVE, Google\Service\Drive::DRIVE_METADATA_READONLY, Directory::ADMIN_DIRECTORY_USER_READONLY]);
$directoryService = new Directory($client);
$users_emails = [];
$pageToken = null;
do {
// 呼叫 API 取得用戶清單
$response = $directoryService->users->listUsers([
'domain' => 'domain.com', // 替換成你的 Google Workspace 域名
'pageToken' => $pageToken,
'maxResults' => 100, // 請求最多也就 100 筆
'fields' => 'nextPageToken, users(primaryEmail)',
]);
foreach ($response->getUsers() as $user) {
$users_emails[] = $user->getPrimaryEmail(); // 主電子郵件
}
$pageToken = $response->getNextPageToken(); // 下一頁 Token
} while ($pageToken);
print_r($users_emails);
這邊有兩個有趣的地方:
-
setSubject
方法是一種「選擇替身」的操作。也就是你當前是用哪個帳號來做哪件事。有些時候是管理員才能做的事,你就要帶入管理員帳號。 -
pageToken
與nextPageToken
的關係還要靠fields
欄位。如果回傳的欄位沒有帶入nextPageToken
,那就算有填寫pageToken
也撈不到nextPageToken
值!
調整每位使用者雲端硬碟檔案的檢視權限
上方程式碼片段已經取得到每位公司成員的信箱了,再來就是要透過 setSubject
替身方法,來「站在這位使用者」的角度來調整自己的檔案。
就算是使用總管理員的帳號來帶入,Google 還是不允許這帳號去接觸到沒有分享編輯權限的其他人的檔案。
所以就是需要個別將撈取到的使用者做一輪搜尋檔案+修改檔案權限的操作,程式碼片段如下:
foreach ($users_emails as $index => $owner_email) {
$account = explode('@', $owner_email);
$client = new Client();
$client->setSubject($owner_email); // 代替此用戶進行操作
$client->setAuthConfig($serviceAccountFile); // 設定服務帳戶金鑰
$client->addScope([Google\Service\Drive::DRIVE, Google\Service\Drive::DRIVE_METADATA_READONLY]);
// 初始化 Google Drive 服務
$drive_service = new Drive($client);
$files = [];
$pageToken = null;
do {
// 呼叫 Google Drive API 列出檔案
$results = $drive_service->files->listFiles([
'q' => "(visibility = 'anyoneWithLink' OR visibility='anyoneCanFind') AND 'me' in owners",
'fields' => 'nextPageToken, files(id, name, mimeType, owners, permissions, modifiedTime)',
'pageSize' => 100,
'pageToken' => $pageToken,
]);
foreach ($results->getFiles() as $file) {
$permissions = $file->getPermissions();
$permissionDetails = [];
if ($permissions) {
foreach ($permissions as $permission) {
$permissionDetails[] = [
'type' => $permission->getType(),
'role' => $permission->getRole(),
'emailAddress' => $permission->getEmailAddress() ?? 'N/A',
'domain' => $permission->getDomain() ?? 'N/A',
];
}
}
$mimeType = $file->getMimeType();
$tmp = explode('.', $mimeType);
$mimeType_patrs = end($tmp);
$type = 'file';
if ($mimeType_patrs == 'folder') {
$type = 'folder';
}
$owner = $file->getOwners()[0]->getEmailAddress();
$log_file = [
'name' => $file->getName(),
'id' => $file->getId(),
'mimeType' => $mimeType,
'url' => "https://drive.google.com/{$type}/d/{$file->getId()}",
'owner' => $owner,
'modifiedTime' => $file->getModifiedTime(),
'permissions' => $permissionDetails,
];
if (strpos(strtolower($owner), strtolower($owner_email)) !== false) {
// 更新檔案權限
// $permissions = $drive_service->permissions->listPermissions($log_file['id'])->getPermissions();
foreach ($permissions as $permission) {
// 如果是公開共享,將其權限刪除
if ($permission->getType() === 'anyone') {
try {
$drive_service->permissions->delete($log_file['id'], $permission->getId());
echo "移除公開權限檔案: " . $log_file['name'] . PHP_EOL;
// 加新的權限(僅限組織內查看)
$newPermission = new Google\Service\Drive\Permission([
'type' => 'domain', // 組織內
'role' => 'reader', // 只讀
'domain' => 'domain.com', // 替換為組織域名
]);
try {
$drive_service->permissions->create($log_file['id'], $newPermission, [
'sendNotificationEmail' => false, // 禁止發送通知
]);
echo "已更新權限檔案: " . $log_file['name'] . PHP_EOL;
$files[] = $log_file;
file_put_contents(dirname(__FILE__) . '/' . $account[0] . '_modify.log', $log_file['name'] . '|' . $log_file['url'] . '|' . json_encode($permissions) . PHP_EOL, FILE_APPEND | LOCK_EX);
} catch (Exception $e) {
echo '更新權限失敗:' . $log_file['name'] . ' / ' . $e->getMessage();
}
} catch (Exception $e) {
echo '移除權限失敗: ' . $log_file['name'] . ' / ' . $e->getMessage();
}
}
}
}
}
$pageToken = $results->getNextPageToken();
} while ($pageToken !== null);
if (!empty($files)) {
file_put_contents(dirname(__FILE__) . '/' . $account[0] . '_modify_' . date('Y-m-d-H-i-s', time()) . '.json', json_encode($files), FILE_APPEND | LOCK_EX);
}
}
上述程式操作的重點是:
- 撈取當前檢視權限是「公開」的(不限制類型)
- 針對這樣的檔案去移除公開權限,並補上「限定組織內部觀看」。
跑完一圈就能全部調整好權限了~
後記
前言有提到可以先設定好稽核的報告,將日後有設定公開的檔案都發通知給指定管理員。
這個通知基本上就可以在這一波掃描修改後發會功用。確實了解到有哪些人注意到了檔案外連公開失效,又還去改變回公開權限的狀況。
針對資安的操作,這都還很淺,有專門做到這類型檢測資料外流的工具 Forcepoint,不過基本使用單位是用 100 人以上來去估,每個不同規模的公司都有不同要解決的情境呀~
至於關於 Google Workspace Admin 的管理這塊,網路上也能找到一些工具,真是哪裡有困難,哪裡就有商機XD