📁

worklohas-upload-files-control

檔案上傳與下載控制套件,用於保護特定路徑下的檔案,確保只有授權使用者可以訪問。 它可以讓開發者輕鬆地在 Spring Boot 2 專案中實做檔案保護功能,無需修改現有的檔案儲存邏輯。

GroupId
com.worklohas
ArtifactId
worklohas-upload-files-control
最新版本
1.0.3
授權
MIT License

🚀 快速開始

<dependency> <groupId>com.worklohas</groupId> <artifactId>worklohas-upload-files-control</artifactId> <version>1.0.3</version> </dependency>

✨ 功能特點

🛡️ 路徑保護

支援透過設定檔案定義受保護的檔案路徑模式,靈活設定存取權限

🔧 自定義邏輯

支援透過實做介面來自定義檔案保護邏輯,滿足各種業務需求

👤 權限檢查

支援透過 session 或 Spring Security 的 Principal 來檢查用戶權限

🗄️ 資料庫整合

支援從資料庫載入受保護檔案列表,動態管理檔案權限

📄 檔案類型檢測

支援檔案類型自動檢測,決定是內嵌顯示還是附件下載

⚡ 快取機制

支援快取機制,提高效能,支援 MSSQL 和 PostgreSQL 資料庫

📦 安裝說明

Maven

在您的 pom.xml 中添加以下依賴:

<dependency> <groupId>com.worklohas</groupId> <artifactId>worklohas-upload-files-control</artifactId> <version>1.0.3</version> </dependency>

💻 範例專案下載

📁 完整範例專案

我們提供了一個完整的 Spring Boot 範例專案,展示如何使用 worklohas-upload-files-control 套件。 範例包含基本設定、自定義實做、Spring Security 整合等多種使用情境, 幫助您快速理解和應用這個套件。

範例專案包含:
  • 基本檔案保護設定範例
  • 自定義權限檢查器實做
  • 資料庫整合範例
  • Spring Security 整合範例
  • 檔案上傳與下載功能演示
  • 完整的測試案例

⚙️ 基本設定

在您的 application.propertiesapplication.yml 中加入以下設定:

# 啟用檔案保護功能(預設為 true) worklohas.file-protection.enabled=true # 資源基礎路徑,用於將請求路徑轉換為實際檔案路徑 worklohas.file-protection.resource-base-path=classpath:static # 受保護的路徑模式列表 worklohas.file-protection.protected-paths[0]=/uploads/**/*.pdf worklohas.file-protection.protected-paths[1]=/secure/** worklohas.file-protection.protected-paths[2]=/documents/*.docx # 未授權時的錯誤頁面 worklohas.file-protection.unauthorized-page=/error/403

🔧 進階設定

資料庫整合

您可以從資料庫載入受保護檔案列表:

# 啟用資料庫查詢 worklohas.file-protection.enable-database-query=true # 資料庫查詢 SQL worklohas.file-protection.database-query-sql=SELECT file_path as path FROM protected_files

快取設定

# 快取大小 worklohas.file-protection.cache-size=1000 # 快取過期時間(秒) worklohas.file-protection.cache-expire-seconds=3600

檔案類型檢測

# 是否啟用檔案類型自動檢測 worklohas.file-protection.enable-content-type-detection=true # 預設的檔案處理方式:inline(內嵌顯示)或 attachment(附件下載) worklohas.file-protection.default-disposition=inline # 需要以附件方式下載的檔案類型列表 worklohas.file-protection.attachment-types[0]=.zip worklohas.file-protection.attachment-types[1]=.rar worklohas.file-protection.attachment-types[2]=application/octet-stream

🛠️ 自定義實做

自定義檔案存取檢查器

您可以不實做這個 interface,套件將自動允許已登入的使用者存取受保護的檔案,未登入的使用者則無法存取。

登入狀態的檢查使用以下兩種方式:

1. 使用 Spring Security 的 `SecurityContextHolder.getContext().getAuthentication()` 檢查使用者是否已認證。

2. 使用 `HttpServletRequest.getUserPrincipal()` 檢查使用者是否已登入。

實做 FileAccessChecker 介面來自定義檔案存取權限檢查邏輯:

