单点登录业务介绍
早期单一服务器,用户认证
缺点:单点性能压力,无法扩展
WEB应用集群,session共享模式
解决了单点性能瓶颈。
问题:
多业务分布式数据独立管理,不适合统一维护一份session数据。
分布式按业务功能切分,用户、认证解耦出来单独统一管理。
cookie中使用jsessionId 容易被篡改、盗取。
跨顶级域名无法访问。
NQ
分布式,SSO(single sign on)模式
解决 :
用户身份信息独立管理,更好的分布式管理。
可以自己扩展安全策略
跨域不是问题
缺点:
认证服务器访问压力较大。
业务流程图
认证中心模块(oauth认证)
数据库表:user_info,并添加一条数据!密码应该是加密的!
在设计密码加密方式时 一般是使用MD5+盐的方式进行加密和解密。
登录功能
业务:
- 用接受的用户名密码核对后台数据库
- 将用户信息写入redis,redis中有该用户视为登录状态。
- 用userId+当前用户登录ip地址+密钥生成token
- 重定向用户到之前的来源地址,同时把token作为参数附上。
生成token
JWT工具
JWT(Json Web Token) 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。
JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。比如用在用户登录上
JWT 最重要的作用就是对 token信息的防伪作用。
JWT的原理,
一个JWT由三个部分组成:公共部分、私有部分、签名部分。最后由这三者组合进行base64编码得到JWT。
公共部分
主要是该JWT的相关配置参数,比如签名的加密算法、格式类型、过期时间等等。
私有部分
用户自定义的内容,根据实际需要真正要封装的信息。
签名部分
根据用户信息+盐值+密钥生成的签名。如果想知道JWT是否是真实的只要把JWT的信息取出来,加上盐值和服务器中的密钥就可以验证真伪。所以不管由谁保存JWT,只要没有密钥就无法伪造。
例如:usrInfo+ip=密钥
base64编码,并不是加密,只是把明文信息变成了不可见的字符串。但是其实只要用一些工具就可以吧base64编码解成明文,所以不要在JWT中放入涉及私密的信息,因为实际上JWT并不是加密信息。
验证功能
功能:当业务模块某个页面要检查当前用户是否登录时,提交到认证中心,认证中心进行检查校验,返回登录状态、用户Id和用户名称。
业务:
- 利用密钥和IP检验token是否正确,并获得里面的userId
- 用userId检查Redis中是否有用户信息,如果有延长它的过期时间。
- 登录成功状态返回。
- 业务模块页面登录情况检查
问题:
1 、由认证中心签发的token如何保存?
2 、难道每一个模块都要做一个token的保存功能?
3 、如何区分请求是否一定要登录? 使用的是拦截器
登录成功后将token写道cookie中
加入拦截器
首先这个验证功能是每个模块都要有的,也就是所有web模块都需要的。在每个controller方法进入前都需要进行检查。可以利用在springmvc中的拦截器功能。
因为咱们是多个web模块分布式部署的,所以不能写在某一个web模块中,可以一个公共的web模块,就是gmall-web-util中。
检验方法是否需要验证用户登录状态
为了方便程序员在controller方法上标记,可以借助自定义注解的方式。
比如某个controller方法需要验证用户登录,在方法上加入自定义的@LoginRequie。
CAS
CAS(Central Authentication Service),是耶鲁大学开发的单点登录系统(SSO,single sign-on),应用广泛,具有独立于平台的,易于理解,支持代理功能。CAS系统在各个大学如耶鲁大学、加州大学、剑桥大学、香港科技大学等得到应用
CAS 的设计目标
(1)为多个Web应用提供单点登录基础设施,同时可以为非Web应用但拥有Web前端的功能服务提供单点登录的功能;
(2)简化应用认证用户身份的流程;
(3)将用户身份认证集中于单一的Web应用,让用户简化他们的密码管理,从而提高安全性;而且,当应用需要修改身份验证的业务逻辑时,不需要到处修改代码。