SSO简介
单点登录(SingleSignOn,SSO),就是通过用户的一次性鉴别登录。当用户在身份认证服务器上登录一次以后,即可获得访问单点登录系统中其他关联系统和应用软件的权限,同时这种实现是不需要管理员对用户的登录状态或其他信息进行修改的,这意味着在多个应用系统中,用户只需一次登录就可以访问所有相互信任的应用系统。这种方式减少了由登录产生的时间消耗,辅助了用户管理,是目前比较流行的
实现步骤:
1.当用户输入用户名和密码之后点击提交按钮.将数据传给JT-WEB服务器.
2.JT-WEB利用RPC方式访问JT-SSO 校验数据是否有效.
3.如果校验的数据准备无误,之后将用户信息保存到Redis中. key 使用uuid, value使用userJSON. 并且设定7天超时.
4.JT-SSO 将服务器数据返回给JT-WEB服务器.(如果用户名和密码错误的则返回为null即可).
5.JT-WEB服务器将数据保存到Cookie中.(要求实现Cookie共享).
编辑UserController
/**
* url:Request URL: http://www.jt.com/user/doLogin?r=0.7578354515890049
* 参数:{password:_password,username:_username}
* 返回值结果 SysResult
* 需求 将cokkie名称为"JT_TICKET"数据输出到浏览器,七天超时
* Cookie特点:
* 1.浏览器中只能查看当前网址的Cookie信息
* 2.doMain表示Cookie共享策略
* doMain:www.jd.com 当前Cookie只能在当前域名中使用
* doMain:.jd.com 当前Cookie时共享的可以再域名为jd.com结尾的域名中共享
*/
@RequestMapping("/doLogin")
@ResponseBody
public SysResult doLogin(User user,HttpServletResponse response){
//完成用户登录操作,获取ticket秘钥信息
String ticket = dubboUserService.doLogin(user);
if (StringUtils.isEmpty(ticket)){
//如果为空,则说明用户名密码有问题
return SysResult.fail();
}
//1.新建cookie对象
Cookie cookie = new Cookie("JT_TICKET", ticket);
//2.设置存在时间,单位为秒,用户关闭回话时 Cookie删除(-1),立即删除Cookie(0)
cookie.setMaxAge(7*24*60*60); //7天销毁
//设置Cookie共享策略(jt.com的玉明珠共享)
cookie.setDomain("jt.com");
cookie.setPath("/");
response.addCookie(cookie);
return SysResult.sussess();
}
编辑User Service
**
* 目的: 校验用户信息是否有效并且实现单点登录操作.
* 步骤:
* 1.校验用户名和密码是否正确(密码明文转化为密文)
* 2.查询数据库检查是否有结果
* 3.如果有结果,则动态生成TICKET信息(uuid),将user对象转化为JSON
* 4.将数据保存到redis中,并且设定超时时间.
* 5.返回当前用户登录的密钥.
*
* @param user
* @return
*/
@Override
public String doLogin(User user) {
String passwork = user.getPassword();
String md5Pass = DigestUtils.md5DigestAsHex(passwork.getBytes());
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username", user.getUsername())
.eq("password", md5Pass);
//获取的是用户的全部记录 (包含涉密信息)
User userDB = userMapper.selectOne(queryWrapper);
//校验数据是否有效
if( userDB == null){
//用户名和密码错误
return null;
}
//如果程序执行到这里,说明用户名和密码正确的. 开启单点登录流程
String ticket = UUID.randomUUID()
.toString().replace("-", "");
//脱敏处理 余额/密码/手机号/家庭地址
userDB.setPassword("123456你信不???");
String userJSON = ObjectMapperUtil.toJSON(userDB);
//操作时保证原子性
jedisCluster.setex(ticket, 7*24*60*60, userJSON);
return ticket;
}
用户信息回显
当用户登录成功之后,需要在顶部实现数据的回显. 根据ticket获取用户用户的JSON信息.
/**
* 完成回显用户名称
* url地址: http://sso.jt.com/user/query/494fcc9ac98e49bc98baffd6d8fc6802?callback=jsonp1597999688824&_=1597999688872
* 参数: ticket信息
* 返回值: SysResult对象(userJSON)
* */
@RequestMapping("/query/{ticket}")
public JSONPObject findUserByTicket(@PathVariable String ticket,String callback){
String userJSON = jedisCluster.get(ticket);
if(StringUtils.isEmpty(userJSON)){
//ticket有误.返回错误信息即可
return new JSONPObject(callback, SysResult.fail());
}else{
return new JSONPObject(callback, SysResult.success(userJSON));
}
}