前言: 单点登录其实是一个概念,主要是为了解决一次登录,多系统(本系统或外部系统)之间不需要重复登录的问题,就目前来说,主流的解决方案针对业务场景分为3个方向:
1: 同一公司,同父域下的单点登录解决方案.
如[http://map.baidu.com] [http://www.baidu.com] [http://image.baidu.com]
基于cookie开源项目代表: JWT(https://jwt.io/);
需要注意jwt token存储在哪里的问题:
首先我们要明确csrf和xss两种漏洞的不同之处:
2: 同一公司,不同域下的单点登录解决方案.
如[http://www.taobao.com] [http://www.tmall.com]
基于中央认证服务器开源项目代表:CAS(https://github.com/apereo/cas); https://www.apereo.org/projects/cas
Request1
【第一步】终端第一次访问CAS—Client1,AuthenticationFilter会截获此请求:
1、首先,检测本地Session没有缓存有用户信息;
2、然后,检测到请求信息中没有ST;
3、所以,CAS—Client1将请求重定向到CAS—Server,并传递 Service (也就是要访问的目的资源地址,以便登录成功过后转回该地址),例:【https://cas:8443/cas/login?service=http0%3A8081%2F】
【第二步】终端第一次访问CAS—Server:
1、CAS—Server检测到请求信息中没有TGC,所以跳转到自己的登录页;
2、终端输入用户名、密码登录CAS—Server,认证成功后,CAS—Server会生成登录票据—TGT(集成了用户信息与ST),并随机生成一个服务票据—ST 与 CAS会话标识—TGC。
TGT实际上就是Session,而TGC就是这标识这个Session存到Cookie中的SessionID;ST即,根据Service生成Ticket。
3、然后,CAS—Server会将Ticket加在url 后面,然后将请求redirect 回客户web 应用,例如URL为【http://192.168.1.1:8081/web1/?ticket=ST-5-Sx6eyvj7cPPCfn0pMZ】
【第三步】这时,终端携带ticket再次请求CAS—Client1:
1、这时客户端的AuthenticationFilter看到ticket 参数后,会跳过,由其后面的TicketValidationFilter 处理;
2、TicketValidationFilter 会利用httpclient工具访问cas 服务的/serviceValidate 接口, 将ticket 、service 都传到此接口,由此接口验证ticket 的有效性,即向CAS—Server验证ST的有效性。
3、TicketValidationFilter如果得到验证成功的消息,就会把用户信息写入web 应用的session里。至此为止,SSO 会话就建立起来了
Request2
上面说SSO 会话已经建立起来了,用户在同一浏览器里第二次访问此web 应用(CAS—Client1)时,AuthenticationFilter会在session 里读取到用户信息,这就代表用户已成功登录,就不会CAS 认证了。
Request3
【第一步】与Request1是完全一样的,如下:终端第一次访问CAS—Client2,AuthenticationFilter会截获此请求:
1、首先,检测本地Session没有缓存有用户信息;
2、然后,检测到请求信息中没有ST;
3、所以,CAS—Client1将请求重定向到CAS—Server,并传递 Service (也就是要访问的目的资源地址,以便登录成功过后转回该地址),例:【https://cas:8443/cas/login?service=http0%3A8081%2F】
【第二步】然后,终端第二次访问CAS—Server:此时,Request中会带有上次生成的TGC,然后根据TGC(SessionID)去查找是否有对应的TGT(Session),如果有,代表此用户已成功登录过,所以此时用户不必再去登录页登录(SSO的体现),而CAS—Server会直接用找到的TGT签发一个ST,然后重定向到CAS—Client2,剩下的如Request1中的【第三步】就完全一样了。
3: 不同公司之间,不同域下的 第三方登录功能实现.
如第三方网站支持qq登录,微信登录,微博登录等;
基于OAuth2.0协议各大公司自己的支持;
没有用过,不太了解,不过微信公众号开发获取用户授权好像就是oauth2.0,那首先用户授权登录获取一个到code,拿到code换取access_token,然后就能使用access_token来获取用户信息了