SAML 单点登录集成方案和实现
1 基础知识说明
1.1 SAML 介绍
SAML 全称是安全断言标记语言(Security Assertion Markup Language)是一个基于 XML 的开源标准数据格式。用于在不同的安全域之间交换认证和数据授权。在 SAML 标准定义了身份提供者(IDP)和服务提供者(SP),这两者构成了前面所说的不同的安全域。 SAML 是 OASIS 组织安全服务技术委员会的产品。
SAML 解决的最重要的需求是 Web 端应用的单点登录(SSO)。
1.2 SAML 协议的角色
SAML 协议主要有三个角色:
SP(Service Provider):向用户提供服务的 web 端应用。
IDP(Identity Provide):向 SP 提供用户身份信息
用户:通过登录 IDP 获取身份断言,并向 SP 返回身份断言来使用 SP 提供的服务。
1.3 SAML 协议的工作流程
SAML 协议的一般化工作流程
1.4 SAML 协议报文示例
2 项目案例
2.1 协议角色说明
康明斯项目需要 MES 集成微软 Azure AD SSO 服务,则这个过程中,MES 是 SP,微软 Azure AD 是 IDP, 用户则是 MES 系统的用户,但是通过 Azure AD 认证。
2.2 项目方案介绍
MES 系统的 session 和用户本质上还是本地管理的方式,只是在 MTS_USER 表中维护了 MES 本地用户和 SSO 用户的对应关系,在根据 SAML 协议完成 SSO 登录后,从 SAML 响应中解析出 SSO 用户,以该用户的本地对应的本地用户进行一次用户不感知的本地登录。
2.3 项目流程实例说明
步骤 |
请求内容 |
请求响应 |
技术说明 |
1 用户请求访问SP |
http://localhost:8080/prj-cummins/index.action |
302 |
重定向到SP登录页面内 |
1.1 SP返回登录页面(可选) |
http://localhost:8080/prj-cummins/login.action |
200 |
这里为了兼容本地登录,保留了登录页面 |
2 SP生成SAML请求并重定向到IDP |
http://localhost:8080/prj-cummins/dologin.jsp |
302 |
重定向到SP发起SSO的页面 |
3浏览器重定向 |
https://login.microsoftonline.com/ac5e3de9-d2f0-4d57-9341-5a991a023d35/saml2 |
200 |
IDP登录页面检测当前浏览器的登录状态并执行登录过程 |
4、5 IDP完成登录 |
https://login.microsoftonline.com/ac5e3de9-d2f0-4d57-9341-5a991a023d35/resume |
200 |
完成登录返回SAML Response |
6 浏览器请求SP的ACS页面 |
http://localhost:8080/prj-cummins/acs.jsp |
200 |
SP获取并解析SAML响应 |
6.1 SP完成本地登录(可选) |
http://localhost:8080/prj-cummins/j_spring_security_check |
302 |
这里为了兼容现有功能,将SSO映射为本地用户又做了一次隐藏的本地登录 |
7 SP登录完成,请求主页 |
http://localhost:8080/prj-cummins/login.action |
200 |
|
2.4 登录过程视频介绍
3 技术实现
3.1 组件引入
引入 java-saml 组件,pom.xml 直接增加依赖即可。
com.onelogin
java-saml
2.9.0
** 注意:** 引入后可能导致 commons-lang3 和 commons-codec 组件的版本冲突,需要使用 saml 组件依赖的版本。
3.2 配置 saml
将 onelogin.saml.properties 文件拷贝到 resources 目录下,关键修改点见下图:
这张图中配置的内容是需要在本地系统中实现了,详见下文。另:用用服务建议使用域名,否则 IP 变化后需要修改配置文件。
这张图中的内容是 IDP 提供,通常由客户的 IT 配置好之后将对应的信息反馈回来写入配置文件中。
这张图在 Azure AD 中配置好应用单点登录后提供的信息。
3.3 主要代码修改点
1、在项目中实现 dologin.jsp 和 asc.jsp 页面,前者用于向 IDP 发起 SSO 登录,后者用于 SSO 登录成功后重新向。
2、修改产品 login.jsp 和 index-desktop.jsp 页面,增加访问 dologin.jsp 的按钮。
3、在 asc.jsp 中增加隐藏表单,并在页面加载时提交 j_spring_security_check 请求。
4、修改 UsernamePasswordAuthenticationFilter 和 UserDetailsServiceImpl,当请求来源是单点登录时,实现 SSO 用户和本地用户映射,并设置密码为固定值,完成后台登录。