import com.worklohas.filecontrol.FileAccessChecker; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import java.nio.file.Path; @Component public class CustomFileAccessChecker implements FileAccessChecker { @Override public boolean hasAccessPermission(HttpServletRequest request, Path filePath) { // 檢查用戶是否已登入 boolean isAuthenticated = request.getSession().getAttribute("user") != null; // 檢查用戶是否有權限存取檔案 // 這裡可以根據您的業務邏輯來實做,例如: // - 檢查用戶是否具有特定角色或權限 // - 檢查檔案是否屬於當前用戶 // - 檢查檔案是否在特定的時間範圍內可存取 return isAuthenticated; } }

自定義受保護路徑模式

實做 ProtectedPathPattern 介面來自定義受保護的路徑模式:

import com.worklohas.filecontrol.ProtectedPathPattern; import org.springframework.stereotype.Component; import java.util.Arrays; import java.util.List; @Component public class CustomProtectedPathPattern implements ProtectedPathPattern { @Override public List<String> getProtectedPathPatterns() { return Arrays.asList( "/uploads/**/*.pdf", "/secure/**", "/documents/*.docx" ); } }

使用資料庫查詢實做檔案存取檢查器

當您啟用 worklohas.file-protection.enable-database-query=true 設定時,您可以實做 FileAccessChecker 介面的 hasAccessPermission 方法,特別是帶有 fileId 參數的重載版本,以便利用資料庫進行權限檢查:

import com.worklohas.filecontrol.FileAccessChecker; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import java.nio.file.Path; @Component public class DatabaseFileAccessChecker implements FileAccessChecker { @Autowired private JdbcTemplate jdbcTemplate; @Override public boolean hasAccessPermission(HttpServletRequest request, Path filePath) { // 基本檢查,例如用戶是否已登入 boolean isAuthenticated = request.getSession().getAttribute("user") != null; if (!isAuthenticated) { return false; } // 如果沒有 fileId,只能進行基本檢查 return true; } @Override public boolean hasAccessPermission(HttpServletRequest request, Path filePath, String fileId) { // 基本檢查,例如用戶是否已登入 Object user = request.getSession().getAttribute("user"); if (user == null) { return false; } // 從 session 中獲取用戶 ID String userId = getUserIdFromSession(request); // 使用 fileId 從資料庫查詢權限 String sql = "SELECT COUNT(*) FROM file_permissions WHERE file_id = ? AND user_id = ?"; int count = jdbcTemplate.queryForObject(sql, Integer.class, fileId, userId); return count > 0; } private String getUserIdFromSession(HttpServletRequest request) { // 根據您的應用程式邏輯從 session 中獲取用戶 ID Object user = request.getSession().getAttribute("user"); if (user instanceof String) { return (String) user; } else if (user != null) { // 假設 user 是一個包含 id 屬性的對象 // 根據您的實際用戶對象結構調整此處 return user.toString(); } return null; } }

確保您的資料庫中有適當的表格結構來存儲檔案權限,例如:

CREATE TABLE file_permissions ( id INT PRIMARY KEY AUTO_INCREMENT, file_id VARCHAR(255) NOT NULL, user_id VARCHAR(255) NOT NULL, permission_type VARCHAR(50) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY unique_file_user (file_id, user_id) );
進階實做:

您可以根據業務需求擴展此實做,例如支援不同類型的權限(讀取、寫入、刪除等):

@Override public boolean hasAccessPermission(HttpServletRequest request, Path filePath, String fileId) { String userId = getUserIdFromSession(request); // 檢查用戶是否有讀取權限 String sql = "SELECT permission_type FROM file_permissions WHERE file_id = ? AND user_id = ?"; List<String> permissions = jdbcTemplate.queryForList(sql, String.class, fileId, userId); return permissions.contains("READ") || permissions.contains("ADMIN"); }

🔐 與 Spring Security 整合

如果您的專案使用 Spring Security,您可以使用 Spring Security 的 Principal 來檢查用戶權限:

import com.worklohas.filecontrol.FileAccessChecker; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import java.nio.file.Path; @Component public class SecurityFileAccessChecker implements FileAccessChecker { @Override public boolean hasAccessPermission(HttpServletRequest request, Path filePath) { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); // 檢查用戶是否已認證 if (authentication == null || !authentication.isAuthenticated()) { return false; } // 檢查用戶是否有特定角色 boolean hasRole = authentication.getAuthorities().stream() .anyMatch(authority -> authority.getAuthority().equals("ROLE_ADMIN")); return hasRole; } }

📋 完整設定選項

設定項 類型 預設值 說明
worklohas.file-protection.enabled Boolean true 是否啟用檔案保護功能
worklohas.file-protection.resource-base-path String classpath:static 資源基礎路徑,用於將請求路徑轉換為實際檔案路徑
worklohas.file-protection.protected-paths List<String> [] 受保護的路徑模式列表
worklohas.file-protection.enable-database-query Boolean false 是否啟用資料庫查詢來獲取受保護檔案列表
worklohas.file-protection.database-query-sql String null 用於查詢受保護檔案列表的 SQL 語句
worklohas.file-protection.cache-size Integer 1000 受保護檔案快取的大小
worklohas.file-protection.cache-expire-seconds Integer 3600 受保護檔案快取的過期時間(秒)
worklohas.file-protection.enable-content-type-detection Boolean true 是否啟用檔案類型自動檢測
worklohas.file-protection.default-disposition String inline 預設的檔案處理方式:inline(內嵌顯示)或 attachment(附件下載)
worklohas.file-protection.attachment-types List<String> [] 需要以附件方式下載的檔案類型列表
worklohas.file-protection.unauthorized-page String /error/403 未授權時的錯誤頁面路徑

❓ 常見問題

如何處理大檔案?

本套件使用 Java NIO 來讀取和寫入檔案,可以有效處理大檔案。預設的緩衝區大小為 8KB,您可以根據需要調整 DefaultFileProtectionService 中的 BUFFER_SIZE 常量。

如何支援其他資料庫?

本套件使用 Spring 的 JdbcTemplate 來執行資料庫查詢,因此理論上支援所有 Spring 支援的資料庫。您只需要在專案中添加相應的資料庫驅動依賴即可。

如何自定義檔案類型檢測?

您可以實做自己的 FileTypeDetector 類,並將其註冊為 Spring Bean,覆蓋預設的實做。