SAML(Security Assertion Markup Language)是一个 XML 框架,也就是一组协议,可以用来传输安全声明。比如,两台远程机器之间要通讯,为了保证安全,我们可以采用加密等措施,也可以采用 SAML 来传输,传输的数据以 XML 形式,符合 SAML 规范,这样我们就可以不要求两台机器采用什么样的系统,只要求能理解 SAML 规范即可。
其核心是: IDP和SP通过用户的浏览器的重定向访问来实现交换数据。
SP向IDP发出SAML身份认证请求消息,来请求IDP鉴别用户身份;IDP向用户索要用户名和口令,并验证其是否正确,如果验证无误,则向SP返回SAML身份认证应答,表示该用户已经登录成功了,此外应答中里还包括一些额外的信息,来却确保应答被篡改和伪造。
本人在网上找了一张图片,感觉比较好的说明了saml2.0的SSO认证的过程:
本人是python研发工程师,所以以python3为例,说明我是如何接入我们公司的SSO的。
本人使用的是python3-saml库
1.准备所需要的json数据
req = {
"idp": {
"entityId": data["sso"]["login-url"],
"singleSignOnService": {
"url": data["sso"]["login-url"]
},
"singleLogoutService": {
"url": "{0}?service={1}".format(
data["sso"]["logout-url"], url)
}
},
"sp": {
"entityId": url,
"singleSignOnService": {
"url": data["sso"]["login-url"]
},
"assertionConsumerService": {
"url": url
},
"singleLogoutService": {
"url": "{0}?service={1}".format(
data["sso"]["logout-url"], url)
},
"NameIDFormat": "urn:oasis:names:tc:SAML:2.0:assertion"
}
}
将登录认证服务器的请求地址写到idp和sp的singleSignOnService,将登录后跳转的地址写到sp的entityId和assertionConsumerService,将登出认证服务器的地址和登录后要跳转的地址写到sp和idp的singleLogoutService
2.使用python3-saml库
以django为例演示登录
def login(request):
one_login = OneLogin_Saml2_Settings(req)
login = OneLogin_Saml2_Authn_Request(one_login)
result = quote(login.get_request())
return HttpResponseRedirect(result)
之后跳转至SSO的统一登录界面,然后输入用户名和密码进行验证。校验通过后,登录认证服务器会发送POST请求将用户名等信息通过base64加密的方式传给你,你解析做处理。
以django为例演示登出
def logout(reqeust):
one_login = OneLogin_Saml2_Settings(req)
logout_request = OneLogin_Saml2_Logout_Request(one_login)
parameters = {'SAMLRequest': logout_request.get_request()}
uri = logout_url + '?service={}'.format(domain + address)
logout_url = OneLogin_Saml2_Utils.redirect(uri, parameters, True)
return HttpResponseRedirect(logout_url)
之后跳回SSO统一登录界面。