[关闭]
@iamfox 2015-05-06T18:03:21.000000Z 字数 5852 阅读 1768

单点登录方案

方案


1 背景概要

单点登录需求为在两个web系统间实现统一的注册和统一的登录效果,具体情况分为跨域和不跨域两种。

2 不跨域方案设计

2.1 方案介绍和操作接口

在不跨域情况下,如果各子系统session相通,则无必要采用单点登录方案,可以继续使用传统session登录状态判断。
若session各子系统独立,而cookie可以互通,即每个web系统都可以读取到共同的cookie,则采用本方案,通过可重用的jar包,为每个web系统模块提供统一注册和登录功能。
本方案另一个前提是各子系统拥有一个共同访问的数据源,以保存用户信息。如果数据源也完全隔离,可采用跨域方案。

基本业务实体如下:

  1. public class SSOUser {
  2. /**
  3. * 注册时创建一个新用户
  4. */
  5. private String id;
  6. /**
  7. * 用户名
  8. */
  9. private String userName;
  10. /**
  11. * 密文密码
  12. */
  13. private String encryPassword;
  14. /**
  15. * 最后登录时间
  16. */
  17. private Date lastLoginDate;
  18. /**
  19. * 当前登录令牌
  20. */
  21. private String currentLoginToken;
  22. /**
  23. * 该用户的注册来源子系统,可选
  24. */
  25. private String registerFromClient;
  26. /**
  27. * 最后一次登录来源子系统,可选
  28. */
  29. private String lastLoginFromClient;
  30. ...
  31. }

jar包中提供了一个用户操作接口:

  1. public interface SSOUserService {
  2. /**
  3. * 注册时创建一个新用户,ssoUser持久化
  4. * 可选参数为是否允许用户名重复,true为可重复
  5. */
  6. public void createUser(SSOUser, Boolean allowUserNameRepeat);
  7. /**
  8. * 修改用户名
  9. */
  10. public void changeUserName(String ssoUserId, String newUserName);
  11. /**
  12. * 修改用户密文密码
  13. */
  14. public void changeEncryPassword(String ssoUserId, String newEncryPassword);
  15. /**
  16. * 登录,需要用户名,密文密码和登录来源标识,每个web系统对应一个独立的登录来源标识。
  17. * 登录时会更新最后登录时间和当前登录令牌值
  18. */
  19. public SSOUser login(String userName, String encryPassword, String loginClientKey);
  20. /**
  21. * 根据cookie中的登录令牌获取用户
  22. * 能获取到
  23. */
  24. public SSOUser getLoginUser(String currentLoginToken);
  25. /**
  26. * 当发现登录超时时调用登出
  27. */
  28. public String logout(String currentLoginToken);
  29. /**
  30. * 获取用于保存用户登录令牌的cookie字段名常量
  31. */
  32. public String getLoginTokenCookieName();
  33. /**
  34. * 获取用于保存用户最后请求时间戳的cookie字段名常量
  35. */
  36. public String getLastOperateTimeCookieName();
  37. ...
  38. }

jar包中提供一套该接口的默认实现,基于mysql存储基本用户,基于redis存储用户登录信息。
使用该默认实现时,各子系统应采用同一mysql和redis数据源,提供方式为在WEB-INF\classes目录放置一个sso_datasource.properties,内容如下:

  1. mysql_url=
  2. mysql_username=
  3. mysql_password=
  4. redis_ip=
  5. redis_port=

各系统也可以在约定好的情况下集体换用新的实现。

2.2 使用方式和默认实现处理

3 跨域方案介绍

3.1 方案介绍

当各子系统不在同一域名下时,采用本方案。本方案为基于api开放接口及oauth2授权认证的中央通行证方案。
本方案提供一个独立的web应用(下称通行证系统),包括中央注册登录页面、用户授权管理中心,以及运营管理后台。

3.1.1 基本名词解释

英文变量名 中文名 备注
accessToken 临时令牌 一个临时的字符串标识符,有效期较短,用于追踪一个用户跳转到通行证系统进行注册登录流程,然后再通过服务端接口获取流程结果的一个流程追踪标识。每当要开启新注册和登录流程时,应用系统可以向通行证系统申请一个
refreshToken 正式授权令牌 在完成了注册或登录流程后,用accessToken通过服务端接口换取到的正式授权令牌,有很长的有效期,在有效期内可以凭该令牌调用各种通行证系统提供的与用户有关的操作接口(例如查询用户信息)
loginToken 登录令牌 通行证系统在自己的域名下的cookie中写入的,用于追踪用户登录状态的标识,每次用户跳转过来进行登录状态验证时,都会维持该令牌在cookie中继续存在,该令牌与跨域的应用子系统无关,是通行证系统及其同域子系统自用的
  • accessToken每开启一个跨域注册或登录流程时会建一个
  • refreshToken每当通行证系统确认要授予某个应用子系统对某个用户的操作权限时建一个
  • loginToken每当用户成功登录时在通行证系统的cookie中写入一个

