单点登录实现:一次登录,到处运行

单点登录:一次登录,到处运行
举个场景,假设我们的系统被切割为N个部分:商城、论坛、直播、社交…… 如果用户每访问一个模块都要登录一次,那么用户将会疯掉, 为了优化用户体验,我们急需一套机制将这N个系统的认证授权互通共享,让用户在一个系统登录之后,便可以畅通无阻的访问其它所有系统。
单点登录——就是为了解决这个问题而生!
简而言之,单点登录可以做到: 在多个互相信任的系统中,用户只需登录一次,就可以访问所有系统。
比如说校园论坛项目,原始模块可能有学习模块,娱乐模块,但是又有需求需要添加一个考研保研模块,这个时候怎么办呢?
在这里插入图片描述

单点登录就出来了,只需要在门户网站登录后,即可访问系统各个模块。

一、技术调研

实现单点登录可以有很多种方案,常见的有以下几种:

1,cookie+session

什么是cookie

  • HTTP 是无状态的协议(对于事务处理没有记忆能力,每次客户端和服务端会话完成时,服务端不会保存任何会话信息):每个请求都是完全独立的,服务端无法确认当前访问者的身份信息,无法分辨上一次的请求发送者和这一次的发送者是不是同一个人。所以服务器与浏览器为了进行会话跟踪(知道是谁在访问我),就必须主动的去维护一个状态,这个状态用于告知服务端前后两个请求是否来自同一浏览器。而这个状态需要通过 cookie 或者 session 去实现。
  • cookie 存储在客户端: cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。
  • cookie 是不可跨域的: 每个 cookie 都会绑定单一的域名,无法在别的域名下获取使用,一级域名和二级域名之间是允许共享使用的(靠的是 domain)。
    也就是说,在登录成功后,可以给用户颁发一个cookie,每次请求都带着一个cookie。只要携带着cookie就代表着用户已经登录过了。
    什么是session:
    session 由服务端创建,当一个请求发送到服务端时,服务器会检索该请求里面有没有包含 sessionId 标识,如果包含了 sessionId,则代表服务端已经和客户端创建过 session,然后就通过这个 sessionId 去查找真正的 session,如果没找到,则为客户端创建一个新的 session,并生成一个新的 sessionId 与 session 对应,然后在响应的时候将 sessionId 给客户端,通常是存储在 cookie 中。如果在请求中找到了真正的 session,验证通过,正常处理该请求。
    每一个客户端与服务端连接,服务端都会为该客户端创建一个 session,并将 session 的唯一标识 sessionId 通过设置 Set-Cookie 头的方式响应给客户端,客户端将 sessionId 存到 cookie 中。

2,token+session

token和cookie的区别是:cookie属于前后端共享的,也就是说不需要前端显示的传递,服务端即可拿到cookie。
而token是用户登录成功以后,服务端返回一个token,每次请求用户都必须显式的传递这个token。客户端将这个token存储起来,然后每次客户端请求都需要开发者手动将token放在header中带过去,服务端每次只需要对这个token进行验证就能使用token中的信息来进行下一步操作了。

token比cookie更安全
需要了解一下一些常见的攻击:

  • xss 是什么:用户通过各种方式将恶意代码注入到其他用户的页面中,就可以通过脚本获取用户信息,发送请求等。
  • csrf 是什么:跨站请求攻击,简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并运行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去运行。
    这利用了web中用户身份验证的一个漏洞:简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。csrf并不能够拿到用户的任何信息,它只是欺骗用户浏览器,让其以用户的名义进行操作。
  • csrf例子:假如一家银行用以运行转账操作的URL地址如下: http://www.examplebank.com/withdraw?account=AccoutName&amount=1000&for=PayeeName,
    那么,一个恶意攻击者可以在另一个网站上放置了一串恶意代码,该代码会自动调用转账接口。
    如果有账户名为Alice的用户访问了恶意站点,而她之前刚访问过银行不久,登录信息尚未过期,那么她就会损失1000资金。
  • 对于xss攻击来说,cookie和token没有什么区别。但是对于csrf来说就有区别
    如果被xss攻击了,不管是token还是cookie,都能被拿到,所以对于xss攻击来说,cookie和token没有什么区别。
    但是对于csrf来说就有区别,以上面的csrf攻击为例:
  • cookie:用户点击了链接,cookie未失效,导致发起请求后,浏览器自动携带cookie,后端以为是用户正常操作,于是进行扣款操作。
  • token:用户点击链接,由于浏览器不会自动带上token,所以即使发了请求,后端的token验证不会通过,所以不会进行扣款操作。

