2016 年第一帖。

闲来无事唠嗑一下 STF 相关的技术点。

关于 STF

STF 是啥,怎么安装,可以先看看这两个帖子:

别问我为什么都是 Mac 和 Linux 的,STF 的 Github 上明白得写着:
In principle we will not provide any Windows installation support, but please do send a documentation pull request if you figure out what to do.
官方不提供任何关于 windows 的安装支持,但是你装成功了欢迎你来分享你在 windows 下安装的经验。

关于单点登录和 LDAP

因为 STF 的平台默认是 Mock 登录的,任何人只要获取地址了就可以使用平台上的设备,所以鼓捣着给 STF 接一个单点登录模块,用来限制使用人群,控制使用范围(毕竟设备有限)。
把想法跟小 A 一说,OK,开始鼓捣。
刚准备开干,一扫 STF 的项目目录,/lib/units/auth目录下,除了默认的mock.js模块以外,还有ldap.js这么个文件,打开文件一扫,原来STF已经是有实现好的LDAP模块了,都有现成的模块了,我们还造个毛轮子。
二话不说,找 IT 部门把公司的 LDAP 目录地址、DN 和 DC 拿到,直接接入。

PS:其实 STF 的开发文档里已经说明了 STF 包含的模块了,stf.auth-ldap也在其列,只是我自己偷懒,没有认真阅读,建议大家先读读 STF 里面有说明东西再开工。

另外,应该有许多同学不知道 LDAP 是什么,建议先去百度谷歌补习一下。简单得来说,LDAP 是一种协议,我们通过这种协议可以访问公司的 director server(DS),实现单点登录的效果。(即实现使用域内邮箱密码登录)

准备工作

LDAP 服务器信息与连接 LDAP 服务器的认证账号:

经不断尝试,STF 的 ldap 模式也只需要以上几个重要参数即可。以上信息直接跟你们的行政 IT 部门获取或申请即可。

调试 LDAP 服务器连接

从行政 IT 部门获取到了 LDAP 相关的信息以后,我们利用ldapsearch命令来调试是否能够连通你们公司的 DS。
调试方法:

#调试命令
ldapsearch -x -H $LDAP-SERVER-URI -D $LDAP-BIND-DN -b $LDAP-BSAE-DN -w $LDAP-BIND-DN-PWD
#将大写的参数换成你公司对应的参数即可。例子:
ldapsearch -x H ldap://server.testerhome.com -D 'dadong@testerhome.com' -b 'DC=testerhome,DC=com' -w 'dadongdemima'

如果你公司的 DS 目录内有非常多的员工信息,那你使用该命令会返回 N 页的信息,那么如果是这样的话,说明该 SERVER-URI 和 BIND-DN 是可用的。
那么我们就可用开始正式接入我们的 STF 中去了。

STF 的 LDAP 模块

玩过 STF 的都知道,我们启动 STF 时,使用的命令是stf local,但是这样启动的模式是 mock 登录模式,我们要使用 stf 的 ldap 模式的话,需要在启动的时候,切换 auth 的 type 为 ldap,并设置好 ldap 相关的 option。

我们可以使用stf auth-ldap -h命令来看看 ldap 模块里面有哪些必备的 option:

➜  ~  stf auth-ldap -h

  Usage: auth-ldap [options]

  start LDAP auth client

  Options:

    -h, --help                             output usage information
    -p, --port <port>                      port (or $PORT)
    -s, --secret <secret>                  secret (or $SECRET)
    -i, --ssid <ssid>                      session SSID (or $SSID)
    -a, --app-url <url>                    URL to app
    -u, --ldap-url <url>                   LDAP server URL (or $LDAP_URL)
    -t, --ldap-timeout <timeout>           LDAP timeout (or $LDAP_TIMEOUT)
    --ldap-bind-dn <dn>                    LDAP bind DN (or $LDAP_BIND_DN)
    --ldap-bind-credentials <credentials>  LDAP bind credentials (or $LDAP_BIND_CREDENTIALS)
    --ldap-search-dn <dn>                  LDAP search DN (or $LDAP_SEARCH_DN)
    --ldap-search-scope <scope>            LDAP search scope (or $LDAP_SEARCH_SCOPE)
    --ldap-search-class <class>            LDAP search objectClass (or $LDAP_SEARCH_CLASS)
    --ldap-search-field <name>             LDAP search field (or $LDAP_SEARCH_FIELD)

通过stf auth-ldap -h命令我们大致可以看到 stf 的 ldap 模式启动参数多得让我们眼花缭乱,但实际上我们只会用到其中几个,也就是前面需要大家准备的几个。

由于官方 Github 上没有任何文档有对各个模块的详细单个说明,只能硬啃源码了。

我们看看stf提供的ldaputil.js方法里是怎么设计的。
ldaputil 方法里主要有三个步骤:

所以我们知道了,stf里需要启用ldap模式登录的话,必须要有bind dncredentialsobjectClassfieldsearch dn这么几样东西。

但是这几样东西好像跟我们一开始去取的不太一样啊?其实一样的,这里我们来列一下对照的关系:

-u, -ldap-url : LDAP SERVER URI
--ldap-bind-dn : LDAP BIND DN
--ldap-bind-credentials: LDAP BIND DN_PWD
--ldap-search-dn : LDAP BASE DN

但是,好像还有个参数我们一开始没准备到:objectClass 或 field;
这个是用于我们设置登录 LDAP 服务的时候的条件筛选,比如说,DS 目录中,包含了员工的用户名、邮箱,那么你是可以通过 field 这个参数来配置是使用用户名还是使用邮箱来进行验证的。
也就是说,你可以通过这个参数,来限制使用 STF 的用户只能使用邮箱来登录。

邮箱一般是唯一的,名字可能是重复的。

LDAP 模式启动 STF

说了那么多,最后我们需要启用 ldap 模式的命令是:

~ rethinkdb &
~ stf local --public-ip='本机IP' --auth-type ldap --auth-options '["--ldap-url","$LDAP SERVER URI", "--ldap-bind-dn","$LDAP BIND DN","--ldap-search-dn","$LDAP BASE DN", "--ldap-bind-credentials","$LDAP BIND DN PWD", "--ldap-search-class","user", "--ldap-search-field", "mail"]'

#--auth-type ldap,指定auth的模式为ldap
#--auth-option, 配置ldap启动的参数
#--ldap-search-class='user',筛选目录下的所有用户
#--ldap-search-field='mail',使用mail的方式来获取需要授权的用户

OK,再次打开浏览器输入localhost:7100,会发现被重定向到localhost:7100/auth/ldap页面中去了,愉快得使用域内邮箱密码登录吧。

PS:对了,LDAP BIND DN可以是域内的任何一个用户,只要有权访问 DS 目录的用户就可以了,也就是说只要是你们公司的域内可认证的用户密码,就可以作为公共认证账号,不过并不建议这么使用。

我个人认为这样的平台(前提就是只给内部人使用)是非常适合接入 LDAP 的,无需注册,且能够帮助你后续的二次开发中很好得区分部门关系,用户关系。
比如说后面要开发一个区分部门使用设备的功能,有些设备是给开发用的,有些设备是自动化专用的,测试专用的,那么通过 LDAP 的目录关系,就可以很好得做到区分。
大家玩起来吧,欢迎拍砖。


↙↙↙阅读原文可查看相关链接,并与作者交流