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 协议的一般化工作流程

image.png

1.4 SAML 协议报文示例

SAML 报文.txt


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登录页面检测当前浏览器的登录状态并执行登录过程

45 IDP完成登录

https://login.microsoftonline.com/ac5e3de9-d2f0-4d57-9341-5a991a023d35/resume

200

完成登录返回SAML Response

6 浏览器请求SPACS页面

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 目录下,关键修改点见下图:

image.png

这张图中配置的内容是需要在本地系统中实现了,详见下文。另:用用服务建议使用域名,否则 IP 变化后需要修改配置文件。

 

image.png

这张图中的内容是 IDP 提供,通常由客户的 IT 配置好之后将对应的信息反馈回来写入配置文件中。

 

image.png

这张图在 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 用户和本地用户映射,并设置密码为固定值,完成后台登录。

 

4 参考资料

https://github.com/MicrosoftDocs/azure-docs/blob/main/articles/active-directory/saas-apps/sonarqube-tutorial.md

https://github.com/SAML-Toolkits/java-saml

https://help.aliyun.com/document_detail/174224.html