开发语言:Python
云端SSO方式:用户SSO
起初,是为了腾讯云开启用户SSO来接入企业SSO,但是腾讯云的文档,真是一言难尽,于是就去找阿里云的文档做参考,阿里云的文档就好一些,不过,想成功接入,还是不够。于是在网上找到【使用python构建伪IdP实现SAML接入阿里云访问控制SSO】这篇文章,最终成功实现了腾讯云接入内部SSO的功能。
本文会提供阿里云与腾讯云的接入方式,总体区别不大,只有稍微有些不同,遇到的时候会说。
第一步:生成IDP密钥对
密钥对主要作用使用公钥生成 idp 元数据文档 提供给 SP 做信任,然后就是使用公私钥对 IDP 响应的断言部分XML做签名。
脚本参考 generate_key.sh
,使用原作者所提供的,并未做更改。
#!/bin/bash
#
# Usage: mk_keys.sh [prefix]
#
# Makes two files: private_key.pem and certificate.pem, optionally prefixed
# with the first positional argument.
#
# Thanks to http://robinelvin.wordpress.com/2009/09/04/saml-with-django/
if [[ $# -ge 1 ]] ; then
prefix="${1}-"
else
prefix=""
fi
private_key="${prefix}private-key.pem"
certificate="${prefix}certificate.pem"
echo "** This utility will create the OpenSSL key and certificate for the keys app."
type -P openssl &>/dev/null || {
echo "** This utility requires openssl but it's not installed. Aborting." >&2;
exit 1;
}
echo "** Starting OpenSSL Interaction ------------------------------------"
openssl genrsa > "${private_key}"
openssl req -new -x509 -key "${private_key}" -out "${certificate}" -days 3650
echo "** Finished OpenSSL Interaction ------------------------------------"
echo "** These keys were created:"
ls -l -- "${private_key}" "${certificate}"
echo "** Finished."
第二步:生成IDP元数据文档
主要提供数据:idp entity id, 公钥;如下示例中:
EntityID:http://127.0.0.1:8000/sso/saml/login
公钥(太长已简化):MIIDazCCAlOgAwIBAgIUGDDqjlsgN
<?xml version="1.0" encoding="UTF-8"?>
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" entityID="http://127.0.0.1:8000/sso/saml/login">
<IDPSSODescriptor WantAuthnRequestsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<KeyDescriptor use="signing">
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIIDazCCAlOgAwIBAgIUGDDqjlsgN</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</KeyDescriptor>
<KeyDescriptor use="encryption">
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIIDazCCAlOgAwIBAgIUGDD</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</KeyDescriptor>
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://127.0.0.1:8000/sso/saml/login"/>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://127.0.0.1:8000/sso/saml/login"/>
</IDPSSODescriptor>
<Organization>
<OrganizationName xml:lang="en">Mouse Tech</OrganizationName>
<OrganizationDisplayName xml:lang="en">Mouse Tech</OrganizationDisplayName>
<OrganizationURL xml:lang="en">http://127.0.0.1:8000</OrganizationURL>
</Organization>
</EntityDescriptor>
将内容保存为.xml后缀文件,上传到腾讯云或者阿里云即可。
第三步:用Flask实现IDP响应
下面会分别给出阿里云与腾讯云的代码示例,其中不同的地方:
- 跳转到IDP登录的时候,腾讯云用的POST请求,阿里云采用的是GET请求且阿里云的请求需要进行解压缩。
- IDP登录后的跳转腾讯云页面与方式:如您需要指定跳转腾讯云的其他页面,可使用 cloud.tencent.com/login/saml?… 形式指定,其中 xxxx 为需要指定的地址,需要做 urlencode。