如何用开源技术搭建企业级档案数字化防盗柜系统

一、系统架构与核心组件选型

本方案基于微服务架构,核心在于实现档案数字化后的安全存储与访问控制。我们将使用以下完全开源且成熟的组件:

1. 存储与文件管理

MinIO:替代商业对象存储,用于存放数字化后的扫描文件(PDF、图片等)。

安装命令

``` docker run -p 9000:9000 -p 9001:9001 \ -e "MINIO_ROOT_USER=admin" \ -e "MINIO_ROOT_PASSWORD=YourStrongPassword123" \ -v /mnt/data:/data \ minio/minio server /data --console-address ":9001" ```

2. 元数据与权限管理数据库

PostgreSQL:存储档案的元数据(如档案编号、名称、密级、存储位置、访问记录)和用户权限信息。

3. 防盗与审计核心

Keycloak:负责统一身份认证与细粒度权限控制。

Elasticsearch + Kibana:用于记录和可视化所有档案访问、下载、预览日志,实现操作全追踪。

4. 业务应用层

使用Spring Boot或Python Django快速开发一个简单的Web应用,提供档案上传、检索、在线预览(需集成PDF.js等开源预览组件)和审批流程界面。

二、环境准备与基础服务部署

1. 服务器要求

准备一台Linux服务器(CentOS 7.9或Ubuntu 20.04 LTS),配置建议:4核CPU,8GB内存,500GB SSD硬盘。确保开放所需端口:9000(MinIO API),9001(MinIO控制台),5432(PostgreSQL),8080(Keycloak),9200(Elasticsearch),5601(Kibana)。

2. 使用Docker Compose一键部署基础服务

创建docker-compose.yml文件,内容如下:

``` version: '3.8' services: postgres: image: postgres:14-alpine environment: POSTGRES_DB: archive_db POSTGRES_USER: archive_admin POSTGRES_PASSWORD: YourPostgresPass456 volumes: - postgres_data:/var/lib/postgresql/data restart: unless-stopped minio: image: minio/minio command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: admin MINIO_ROOT_PASSWORD: YourMinioPass123 ports: - "9000:9000" - "9001:9001" volumes: - minio_data:/data restart: unless-stopped keycloak: image: quay.io/keycloak/keycloak:20.0.3 environment: KC_DB: postgres KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak_db KC_DB_USERNAME: archive_admin KC_DB_PASSWORD: YourPostgresPass456 KEYCLOAK_ADMIN: admin KEYCLOAK_ADMIN_PASSWORD: YourKeyCloakAdminPass789 KC_HOSTNAME: localhost command: start-dev ports: - "8080:8080" depends_on: - postgres restart: unless-stopped elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:8.6.2 environment: - discovery.type=single-node - xpack.security.enabled=false - "ES_JAVA_OPTS=-Xms512m -Xmx512m" ports: - "9200:9200" volumes: - es_data:/usr/share/elasticsearch/data restart: unless-stopped kibana: image: docker.elastic.co/kibana/kibana:8.6.2 environment: ELASTICSEARCH_HOSTS: '["http://elasticsearch:9200"]' ports: - "5601:5601" depends_on: - elasticsearch restart: unless-stopped volumes: postgres_data: minio_data: es_data: ```

在包含该文件的目录下,执行docker-compose up -d启动所有服务。等待1-2分钟后,访问以下地址验证:

  • MinIO控制台:http://服务器IP:9001, 使用admin/YourMinioPass123登录。
  • Keycloak管理后台:http://服务器IP:8080, 使用admin/YourKeyCloakAdminPass789登录。
  • Kibana:http://服务器IP:5601。

三、关键配置与核心功能实现

1. 在MinIO中创建存储桶与访问策略

登录MinIO控制台,点击“Buckets”创建两个桶:archive-original(存放原始扫描件)、archive-preview(存放用于在线预览的压缩或水印版)。

如何用开源技术搭建企业级档案数字化防盗柜系统

