前置准备
1. 确认你的档案管理软件为开源可扩展版本,本文以开源热门工具Paperless-ngx为例,其他同类软件可按逻辑适配;2. 安装Python3.9+,具体下载地址:https://www.python.org/downloads/,安装时必须勾选Add Python to PATH选项;3. 准备企业LDAP用户属性数据,本文假设LDAP服务器地址为ldap://your-ldap-server:389,用户包含department(部门)、title(岗位)属性。
第一步:部署轻量ABAC适配服务
ABAC即基于属性的权限控制,可实现“档案类型+部门+岗位”的细粒度权限管控,无需修改核心档案软件代码。操作步骤:
- 新建文件夹paperless-abac,进入文件夹后执行命令:pip install flask ldap3 requests
- 新建文件app.py,粘贴以下完整代码:
```
from flask import Flask, request, jsonify
import ldap3
import requests
app = Flask(__name__)
LDAP基础配置,务必替换为你自己的参数
LDAP_SERVER = 'ldap://your-ldap-server:389'
LDAP_ADMIN_USER = 'cn=admin,dc=yourcompany,dc=com'
LDAP_ADMIN_PWD = 'your-ldap-admin-password'
LDAP_SEARCH_BASE = 'ou=users,dc=yourcompany,dc=com'
细粒度权限校验函数
def check_user_permission(user_dn, doc_type):
连接LDAP查询用户属性
server = ldap3.Server(LDAP_SERVER)
conn = ldap3.Connection(server, user=LDAP_ADMIN_USER, password=LDAP_ADMIN_PWD, auto_bind=True)
conn.search(LDAP_SEARCH_BASE, f'(distinguishedName={user_dn})', attributes=['department', 'title'])
if not conn.entries:
return False
user_dept = conn.entries[0].department.value
user_title = conn.entries[0].title.value
核心权限规则:可根据自身需求修改
规则1:项目档案仅研发部高级工程师可读写
if doc_type == 'project' and user_dept == '研发部' and user_title == '高级工程师':
return True
规则2:人事档案仅HR部经理可读写
if doc_type == 'personnel' and user_dept == 'HR部' and user_title == '经理':
return True
return False
对外权限校验接口
@app.route('/api/check-doc-access', methods=['POST'])
def api_check_access():
req_data = request.get_json()
user_dn = req_data.get('user_dn')
doc_type = req_data.get('doc_type')
if not user_dn or not doc_type:
return jsonify({'code': 400, 'msg': '缺少user_dn或doc_type参数'}), 400
access_allowed = check_user_permission(user_dn, doc_type)
return jsonify({'code': 200, 'data': {'allowed': access_allowed}})
if __name__ == '__main__':
启动服务,监听所有网卡5000端口
app.run(host='0.0.0.0', port=5000, debug=False)
```
- 修改app.py中的LDAP配置参数,替换为你的实际LDAP服务器地址、管理员账号密码、搜索基;
- 启动适配服务:在paperless-abac目录执行命令:python app.py,确保防火墙开放5000端口。
第二步:修改Paperless-ngx权限校验逻辑

Paperless-ngx默认权限为粗粒度角色控制,需在其权限校验入口调用我们的ABAC接口,步骤:
- 找到Paperless-ngx的视图文件:paperless/src/documents/views/document_viewset.py;
- 在该文件顶部导入适配服务的请求模块,同时配置接口地址:
```
import requests
本地适配服务地址,若部署在其他服务器替换为对应IP
ABAC_API = 'http://localhost:5000/api/check-doc-access'
```
- 重写get_queryset方法,添加权限校验逻辑,修改后核心代码:
```
from rest_framework import viewsets
from .models import Document
from .serializers import DocumentSerializer
import requests
class DocumentViewSet(viewsets.ModelViewSet):
serializer_class = DocumentSerializer
queryset = Document.objects.all()
ABAC_API = 'http://localhost:5000/api/check-doc-access'
def get_queryset(self):
user = self.request.user
doc_type = self.request.query_params.get('doc_type', '')
调用ABAC接口校验权限
try:
resp = requests.post(
ABAC_API,
json={'user_dn': user.username, 'doc_type': doc_type},
timeout=2
)
resp_data = resp.json()
if not resp_data.get('data', {}).get('allowed'):
return Document.objects.none()
except Exception:
权限校验失败时默认返回无权限,可按需调整
return Document.objects.none()
return super().get_queryset()
```
- 重启Paperless-ngx服务,使修改生效,执行命令:sudo systemctl restart paperless(若为Docker部署,执行docker restart paperless)。
第三步:扩展自定义权限规则
若需新增细粒度权限,比如“2024年以后的项目档案仅研发部主管可读写”,直接修改app.py中的check_user_permission函数,追加规则即可:
- 在函数中新增逻辑:
```
规则3:2024年后项目档案仅研发部主管可读写
if doc_type == 'project' and user_dept == '研发部' and user_title == '主管':
需在请求参数中新增doc_year,此处假设从请求获取
doc_year = request.json.get('doc_year', 0) if 'request' in locals() else 0
if doc_year >=2024:
return True
```
- 修改调用接口的传参,将doc_year添加到POST请求中,确保参数传递完整。
验证与排障
1. 功能验证:用研发部高级工程师账号访问项目档案,应显示正常;用普通工程师账号访问项目档案,应无权限显示;2. 常见问题排障:若适配服务无响应,检查5000端口是否开放;若权限校验失败,检查LDAP配置是否正确,或Paperless-ngx与适配服务的网络连通性;若Paperless服务报错,查看Paperless日志路径(默认/var/log/paperless),确认代码修改无语法错误。