二,token生成方案:

1,JWT

它将用户信息加密到token里,服务器不保存任何用户信息。服务器通过使用保存的密钥验证token的正确性,只要正确即通过验证。
组成:
JWT包含三个部分:Header头部,Payload负载和Signature签名。由三部分生成token,三部分之间用“.”号做分割。列如 :eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

  1. Header 在Header中通常包含了两部分:type:代表token的类型,这里使用的是JWT类型。alg:使用的Hash算法,例如HMAC SHA256或RSA.
    { “alg”: “HS256”, “typ”: “JWT” } 这会被经过base64Url编码形成第一部分

  2. Payload token的第二个部分是荷载信息,它包含一些声明Claim(实体的描述,通常是一个User信息,还包括一些其他的元数据) 声明分三类: 1)Reserved Claims,这是一套预定义的声明,并不是必须的,这是一套易于使用、操作性强的声明。包括:iss(issuer)、exp(expiration time)、sub(subject)、aud(audience)等 2)Plubic Claims, 3)Private Claims,交换信息的双方自定义的声明 { “sub”: “1234567890”, “name”: “John Doe”, “admin”: true } 同样经过Base64Url编码后形成第二部分

  3. signature 使用header中指定的算法将编码后的header、编码后的payload、一个secret进行加密。例如使用的是HMAC SHA256算法,大致流程类似于: HMACSHA256( base64UrlEncode(header) + “.” + base64UrlEncode(payload), secret) 这个signature字段被用来确认JWT信息的发送者是谁,并保证信息没有被修改 。
    也就是说通过使用JWT我们可以不用将用户信息和过期时间,存储到服务端,因为JWT本身就存储了用户信息。但是这也是JWT的一个很致命的问题,因为JWT一旦颁发,就无法做到失效。还有就是如何做到JWT的续签问题?

2,UUID+redis

就是用户登录成功以后,生成一个uuid当作token,然后将用户信息存储到redis中。通过这种方式实现的登录模型,我们可以做到对每个token的单独管控,包括注销,续签,踢人下线等功能,但是如果用户比较多,需要在内存型数据库中维护海量的用户数据。还有就是每次获取用户信息时,需要读取一次redis,相比于JWT这种CPU解密级别,读取redis稍微慢一些。

三、鉴权框架:

Shiro、SpringSecurity、Sa-Token都属于Java的权限框架。

  • Apache Shiro是Java的一个安全框架。目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Security做的功能强大,但应对中小型项目完全足够。
  • Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI和AOP功能,为应用系统提供声明式的安全访问控制功能,但是Spring Security 相较于 Apache Shiro 更复杂,学习成本高,仅限于Spring框架中使用,相较于Apache Shiro在权限控制方面更灵活。
  • Sa-Token和Shrio一样也是一个轻量级的java安全框架,主要解决:登录认证、权限认证、Session会话、单点登录、OAuth2.0 等一系列权限相关问题,相较于shiro,Sa-Token更适合于前后台分离架构,功能强大, 上手简单。缺点:没有Shiro知名度高,出现较晚。

四、 技术选型:

针对上面提到的优缺点,做出了如下的技术选型:
token+jwt+redis+sa-token:

  1. 摒弃cookie,拥抱token.
  2. 不再单纯的使用JWT,也不单纯的使用uuid+token,而是让两者结合,一些固定不变的信息,比如说用户基础信息,权限信息使用JWT存储,redis用来当作一个黑名单的功能.
  3. 权限框架使用轻量级的Sa-Token,上手简单,并且内部功能支持比较多。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值