✨ 功能特點
🛡️ 路徑保護
支援透過設定檔案定義受保護的檔案路徑模式,靈活設定存取權限
🔧 自定義邏輯
支援透過實做介面來自定義檔案保護邏輯,滿足各種業務需求
👤 權限檢查
支援透過 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.properties
或 application.yml
中加入以下設定:
複製
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
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
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 ;
}
return true ;
}
@Override
public boolean hasAccessPermission (HttpServletRequest request, Path filePath, String fileId) {
Object user = request.getSession().getAttribute("user" );
if (user == null ) {
return false ;
}
String userId = getUserIdFromSession(request);
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) {
Object user = request.getSession().getAttribute("user" );
if (user instanceof String ) {
return (String ) user;
} else if (user != null ) {
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,覆蓋預設的實做。