今天花了3个小时把公司内网论坛架好了,同时接入了公司的 Active Directory 服务器账号登录。在此做一点记录。
因为最近用flask 写了几个网站,所以论坛系统我也选择了 flaskbb ,方便平时改着玩儿。这是一个基于 flask 的轻量级论坛,在 Github 上有 800+ follows ,它使用了大量的 flask 插件来简化开发,论坛本身也支持插件系统。
应该使用 python 2.7 来部署 flaskbb。
为了支持 mysql,我们需要安装一个数据库驱动库,这里我选择 PyMySQL ,它使用纯 Python 实现,在 Python2/3 下都可以使用。使用 pip install pymysql 安装它。
为了支持 LDAP 协议,我们需要安装一个 LDAP 驱动。这里我选择 ldap3 ,我在实现 LDAP 验证登录 中做过介绍。它也是使用纯 Python 实现, 同时兼容 Python2/3 。使用 pip install ldap3 安装它。
默认配置文件中使用的数据库系统是 sqlite。如果要使用 MySQL,需要做一些小小的修改。
首先,需要修改官方配置文件中的 SQLALCHEMY_DATABASE_URI 为如下所示:
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://zrong:password@localhost/flaskbb'这里的配置已经指定使用 MySQL 数据库,而且采用 pymysql 作为数据库驱动,数据库名称是 flaskbb。flaskbb 应该是一个已经存在的数据库,而且内容为空。除了基本的 SELECT/INSERT/UPDATE/DELETE 权限外,zrong 这个帐号需要有 ALTER/CREATE/INDEX 权限。
接下来,需要初始化数据库。如果按照官方文档所说执行 make install 多半是不成功的,会提示表不存在。这可能是由于作者没有仔细测试,或者没有更新文档的原因。正确的用法应该是执行下面的命令对数据库进行初始化(建表,填充必要数据):
python manage.py initdb然后创建一个管理员,命令行会询问帐号和密码等信息:
python manage.py create_admin如果要显示中文翻译(并不完全),还可以编译语言文件:
python manage.py compile_translationsBTW: flaskbb 采用的是 GNU gettext 实现多语言支持的,这和 WordPress 一样。我曾经写过一个 lua 封装: 在Lua中使用gettext实现多语言支持 。在 Python 中, babel 就带有 gettext 的支持 。
我在实现 LDAP 验证登录 中已经介绍过 Python 的 LDAP 实现。这里介绍一下应该如何修改 flaskbb 使其支持与公司的 AD 服务器集成。
一开始我准备采用 flaskbb 的 插件系统 来实现这个功能,这样就可以不必修改源码。但我仔细看了官方提供的 Portal 插件的实现后后发现,flaskbb 中的插件机制是通过预埋 event 钩子来实现注入的。这个 event 必须自己埋入代码中才能生效。这就违背了我不愿意改源码的初衷。时间有限,插件的机制后面再深究,先把功能实现再说。
LDAP 服务器的信息需要加入到配置项中,我修改了 configs/production.py.example ,这些项目必须配置才能实现 LDAP 登录:
# LDAP Settings # ------------------------------ # # For LDAP authorize LDAP_SERVER = 'ldapserver.example.org' LDAP_PORT = None LDAP_USER_FMT = 'Yourcompany\\%s' LDAP_EMAIL_SUFFIX = '@example.org'帐号鉴权调用的是 user/models.py 中的 User.authenticate 方法。这是个 classmethod 。我增加了一个 User.authenticate_ldap classmethod,在这个方法中读取上述配置项。
这个方法的实现很简单:先检测帐号的合法性,去 AD 服务器鉴权。若鉴权成功,就查询 flashbb 的数据库中有没有该账号,若有则更新登录时间,若无则在 flaskbb 的 users 表中创建该帐号,将密码置为 ‘password’ ,并立即启用该帐号。
user = User(username=login, email=login+email_suffix, password='password', date_joined=time_utcnow(), primary_group_id=4, language='zh', activated=True) user.save()由于鉴权完全使用 AD 服务器实现,在 users 表中不应该保存密码。
完整的方法可查看 User.authenticate_ldap 。
调用鉴权的位置是 auth/views.py 中的 login 路由。将这个路由的端点注释掉,改名为 login_origin ,创建一个新的 login 方法,使其调用 User.authenticate_ldap 方法进行鉴权。
完整的方法可查看 login 。
由于鉴权完全使用 AD 服务器实现,注册账号、修改账号、重置密码、修改密码、修改 email 等功能都需要禁用。
注册账号的功能可以直接在 flaskbb 的后台中取消。其他几个功能则需要修改源码实现。
忘记密码和重置密码功能在 auth/views.py 的 forgot_password 和 reset_password 中, abort(403) 即可: