操作前需提前获取以下资源/权限,避免操作中途卡壳:
操作前必须执行全量备份,避免配置错误导致业务中断:执行以下命令备份系统源码、数据库、配置文件:
```shell 备份源码 tar -zcvf /backup/archive-system-src-$(date +%Y%m%d).tar.gz /opt/archive-system 备份MySQL数据库,替换括号内内容为实际数据库密码 mysqldump -u root -p[你的数据库密码] archive_db > /backup/archive-db-$(date +%Y%m%d).sql 备份配置文件 cp -r /opt/archive-system/config /backup/config-$(date +%Y%m%d) ```针对管理员、涉密档案访问用户强制开启MFA,采用TOTP算法无需对接第三方服务,直接集成:
添加密码规则校验,所有用户密码必须满足长度≥10位,包含大小写字母、数字、特殊符号,正则校验规则如下,可直接复制使用:
```regex ^(?=.[a-z])(?=.[A-Z])(?=.\d)(?=.[@$!%?&])[A-Za-z\d@$!%?&]{10,}$ ```用户表新增last_pwd_change字段,新增90天强制修改密码逻辑,每次登录校验时间差,超期强制跳转密码修改页。
Nginx部署场景直接修改/etc/nginx/conf.d/archive-system.conf配置文件,强制HTTP跳转HTTPS,禁用低版本TLS协议避免降级攻击:
```nginx server { listen 80; server_name 替换为你的档案系统域名; return 301 https://$server_name$request_uri; } server { listen 443 ssl; server_name 替换为你的档案系统域名; ssl_certificate 替换为SSL证书pem文件路径; ssl_certificate_key 替换为SSL证书key文件路径; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } ```配置完成后执行nginx -t校验配置无误,执行systemctl reload nginx生效。

针对身份证号、涉密档案内容、联系方式等核心字段采用AES-256加密存储,加密密钥存放在服务器环境变量中,禁止硬编码在代码里,加密工具类可直接复制:
```java import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; public class AESUtil { // 密钥从环境变量获取,启动命令添加参数:-DAES_SECRET=自定义32位密钥 private static final String SECRET = System.getenv("AES_SECRET"); private static final String ALGORITHM = "AES/ECB/PKCS5Padding"; // 加密 public static String encrypt(String content) throws Exception { SecretKeySpec keySpec = new SecretKeySpec(SECRET.getBytes(), "AES"); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, keySpec); return Base64.getEncoder().encodeToString(cipher.doFinal(content.getBytes())); } // 解密 public static String decrypt(String encryptStr) throws Exception { SecretKeySpec keySpec = new SecretKeySpec(SECRET.getBytes(), "AES"); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, keySpec); return new String(cipher.doFinal(Base64.getDecoder().decode(encryptStr))); } } ```数据库层面新增涉密字段访问审计表,所有对涉密字段的查询、修改操作全部记录,审计日志仅允许查看,禁止修改、删除。
采用Casbin实现细粒度RBAC权限管控,按角色拆分权限:档案录入员、档案审核员、涉密档案管理员、系统管理员,每个角色仅拥有对应操作权限,model.conf配置文件内容如下:
```conf [request_definition] r = sub, obj, act [policy_definition] p = sub, obj, act [role_definition] g = _, _ [policy_effect] e = some(where (p.eft == allow)) [matchers] m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act ```policy.csv权限规则示例,可根据实际业务调整:
```csv p, 档案录入员, /api/archive/add, POST p, 档案录入员, /api/archive/list, GET p, 涉密档案管理员, /api/archive/secret/, p, 系统管理员, /api/system/, ```新增权限拦截器,所有接口请求前调用Casbin的enforce方法校验权限,校验不通过直接返回403:
```java @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String userId = request.getHeader("user-id"); String role = userService.getUserRole(userId); String uri = request.getRequestURI(); String method = request.getMethod(); boolean hasPermission = casbinEnforcer.enforce(role, uri, method); if (!hasPermission) { response.setStatus(403); response.getWriter().write("无访问权限"); return false; } return true; } ```注意:所有单条资源查询接口必须额外校验资源归属,比如查询档案接口需校验档案所属部门和用户所属部门是否匹配,避免水平越权。
所有操作都要记录日志,包括用户ID、操作时间、操作IP、操作内容、请求参数、返回结果,日志保存时间≥6个月,符合档案管理安全规范,审计日志表结构如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键 |
| user_id | varchar(32) | 操作用户ID |
| operate_time | datetime | 操作时间 |
| operate_ip | varchar(16) | 操作IP |
| content | text | 操作内容 |
| request_param | text | 请求参数 |
所有配置完成后执行全量功能测试,确认登录、档案增删改查、权限校验等核心流程正常,无加密解密异常、权限异常后即可上线。