单点登陆流程
一、单点登陆流程
1. 单点登陆流程
- SP1: 系统1,客户端(请求SCA服务)
- SP2: 系统2,客户端(请求SCA服务)
- SCA: SSO认证服务中心,服务端(为SP提供服务)
对于SP1
、SP2
和SCA
服务可以理解为三个不同的系统,域名也不一样。
1.1 时序图
单点登陆如下:
1.2 实现步骤
(1)用户访问SP1
站点需授权页面,例如:http://sp1.com/admin
(2)浏览器请求SP1服务
(3)SP1
站点判断是否存在局部会话。会话存在,返回用户响应;会话不存在,携带appId
(应用id)和redirectUrl
(用户请求地址)重定向到SCA
的默认服务http://sca.com/sca/sps/index
(具体请参考接口规范文档);
(4)局部会话不存在,返回浏览器重定向
(5)重定向SCA
默认服务,http://sca.com/sca/sps/index?appId=1&redirectUrl=http%3a%2f%2fsp1.com%2fadmin
(6)SCA
不存在全局会话,说明用户还未登陆,跳转到SCA的统一登陆页面,已便用户填写用户名和密码。
(7)返回SCA登陆页面
(8)浏览器向用户展示登陆页面
(9)用户填写用户名和密码
(10)浏览器拿着用户名和密码提交用户信息
(11)验证用户名和密码,判断是否用户是否需要进行二次认证(后面有详细的二次认证说明)。认证成功后建立全局会话,生成token,通知浏览器重定向到SP1的接收token地址(需要进行开发和配置,例如http://sp1.com/receiveToken
,具体操作请参考接口文档),并把token
和redirectUrl
当作参数传递。
(12)保存全局Cookie
(13)重定向到SP1接收token服务,http://sp1.com/receiveToken?token=xx.yyy.zz&redirectUrl=http://10.10.10.10/requestUrl
(14)解析token(此处解析token使用JWT令牌,具体操作请参照JWT集成流程),创建局部会话和设置自己的Cookie。
(15)SP1重定向到原请求地址http://sp1.com/admin
,跳转至操作(2),因为已创建局部会话,所以直接返回请求数据。
(16)返回请求页面
(17)浏览器向用户展示最开始请求页面
(18)用户访问SP2
站点需授权页面,例如:http://sp2.com/admin
(19)浏览器请求SP2
服务
(20)SP2
并没有局部会话,携带appId和redirectUrl重定向至SCA默认服务
(21)返回请求浏览器重定向
(22)重定向请求http://sca.com/sca/sps/index?appId=2&redirectUrl=http%3a%2f%2fsp2.com%2fadmin
(23)SCA已存在全局会话,直接颁发token,重定向回SP2接收token地址
(24)请求SP2接收地址,http://sp2.com/receiveToken?token=xx.yyy.zz&redirectUrl=http%3a%2f%2fsp2.com%2fadmin
(25)解析token,创建局部会话和Cookie。
(26)SP2
重定向原请求地址http://sp2.com/admin
,因为(25)上一布已经创建了局部会话,所以直接返回请求数据。
(27)返回请求页面
(28)浏览器向用户展示页面
1.3详细时序图
详细时序图如下:
2. 二次认证流程
当二次认证的用户登录时,需要进行短信二次认证
2.1 时序图
2.2实现步骤
(1)~(10)…
(11)SCA验证用户需要二次认证
(12)重定向二次认证页面
(13)浏览器向用户展示页面
(14)用户发送并填写手机短信验证码
(15)浏览器提交验证码请求SCA服务
(16)SCA服务校验验证码是否正确。正确生成全局会话并颁发token。
(17)保存Cookie并重定向到SP的接收token地址
(18)~(25)…
二、第三方对接
1.添加应用
- 登陆sca管理系统,点击”添加应用“,输入配置信息。
- 查看应用详情,将生成的token私钥、数据私钥、签名私钥和应用ID配置在自己的系统中。
2.开发接口
需要有一个sca认证通过后生成token重定向回来的控制器,并将其url绝对路径配置到sca的管理系统中。需要集成sca-jwt-sdk的jar包,里面有生成签名,解密数据以及解析token的工具类可以直接调用,具体使用方式可以参考jwt集成)。
3.开发过滤器/拦截器
主要用于校验用户是否已登陆存在session。如果未登陆移交sca处理。同时修改过滤/拦截规则,开放接收token的地址。
4.调用接口
调用sca服务提供的接口,具体请参考sca接口规范。
5.开发逻辑
(1)第三方在用户访问时拦截请求,先判断用户的session是否存在,不存在则重定向给sca站点处理。sca提供了统一处理地址http://SCA域名/sca/sps/index
,需要携带appId
应用id和redirectUrl
用户访问地址。sca会对用户进行统一认证,认证通过会将token
和redirectUrl
重定向回第三方的接收地址。
(2)第三方需要开发接收token的控制器,例如http://127.0.0.1:8080/sp1/sso/index
,并将其url绝对路径配置在sca管理系统中。同时在拦截器配置中开放此路径,以免进入死循环。
三、JWT集成
1.简介
整个插件式JWT的流程,是接收SCA向callback url发出的token参数(即JWT令牌),并使用我们提供的(或第三方提供的)JWT解密库/方法对jwt进行解析,并验证身份。 你可以自己按照这个逻辑完成代码,也可以在我们提供的代码/demo的基础上进行修改
2.实现原理
- 通过浏览器登录集成的SCA系统后,确认要单点登录的应用,发起SSO请求到SCA系统。
- SCA系统生成token令牌发送到业务应用。
- 你的应用获取到token令牌,用我们提供的插件或方法解析token令牌,解析成功获取到用户信息并验证后,重定向进行登录;如果解析失败则拒绝登录。
3.配置环境
JDK1.7以上
请下载sca-jwt-sdk,下载下来的.jar包含了我们封装好的帮助方法,jar包请引入你开发的应用中。
在申请JWT应用步骤的结尾获取到的publicKey
4.接收令牌
//token 是sso站点请求时带来的,在body里获取,此示例代码是获取用户信息。
//JWT SSO
@RequestMapping(value = "/receiveToken")
public String ssoUrl(@RequestParam("token") String token, @RequestParam("redirectUrl") String redirectUrl) {
//1.接收方法为GET方式,参数名为token,redirectUrl
//2.解析token
//成功:创建局部会话,重定向到用户请求页面
//失败:重定向回sca的默认地址
}
5.解析令牌
publicKey: 解析令牌的过程中,我们会使用到应用的publicKey。请在 JWT应用 -> 详细 中将publicKey字段对应的内容拷贝并存储起来。
//1.使用公钥,解析token
// 使用publicKey解密上一步获取的token令牌
//2.获取用户信息
LoginUserInfo user = JwtTokenUtil.getUserInfoFromToken(token, publicKey);
if (user == null) {
LOG.warn("Retrieve SSO user failed" , e);
return "error";
}
//3.判断用户名是否在自己系统存在isExistedUsername()方法为业务系统自行判断数据库中是否存在
if (isExistedUsername(user.getName())) {
//4.如果存在,登录成功,返回登录成功后的页面
User spUser = userService.updateLoginTimes(user.getName());
request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, saveSecurity(spUser));
//5.重定向用户请求地址redirectUrl
return "redirect:redirectUrl";
} else {
//7.如果不存在,返回登录失败页面,提示用户不存在
model.addAttribute("error", "username { " + user.getName() + " } not exist");
return "error";
}
//jar包中提供了获取应用列表的方法
List<AppInfo> appInfoList = JwtTokenUtil.getAppInfoList(token, publicKey);
6.生成签名
在访问SSO service接口时,部分接口要求传入签名,重要数据需要加密才能访问,在提供的sca-jwt-sdk包中提供了生成签名的工具类,使用方式如下:
// 以调用校验token接口为例
Map<String, Object> params = new TreeMap<String, Object>();
params.put("token", token);
params.put("appId", appId);
long timeStamp = new Date().getTime();
// 生成签名sign(signPrivateKey,是创建应用时生成的签名私钥)
String sign = SignUtil.generateSign(signPrivateKey, timeStamp, params);
ResultData resultDate= scaSpsApiConsumer.veryfyToken(token,appId, sign, timeStamp);
}
四、接口规范
1.SCA站点重定向地址
地址说明
主要用于保存sso站点自己的cookie和session,同时用来校验用户是否已经登录。未登录跳转至SCA的统一登陆认证页面。若已经登录则sso站点会重定向回SP的接收token地址,同时带着token和redirectUrl。例如用户请求sp1站点的登录地址为: http://sp1.com/admin, 重定向回来的格式就为: http://sp1.com/receiveToken?token=xxxxxx&redirectUrl=http://sp1.com/admin
重定向地址
正式环境URL:https://sca.cncecyc.com/sca/sps/index?appId=1&redirectUrl=http://aa.bb.cc/dd 测试环境URL:http://172.23.5.1:8015/sca/sps/index?appId=1&redirectUrl=http://aa.bb.cc/dd 开发环境URL:http://172.23.4.47:8015/sca/sps/index?appId=1&redirectUrl=http://aa.bb.cc/dd
参数说明:
参数名 | 参数选项 | 备注 |
---|---|---|
appId | 必须 | 应用ID(配置应用生成ID) |
redirectUrl | 必须 | 用户最开始请求地址,必须是携带http或者https的绝对路径 |
2.SP站点重定向接收地址
地址说明
主要用于接收由SCA重定向过来进行token的接收验证于解析。获取token后首先去sca的验证token的接口进行token的验证。如果返回成功,进行解析token,成功后保存自己的cookie和session,然后重定向至redirectUrl进行用户最开始的请求。验证结果返回失败,则重定向至SCA进行处理。未登录跳转至SCA的统一登陆认证页面。
注意:开发完控制器后需要在SCA管理系统中配置SSO_URL
字段接收处理token的地址(必须是绝对路径),同时在自己系统中的拦截器中开放此路径。
重定向地址(这里只是举例,具体已自己开发为主)
正式环境URL:https://sp1.cncecyc.com/receivoToken?token=1&redirectUrl=http://aa.bb.cc/dd 测试环境URL:http://172.23.5.1:8015/receivoToken?token=1&redirectUrl=http://aa.bb.cc/dd 开发环境URL:http://172.23.4.47:8015/receivoToken?token=1&redirectUrl=http://aa.bb.cc/dd
参数说明:
参数名 | 参数选项 | 备注 |
---|---|---|
token | 必须 | sca生成的jwt |
redirectUrl | 必须 | 用户最开始请求地址路径 |
3.sca站点退出登录
地址说明
主要用于删除sso站点自己的cookie和session,并重定向回登陆站点并带着返回码。
重定向地址
正式环境URL:https://sca.cncecyc.com/sca/sps/logout?appId=2&redirectUrl=http://aa.bb.com/dd 测试环境URL:http://172.23.5.1:8015/sca/sps/logout?appId=2&redirectUrl=http://aa.bb.com/dd 开发环境URL:http://172.23.4.47:8015/sca/sps/logout?appId=2&redirectUrl=http://aa.bb.com/dd
参数说明:
参数名 | 参数选项 | 备注 |
---|---|---|
appId | 必须 | 应用ID(配置应用生成ID) |
redirectUrl | 必须 | 重定向地址(用户退出前所访问的url) |
4.返回码表
返回码(code) | 描述 |
---|---|
1 | 成功 |
2 | token已删除 |
-100 | 账号或密码错误 |
-101 | token错误 |
-102 | token已过期 |
-103 | 签名错误 |
-104 | 应用配置未正确 |
-105 | 应用未找到或未配置私钥 |
-106 | 生成重定向地址错误 |
-107 | 目标地址URL格式错误 |
-108 | 查询用户登陆信息失败 |
-109 | 生成token信息失败 |
-200 | 需要二次认证 |
-201 | 验证码发送失败 |
-202 | 验证码错误或已过期 |
-203 | SESSION异常 |
-204 | 手机号码为空 |