3.1.2 来自高可信子系统用户注册流程

高可信子系统是指属于同一公司或团队开发,业务代码安全度完全可信,不会恶意窜改或伪造用户信息,可以持有用户敏感信息,因此该注册流程较为简化,省去了对accessToken的使用,允许用户在本地子系统提供的注册页面中操作并通过服务端接口进行用户信息同步。如果该子系统不打算做自己的注册页完全依赖通行证系统,则流程需要按**3.1.4 **低可信子系统注册流程来走。

  • 在以下所有流程图中,实线箭头代表有页面跳转,虚线箭头代表服务端接口调用。
  • 当涉及到url页面跳转时,url参数中都会带有md5验签机制,参数为明文,参与验签的有不在url中的密钥值。凡是通行证系统提供的url均为https访问。
  • 当涉及到服务端接口请求时,除了验签机制,还有可能增加https证书或者来源ip白名单或者专线等安全机制。
  • 在以下所有流程图中,假设应用子系统域名为www.a.com,通行证系统域名为www.sso.com
Created with Raphaël 2.1.2用户用户应用子系统应用子系统通行证系统通行证系统点击注册链接引导用户在本系统注册页完成注册将用户基本信息包括登录帐号密码提交给通行证系统校验用户信息并保存响应成功或失败原因,成功还会带回授权令牌refreshToken注册结果页面

主要规则
- 通行证系统用户信息中对提交了用户登录名手机号电子邮箱身份证号四种身份信息的用户做分级处理,只提交用户登录名的为认证级别最低的1级用户,提交了身份证号的,为认证级别最高的4级用户。

3.1.3 来自高可信子系统用户登录及验证流程

高可信子系统由于可以进行本地登录,与通行证系统的交互中省去了对accessToken的使用。假如高可信子系统不打算做本地登录,则需要按**3.1.5 **低可信子系统的登录流程来走。

Created with Raphaël 2.1.2用户用户应用子系统应用子系统通行证系统通行证系统点击登录链接将用户重定向到通行证系统,带回调地址从cookie中检查loginToken判断登录状态将用户重定向回调地址,带登录判断结果和refreshToken节点1:如果已登录,在cookie中维护本地登录状态节点1:如果未登录,引导用户本地填写登录信息将用户登录帐号密码提交给通行证系统校验用户信息返回登录验证结果,成功登录时发回授权令牌refreshToken登录结果页面

主要规则
- 通行证系统提供了一个带回调地址参数的验证用户登录状态的url地址,在应用子系统觉得有必要校验用户登录状态时(包括www.a.com的cookie中无登录令牌和认为需要重新核实令牌有效性两种情形),就调用该url跳转到www.sso.com检查登录状态,再等待用户被重定向到回调地址来接收通行证系统的判断结果。

3.1.4 来自低可信子系统用户注册流程

低可信子系统一般是指外部合作伙伴开发的web系统,代码不受控制,要进行严格的安全防范。此时的实现方案基于oauth2授权方式,类似于QQ、支付宝帐号登第三方帐号登录形式。

Created with Raphaël 2.1.2用户用户应用子系统应用子系统通行证系统通行证系统点击注册链接请求一个新的用于引导用户进行注册或登录流程的accessToken将生成的accessToken交给应用子系统将用户引导到通行证系统注册页面,url带上accessToken校验临时令牌有效性后允许用户进行注册告知注册完成拿之前的accessToken去获取注册结果和授权内容如果之前注册成功,将refreshToken发回,accessToken失效

主要规则
- 在该流程中accessToken是用于注册过程追踪的临时令牌,会在url中传输,即使被第三方截取偷走,也无法有效对url请求进行验签,即使能成功通过验签完成了用户注册,也没机会换取到正式令牌refreshToken,因为服务端请求无法伪造。

3.1.5 来自低可信子系统用户登录及验证流程

Created with Raphaël 2.1.2用户用户应用子系统应用子系统通行证系统通行证系统点击登录链接请求一个用于引导用户进行登录流程的accessToken将生成的accessToken交给应用子系统将用户引导到通行证系统登录页面,url带上临时令牌校验临时令牌有效性后允许用户进行登录假如该用户已有loginToken,则不重复登录告知登录成功或失败拿之前的accessToken去获取登录结果和授权内容如果之前登录成功,将refreshToken发回,accessToken失效如果已登录,在cookie中维护本地登录状态登录结果页面
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注