exchange自带owa登录,ad账号密码是必填项。登录方式单一,不能和企业内SSO系统融合,用户忘记密码、密码过期等会带来很多不便
目标是实现多种方式登录exchange owa,例如微信扫码,短信验证码,OTP,接入外部单点登录等。首先要解决登录exchange owa必须要使用ad账号密码这个问题。
这里参考了 ,我们使用adfs+saml2协议来实现
具体实现
1、接入ADFS登录
exchange owa接入ADFS登录可以参考 ,官网描述的步骤很详细,按照一步一步操作即可完成接入。
接入后可以使用adfs自带的登录完成exchange owa登录认证,此时我们已经实现了替换exchange owa自带的登录
但是还是没有摆脱必须输入ad账号密码的步骤
2、使用pysaml2库实现saml2协议
参考小米的adfs+cas的解决思路, 大概了解了下cas的功能,ADFS作为cas的SP,cas作为ADFS的IDP,cas配置为ADFS的“声明提供方”,cas使用saml2协议完成ADFS的接入。
但是cas作为比较成熟的解决方案,本身还是比较“重”的,我们仅仅需要一个saml2协议的实现,并不需要一整套cas系统
在github里搜索到了一个库,pysaml2 ,是python实现的saml2协议的库。这个库自带了一个非常简单的示例,让我们可以用一条命令运行IDP,
如果你看到和我一样的提示,说明运行成功了
[root@ityw-centos-vdi idp2]# python idp.py idp_conf [2021-06-11 01:07:11,388] [DEBUG] [saml2.assertion.__init__] policy restrictions: None [2021-06-11 01:07:11,389] [DEBUG] [saml2.assertion.__init__] policy restrictions: None [2021-06-11 01:07:11,389] [DEBUG] [saml2.assertion.__init__] policy restrictions: {'default': {'lifetime': {'minutes': 15}, 'attribute_restrictions': None, 'name_form': 'urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified', 'entity_categories': None}} [2021-06-11 01:07:11,427] [INFO] [saml2.idp.<module>] Server starting IDP listening on localhost:8088
要将我们的IDP接入adfs,要进行一些配置。
pki
目录下的 mycert.pem 和 mykey.pem 文件,分别对应我们证书的.crt和.key,要将我们自己的证书内容覆盖上去
pysaml2-master\tools
目录下的 make_metadata.py 文件复制到 pysaml2-master\example\idp2
目录里
idp.py
文件里的 PASSWD 配置是账号和密码,我们新增一个 test01 账号,密码设置的和AD密码不一致
PASSWD = { "test01": "test01", }
目录复制到 pysaml2-master\example\idp2
idp_conf.py
文件
我们新增一条导入
from saml2.xmldsig import SIG_RSA_SHA256, DIGEST_SHA256
HOST ,我们配置下idp的host地址(要在DNS做对应A记录)
HOST = 'saml.testyunwei.com'
CONFIG.service.idp.policy.default.name_form 值改为
"name_form": "urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"
CONFIG.service.idp.policy.default.entity_categories 字段删除
CONFIG.service.idp.name_id_format 值改为
`"name_id_format": ["urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"]
CONFIG.service.idp 新增四个值
"sign_assertion": True, "sign_response": True, 'signing_algorithm': SIG_RSA_SHA256, 'digest_algorithm': DIGEST_SHA256,
CONFIG.metadata.local 值改为
"local": [full_path("pki/sp.xml")]
CONFIG.attribute_map_dir 取消注释,并且值改为
"attribute_map_dir": "./attributemaps"
idp_user.py 文件我们新增一个users用户信息
USERS = { "test01": { "upn": "test01@testyunwei.com" }, }
我们访问 ADFS的sp终结点获取sp.xml 文件
https://adfs.testyunwei.com/FederationMetadata/2007-06/FederationMetadata.xml
把下载下来的xml文件重命名为sp.xml 复制到 pysaml2-master\example\idp2
目录下
这时,我们再重新运行IDP
python make_metadata.py idp_conf.py > idp.xml python idp.py idp_conf
看到还是刚才的运行成功的记录,只不过监听host变了
[root@ityw-centos-vdi idp2]# python idp.py idp_conf [2021-06-11 02:00:49,005] [DEBUG] [saml2.assertion.__init__] policy restrictions: None [2021-06-11 02:00:49,005] [DEBUG] [saml2.assertion.__init__] policy restrictions: None [2021-06-11 02:00:49,005] [DEBUG] [saml2.assertion.__init__] policy restrictions: {'default': {'lifetime': {'minutes': 15}, 'attribute_restrictions': None, 'name_form': 'urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified', 'entity_categories': None}} [2021-06-11 02:00:49,043] [INFO] [saml2.idp.<module>] Server starting IDP listening on saml.testyunwei.com:8088
我们在ADFS上添加一个声明提供方,从url导入idp元数据:https://saml.testyunwei.com:8088/idp.xml,然后无脑下一步即可,中间有警告可以忽略。
我们配置owa和ecp的依赖方信任,还有我们刚才新增的声明提供方信任,都需要配置声明规则完成转换,我们只用upn一个属性就可以定位到具体用户
后记
到这里dome基本已经实现,认证体系由IDP实现,脱离了ad账号密码完成exchange owa登录
下篇研究下 pysaml2 原理