-
数字证书 = 个人信息 + 数字签名
-
个人信息---Hash 算法----------->信息摘要
-
信息摘要---使用 CA 的私钥加密--->数字签名
-
数字签名---使用 CA 的公钥解密--->信息摘要
为什么对信息摘要进行签名,而不是个人信息? 因为摘要的数据量比较小,而个人信息比较多。 而且,由于哈希算法的单调性,很难篡改个人信息之后,而信息摘要相同。 这就相当于只要对门(摘要)加锁(签名)就能保证房子(整个数据)内东西(个人信息)的安全(不可篡改)。
补充: 用私钥加密任意内容是有风险的,某些特定内容用私钥加密将会把私钥暴露出来,至少 RSA 是这样的,这样攻击者就可以通过诱使服务器加密特定文本(例如,上传特定文件再下载下来)从而破解私钥,所以实际上应该是将 payload 再以某些方式填充一些没有用的数据进去,算 hash 值,然后加密 hash 值。
消除多个账号的问题,将来每个系统不需要维护自己的用户系统,只需要建立一个统一的认证中心,所有的用户注册和认证都在这里完成。
- (1)用户输入用户名和密码
- (2)系统进行验证
- (3)系统验证通过后建立 session
- (4)系统将 sessionid 通过 cookie 发送给浏览器
- (5)用户再次访问系统时,cookie 就会随之发送,系统就知道用户已登陆
登陆就是 cookie,只要共享 cookie 就行了。
cookie 不能跨域,但是 session 可以共享
不共享 session,使用 cookie。用户在 A 系统登陆,A 系统在 cookie 中写入 token。当用户访问 B 系统时,将 token 带过去。B 系统验证一下 token,如果没问题,就认为用户已经登陆。
- (1)用户 -> A 系统 :user + pwd
- (2)A 系统 :验证用户是否合法,生成登陆凭证,进行签名,放到 cookie 中
- (3)A 系统 -> 用户 : [cookie : token=XXX]
- (4)用户 -> B 系统 : [cookie : token=XXX]
- (5)B 系统 : 对 token 进行验证
- (6)B 系统 -> 用户 : 返回页面
这里的 token 使用 JWT(JSON Web Token) 进行数字证书
JWT = token + 签名
需要不同系统使用一致的 Hash 算法和密钥。
问题:JWT 中的用户信息,可能不同的系统维护的结构不同,无法共用
本质上就是一个认证中心的 cookie,加上多个子系统的 cookie
需要统一登入,当然也需要统一登出。
-
(1)浏览器 -> A 系统(a.com) : 访问受保护的页面 www.a.com/pageA
-
(2)A 系统 : 验证未登录(没有局部会话)
-
(3)A 系统 -> 浏览器 : 302 重定向,URL 为 www.sso.com/login?redirect=www.a.com/pageA
-
(4)浏览器 -> 认证中心(sso.com) : 访问认证中心,URL 为 www.sso.com/login?redirect=www.a.com/pageA
-
(5)认证中心 : 验证未登录
-
(6)认证中心 -> 浏览器 : 展示登陆 form
-
(7)浏览器 -> 认证中心 : POST 用户名 + 密码,URL 为 www.sso.com/login?redirect=www.a.com/pageA
-
(8)认证中心 : 验证用户名和密码成功
-
(9)认证中心 : 创建全局会话
-
(10)认证中心 : 创建 ticket
-
(11)认证中心 -> 浏览器 : 302 重定向,redirect 目标:www.a.com/pageA?ticket=T123,并记录 Set cookie: ssoid=1234;domain=sso.com
以上(1-11)是首次登陆
-
(12)浏览器 : 保存 sso.com 的 cookie
-
(13)浏览器 -> A 系统 : 访问 www.a.com/pageA?ticket=T123
-
(14)A 系统 -> 认证中心 : 验证 ticket
-
(15)认证中心 : ticket 有效
-
(16)认证中心 : 注册 A 系统
-
(17)认证中心 -> A 系统 : 令牌有效
-
(18)A 系统 : 创建局部会话
-
(19)A 系统 -> 浏览器 : 返回受保护的资源 pageA,并记录 Set cookie: sessionid=xxxx;domain=a.com
-
(20)浏览器 -> A 系统 : 访问另一个受保护的资源 pageA1,带上 cookie: sessionid=xxxx;domain=a.com
-
(21)A 系统 : 验证已登陆
-
(22)A 系统 : 返回 pageA1
以上(12-22)是验证 ticket
-
(23)浏览器 -> B 系统(b.com) : 访问 B 系统的受保护资源 www.b.com/pageB
-
(24)B 系统 : 未登陆(没有局部会话)
-
(25)B 系统 -> 浏览器 : 302 重定向,URL 为 www.sso.com/login?redirect=www.b.com/pageB
-
(26)浏览器 -> 认证中心 : 访问认证中心 sso.com,URL 为 www.sso.com/login?redirect=www.b.com/pageB,带上 cookie: ssoid=1234;domain=sso.com
-
(27)认证中心 : 验证已登录
-
(28)认证中心 -> 浏览器 : 302 重定向,URL 为 www.b.com/pageB?ticket=T5678
以上(23-28)是登陆另一个系统
-
(29)浏览器 -> B 系统 : 访问 www.b.com/pageB?ticket=T5678
-
(30)B 系统 -> 认证中心 : 验证 ticket
-
(31)认证中心 : ticket 有效
-
(32)认证中心 : 注册 B 系统
-
(33)认证中心 -> B 系统 : 令牌有效
-
(34)B 系统 : 创建局部会话
-
(35)B 系统 -> 浏览器 : 返回受保护的资源 pageB,并记录 Set cookie: sessionid=xxxx;domain=b.com
-
(36)浏览器 -> B 系统 : 访问另一个受保护的资源 pageB1,带上 cookie: sessionid=xxxx;domain=b.com
-
(37)B 系统 : 验证已登陆
-
(38)B 系统 : 返回 pageB1
以上(29-38)是验证 ticket,与之前(13-22)的并无不同
第三方获得资源所有者的用户名,密码登陆,登陆资源服务器。
问题:敏感数据对第三方完全暴露!
第三方重定向到授权服务器,资源所有者授权之后,授权服务器给浏览器一个 token,然后浏览器将这个 token 传给第三方,第三方拿到 token 才能访问资源服务器。
问题:其他应用从浏览器拿到这个 token 后,也能访问资源服务器。
第三方重定向到授权服务器,资源所有者授权之后,授权服务器给浏览器一个授权码,然后浏览器将这个授权码传给第三方,第三方拿到授权码后,再向授权服务器获取 token,获取 token 后,才能访问资源服务器。
这里授权码与第三方应用绑定,只有这个第三方才能获取到 token,其他应用拿到授权码也无用。
-
上帝的规矩:局部性原理
-
坐飞机的怎么和坐驴车的打交道:缓存
-
抛弃细节:抽象
-
我只想和邻居打交道:分层
-
我怕等不及:异步调用
-
大事化小,小事化了:分而治之
-
OpenID 是一个以用户为中心的数字身份识别框架,是一个以 URL 为身份标识的分散式身份验证解决方案,它具有开放、分散、自由等特性
-
可以通过 URL 来认证一个网站的唯一身份,同理,也可以让每人通过一个 URL(一个 OpenID 身份就是一个 URL),在多个网站上进行登录,作为用户的身份认证
-
用户不需要记住像用户名和密码这样传统验证标记。取而代之的是,他们只需要预先在一个作为 OpenID 身份提供者的网站上注册。
-
使用 OpenID,你的网站地址就是你的用户名,而你的密码安全的存储在一个 OpenID 服务网站上。
-
OpenID 使用标准的 HTTPS 协议,并且不依赖于 Cookie。让全网不同架构的 Web 应用服务器和 OpenID 的整合提供可能
@see https://www.cnblogs.com/iskyoole/articles/2659273.html
OAuth 关注的是 authorization;而 OpenID 侧重的是 authentication。
authorization: n. 授权,认可;批准,委任
authentication: n. 证明;鉴定;证实
OAuth 关注的是授权,即:“用户能做什么”;而 OpenID 关注的是证明,即:“用户是谁”。
JWT 是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准RFC7519。该 TOKEN 被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。
JWT 的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该 TOKEN 可以被验证和信任,因为它是数字签名的,也可被加密。
客户端接收服务器返回的 JWT,将其存储在 Cookie 或 localStorage 中。
此后,客户端将在与服务器交互中都会带 JWT。如果将它存储在 Cookie 中,就可以自动发送,但是不会跨域,因此一般是将它放入 HTTP 请求的 Header Authorization 字段中。
JWT 将用户信息加密到 TOKEN 里,服务器不保存任何用户信息。服务器通过使用保存的密钥验证 TOKEN 的正确性,只要正确即通过验证。
无状态和可扩展性:Tokens 存储在客户端。服务器不保存任何会话数据,即服务器变为无状态,使其更容易扩展。我们的负载均衡器可以将用户传递到任意服务器,因为在任何地方都没有状态或会话信息。
安全:Token 不是 Cookie。(The token, not a cookie.)每次请求的时候 Token 都会被发送。而且,由于没有 Cookie 被发送,还有助于防止 CSRF 攻击。即使在你的实现中将 token 存储到客户端的 Cookie 中,这个 Cookie 也只是一种存储机制,而非身份认证机制。没有基于会话的信息可以操作,因为我们没有会话!
优点是在分布式系统中,很好地解决了单点登录问题,很容易解决了 session 共享的问题。缺点是无法作废已颁布的令牌/不易应对数据过期
为了减少盗用和窃取,JWT 不建议使用 HTTP 协议来传输代码,而是使用加密的 HTTPS 协议进行传输。
@see http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html
OAuth 是一个授权协议,JWT 是一个信息安全传输标准。OAuth 的 Access Token 有一种实现方式就是 JWT。
OAuth2 是一种授权框架,JWT 是一种认证协议
无论使用哪种方式切记用 HTTPS 来保证数据的安全性
OAuth2 用在使用第三方账号登录的情况(比如使用 weibo,qq,github 登录某个 app),而 JWT 是用在前后端分离, 需要简单的对后台 API 进行保护时使用。
相同点是,它们都是存储用户信息;然而,Session 是在服务器端的,而 JWT 是在客户端的。
Session 方式存储用户信息的最大问题在于要占用大量服务器内存,增加服务器的开销。
而 JWT 方式将用户状态分散到了客户端中,可以明显减轻服务端的内存压力。
Session 的状态是存储在服务器端,客户端只有 session id;而 Token 的状态是存储在客户端。
-
都是认证用户身份的
-
OpenID 是实现全网统一认证的解决方案,而不是单点登录,OpenID 是单点登录实现的基础
-
CAS 是单点登录的一种实现方案
-
JWT 适用于分布式场景的单点登录。可将其与传统的 session 认证相比较