为每个桶设置访问策略。进入“Access Policies” -> “Add Policy”,创建一个名为“archive-read-write”的策略,内容如下:

``` { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::archive-original/", "arn:aws:s3:::archive-preview/" ] } ] } ```

然后创建一个服务账户(Service Account),将上述策略附加给它,并妥善保存生成的Access Key和Secret Key,用于后端程序连接MinIO。

2. 在Keycloak中配置认证与权限

登录Keycloak管理后台。

  1. 创建领域(Realm):从默认的“master”下拉菜单选择“Create Realm”,输入“archive-system”。
  2. 创建客户端(Client):在左侧菜单“Clients”中点击“Create”,输入Client ID为“archive-web-app”,Client Protocol选择“openid-connect”,保存。
  3. 配置客户端:在客户端的“Settings”选项卡中,将“Access Type”设置为“confidential”,Valid Redirect URIs填入你的应用前端地址,例如“http://your-app-domain/”。保存后,在“Credentials”选项卡中记录下生成的Secret
  4. 创建角色(Roles):在左侧菜单“Roles”中,为“archive-system”领域创建角色,例如:archive_viewer(仅查看)、archive_operator(上传、下载)、archive_admin(管理用户和权限)。
  5. 创建用户并分配角色:在“Users”中创建用户,在“Role Mappings”选项卡中,从“Client Roles”选择“archive-web-app”,将创建好的角色分配给他。

3. 设计并初始化数据库表

连接至PostgreSQL(可使用DBeaver或psql命令行),执行以下SQL创建核心表:

``` CREATE TABLE archive_meta ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), archive_code VARCHAR(100) NOT NULL UNIQUE, archive_name VARCHAR(500) NOT NULL, secret_level INT NOT NULL CHECK (secret_level BETWEEN 1 AND 3), -- 1公开,2内部,3机密 original_file_path VARCHAR(1000), -- 对应MinIO中object key preview_file_path VARCHAR(1000), uploader_id VARCHAR(100), upload_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX idx_code (archive_code), INDEX idx_secret_level (secret_level) ); CREATE TABLE access_log ( id BIGSERIAL PRIMARY KEY, archive_id UUID REFERENCES archive_meta(id), user_id VARCHAR(100) NOT NULL, operation VARCHAR(50) NOT NULL, -- 'PREVIEW', 'DOWNLOAD', 'VIEW_DETAIL' operation_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, client_ip INET, INDEX idx_user_time (user_id, operation_time DESC) ); ```

四、业务应用开发核心代码示例

1. 后端(Spring Boot)文件上传与权限校验

在application.yml中配置:

``` minio: endpoint: http://your-server-ip:9000 access-key: YOUR_MINIO_ACCESS_KEY secret-key: YOUR_MINIO_SECRET_KEY bucket: original: archive-original preview: archive-preview ```

核心上传控制器方法:

``` @PostMapping("/upload") @PreAuthorize("hasRole('archive_operator')") // Keycloak角色校验 public ResponseEntity uploadArchive(@RequestParam("file") MultipartFile file, @RequestParam String archiveCode, @RequestParam int secretLevel, @AuthenticationPrincipal Jwt jwt) { String userId = jwt.getClaim("preferred_username"); // 1. 生成唯一文件名,避免覆盖 String originalFileName = UUID.randomUUID() + "_" + file.getOriginalFilename(); // 2. 上传至MinIO原始桶 minioClient.putObject( PutObjectArgs.builder() .bucket(minioConfig.getBucket().getOriginal()) .object(originalFileName) .stream(file.getInputStream(), file.getSize(), -1) .contentType(file.getContentType()) .build()); // 3. 生成预览文件(此处简化,实际需调用图像处理库加水印、压缩) // 4. 元数据存入PostgreSQL archiveMetaService.save(archiveCode, originalFileName, userId, secretLevel); // 5. 记录审计日志至Elasticsearch logToElasticsearch(archiveCode, userId, "UPLOAD", getClientIp()); return ResponseEntity.ok("上传成功"); } ```

