单点登录的两种实现方案
传统的登录方案中,用户每访问一个站点都需要先输入用户名密码进行登录。当这些站点接入单点登录(Single Sign On, SSO)系统之后,用户只需要在第一次访问的站点中登录一次,那么用户对其它接入该SSO系统的站点就都拥有了访问权限。
flowchart LR A1[Application1] A2[Application2] A3[Application3] S[SSO] A1 --> S A2 --> S A3 --> S
同源策略
在设计单点登录系统之前,需要搞清楚浏览器的同源策略:
- cookie在不同域名下不能共享。如a.com的站点不能访问b.com的cookie,也不能为b.com设置cookie
- 子域名可以设置父域名(eTLD除外)的cookie,也可以访问父域名的cookie,即父域cookie被所有子域共享
基于认证中心的标准实现方案
用户首次访问时,需要在认证中心登录:
sequenceDiagram participant B as 浏览器 participant A as 系统A(a.com) participant S as 认证中心(sso.com) B->>+A: 访问受保护页面<br>a.com/pageA A->>A: 验证未登录 A-->>-B: sso.com/login?redirect=a.com/pageA B->>+S: 访问sso.com<br>sso.com/login?redreict=a.com/pageA S->>S: 验证未登录 S-->>-B: 展示登陆form B->>+S: POST 用户名 密码 S->>S: 验证用户名和密码成功 S->>S: 创建全局会话 S->>S: 创建ticket S-->>-B: 302重定向<br>set cookie: ssoid=1234, sso.com<br>redirect: a.com/pageA?ticket=T123
- 用户访问网站a.com下的pageA页面
- 由于没有登录,则会重定向到认证中心,并带上回调地址sso.com?redirect=a.com/pageA,以便用户登录之后能跳转回来
- 用户在认证中心输入账号密码,提交登录。
- 认证中心验证账号密码有效,然后重定向到a.com/pageA?ticket=T123并带上授权码ticket,并将认证中心sso.com的登录态写入Cookie。
- 在a.com的服务器中,拿着ticket向认证中心确认,授权码ticket真实有效。
- ticket验证成功后,a.com将登录信息写入自己域名下的cookie中。
用户访问接入了认证中心的其它服务时:
sequenceDiagram participant B as 浏览器 participant C as 系统B(b.com) participant S as 认证中心(sso.com) B->>+C: 访问系统B的受保护资源<br>b.com/pageB C->>C: 验证未登录 C-->>-B: 重定向到认证中心<br>sso.com/login?redirect=b.com/pageB B->>+S: 访问sso.com<br>sso.com/login?redirect=b.com/pageB<br>cookie: ssoid=1234 S->>S: 有cookie,用户已登录 S-->>-B: 重定向到b.com/pageB?ticket=T456
认证中心发现自己的域名下已经有了cookie,说明之前用户已经有效登录过了,所以直接将新的ticket带到b.com,b.com拿该ticket验证用户信息后种下自己的cookie
基于父域cookie共享的实现方案
该方案需要确保所有的服务都在同一父域名下,如a.baidu.com, b.baidu.com, c.d.baidu.com等,由于任一子服务可以将cookie种到baidu.com域名下,所以一个服务登录之后,只需要各子服务器能够共享登录态,其它服务就不需要再次登录了。
sequenceDiagram participant Browser as 浏览器 participant A as a.baidu.com participant B as b.baidu.com Browser->>+A: 用户访问a.baidu.com受保护页面 A->>A: 未登录 A-->>-Browser: 返回登录form Browser->>+A: post 用户名密码登录 A->>A: 验证成功<br>session写入redis, 与b.baidu.com, c.d.baidu.com共享 A-->>-Browser: 种入baidu.com域的cookie<br>Set-Cookie: name=value#59; domain=baidu.com Browser->>+B: 访问b.baidu.com受保护页面 B->>B: 浏览器将baidu.com的cookie传递到b.baidu.com<br>检查cookie有效 B-->>-Browser: 返回b.baidu.com受保护页面
登录服务也可以用一个专门的服务提供,如oa.baidu.com,这样不需要每个子域服务都开发登录功能。

评论列表:
暂无评论 😭