2. 前端集成Keycloak登录

在Vue/React应用入口,使用Keycloak JS适配器:

``` import Keycloak from 'keycloak-js'; const initOptions = { url: 'http://your-server-ip:8080', realm: 'archive-system', clientId: 'archive-web-app', onLoad: 'login-required' }; const keycloak = new Keycloak(initOptions); keycloak.init({ onLoad: initOptions.onLoad }).then((authenticated) => { if (authenticated) { // 将token存入axios请求头 axios.defaults.headers.common['Authorization'] = 'Bearer ' + keycloak.token; // 启动你的应用 app.mount('app'); } }).catch(() => { console.error("认证失败"); }); ```

五、审计日志与安全加固

1. 全量操作日志记录

在后端每个涉及档案操作的接口中,调用日志服务。使用Spring AOP或拦截器统一处理。日志数据直接通过Elasticsearch REST API写入。

``` @Async public void logToElasticsearch(String archiveCode, String userId, String operation, String ip) { Map log = new HashMap<>(); log.put("@timestamp", Instant.now()); log.put("archive_code", archiveCode); log.put("user_id", userId); log.put("operation", operation); log.put("client_ip", ip); // 使用RestHighLevelClient或WebClient发送POST请求到 http://localhost:9200/archive-access-log/_doc } ```

2. 在Kibana中创建监控仪表盘

登录Kibana,进入“Discover”,首次使用会提示创建“archive-access-log”索引模式。创建后,进入“Dashboard”创建新的仪表盘,添加以下可视化组件:

  • “今日档案访问次数”指标图。
  • “操作类型分布(预览/下载)”饼图。
  • “高频访问用户TOP10”柱状图。
  • “原始日志数据”表格,展示时间、用户、档案编号、操作和IP。

将此仪表盘设置为管理员每日查看的首页。

3. 关键安全配置

  • 网络隔离:将上述所有服务部署在内网,仅通过反向代理(如Nginx)暴露前端应用和Keycloak登录页面。
  • MinIO加密:在MinIO控制台为存储桶启用服务器端加密(SSE-S3)。
  • 数据库备份:设置PostgreSQL每日定时备份至另一台物理隔离的服务器。使用命令pg_dump -U archive_admin archive_db > /backup/archive_$(date +%Y%m%d).sql
  • Keycloak双因素认证:在Keycloak的“Authentication”流程中,为“archive-system”领域绑定OTP(一次性密码)认证器,要求archive_admin角色用户必须启用。

六、上线与日常维护检查清单

  • ✅ 所有Docker服务运行正常(docker-compose ps)。
  • ✅ MinIO存储桶策略正确,服务账户密钥已安全配置到后端。
  • ✅ Keycloak领域、客户端、角色、用户配置完成,前端能成功获取Token。
  • ✅ 数据库表创建完成,应用能正常连接和写入。
  • ✅ 前端应用上传、检索、预览功能测试通过,权限控制生效(不同角色用户看到不同内容)。
  • ✅ Elasticsearch能正常接收日志,Kibana仪表盘数据展示正常。
  • ✅ 制定备份策略:数据库每日全量备份,MinIO数据可通过mc mirror命令同步至备份存储。
  • ✅ 设置系统监控(如使用Prometheus+Grafana监控服务器资源、服务健康状态)。

完成以上所有步骤,一个具备完整身份认证、细粒度权限控制、全操作审计追踪的企业级档案数字化防盗柜系统即部署完毕。核心在于权限与审计链条的闭环,任何对数字档案的触碰都会留下不可篡改的记录。

AI咨询
热线电话

028-85154420

15388110056

全国售前咨询电话

扫码咨询
安答联动微信公众号二维码

微信扫码关注安答联动

申请试用
热线电话
申请试用

安答联动档案管理系统