单点登录的通用架构实现

pphh发布于2018年4月26日

http://www.hyhblog.cn/2018/04/26/single_sign_on_arch/

目录

  • 1. 什么是单点登录
  • 2. 用户登录
    • 2.1 认证方式
    • 2.2 授权方式
    • 2.3 第一方登录架构实现
    • 2.4 第三方登录架构实现
    • 2.5 第一方登录和第三方登录的授权区别
    • 2.6 登录架构实现小结
  • 3. 权限控制
    • 3.1 分布式鉴权架构
    • 3.2 集中式鉴权架构
    • 3.3 分布式和集中式鉴权的优缺点
    • 3.4 访问控制的粒度
      • 3.4.1 Http方法级别
      • 3.4.2 API接口级别
      • 3.4.3 API实现级别
  • 4. 小结
  • 5. 参考资料

在互联网应用开发中,应用服务的用户登录和权限控制是至关重要的一个环节,直接影响到应用的安全运营,也影响到用户的隐私保护,因此用户登录和权限控制是互联网应用开发的必要功能组件, 其涉及到认证、授权、鉴权和权限控制四个功能环节。本文将梳理互联网应用开发中的单点登录(single-sign-on)技术架构实现,单点用户登录也被称为统一用户登录。

  • 注1:本文讨论的互联网应用开发,主要是指web应用和移动应用开发两个技术领域。
  • 注2:本文所讨论的认证、授权、鉴权和权限控制的概念定义来自其这篇文章。因此,在阅读本文之前,建议先请阅读前篇文章。

1. 什么是单点登录

单点登录SSO不仅仅是实现用户登录这单一功能,它更是一个技术架构,一个解决方案,能够提供统一的认证、授权、鉴权和权限控制,提供相应的组件,方便用户的使用,以及应用的开发快速接入。所以,单点登录不是一个简单的登录模块。

单点登录,从字面来说,是让用户使用同一账号可以访问不同应用服务,而且用户只需登录一次(输入一次用户名和密码)便可实现多次授权。单点登录能够很大程度上方便用户的登录操作。这是从用户的角度出发来看单点登录。

单点登录还需要考虑的另外一个重要需求,是方便应用的对接使用,单点登录架构必须提供相应的客户端组件和配置,使得应用可以简单、方便、快速地接入单点登录功能,同时实现安全的权限控制。

因此,单点登录作为一个安全技术架构,其主要包括用户登录和权限控制两大功能需求,前者涉及认证和授权环节,后者涉及鉴权和权限控制环节。

2. 用户登录

用户登录的过程一般会涉及到用户认证和授权两个环节,这两个环节往往一并发生,即在确认用户身份的同时,也完成用户的授权。

根据登录功能模块的提供方,可以将登录划分为第一方登录和第三方登录两种类型,

  • 第一方登录:应用的登录服务由自己提供。由于是己方登录和己方应用,所以登录服务和应用服务之间相互可信,这大大方便了授权过程。
  • 第三方登录:应用的登录服务由第三方提供,使用第三方的用户账号登录,比如通过微信、QQ、支付宝账号进行登录等等。目前各大互联网开放平台大多采用业界标准的OAuth 2.0授权码模式实现第三方登录。

第一方登录和第三方登录,在用户认证技术的实现上没有太大差别,但是授权流程有区别。具体的授权流程和区别在下文的架构实现中讨论。

2.1 认证方式

在互联网开发中,常见的认证方式有,

  • 用户名和密码
  • 手机短信验证码
  • 手机应用二维码扫描
  • 用户手势
  • 基于时间序列和用户相关的一次性口令

本文为了方便讨论,将使用简单的http基本认证(http basic authentication)方式进行用户登录,即用户名和密码的方式。更多的认证方式,一般可以通过identity provider的扩展接口来实现。

2.2 授权方式

一旦用户登录成功,即可获取到相应的授权信息。

在互联网应用开发领域,授权的实现技术主要包括如下几种,

  • 通过web服务器的session机制,一个访问会话保持着用户的授权信息
  • 通过web浏览器的cookie机制,一个网站的cookie保持着用户的授权信息
  • 颁发授权令牌(token),一个合法有效的令牌中保持着用户的授权信息

前面两者常见于web开发,需要有浏览器的支持。而对于移动应用及其其它无法使用cookie的场景中,大多可以采用token的实现并通过header方式携带该授权信息在请求中。

本文为了同时支持web应用和移动应用的授权,授权信息将以授权令牌(token)形式颁发,对于web应用,该授权令牌通过cookie携带于请求中,而对于移动应用,则通过header方式携带于请求中。

2.3 第一方登录架构实现

由于是己方登录实现,所以登录服务和应用服务之间相互可信,这大大方便了授权过程。

在第一方登录的场景下,一般可以通过两种方式获得授权,

  • 若应用通过浏览器访问,则可以通过同域cookie方式实现共享授权
  • 若应用不是浏览器访问,或者无法通过cookie技术,则可以直接通过用户名和密码来换取授权。需要注意的是,应用服务可以拿到用户名和密码等敏感信息,这是基于可信应用的先决条件。

代码实现(待开发)

一个简单的架构实现如下,

图中亮红色线和方格为单点登录架构所需实现的组件和功能,其主要包括,

  • 单点登录模块:提供用户登录界面,实现跳转返回,授权令牌(token)的颁发、校验和注销
  • Web filter:获取请求中的授权令牌并校验,若合法则通过请求,否则返回错误消息。

对于web应用,通过共享cookie的方式获取授权,整个流程交互如下,

  1. 用户通过浏览器访问web服务
  2. 后端服务中一个通用的web filter校验请求,若发现请求中没有授权令牌,则跳转至用户登录模块,让用户进行登录
  3. 用户输入用户名和密码,若登录成功,则将授权令牌存储在浏览器的cookie中
  4. 将用户跳转回用户的访问页面,此时请求中cookie将自动带上授权令牌
  5. 后端服务的web filter校验请求cookie中的授权令牌,若合法且有效,则用户可以正常访问后端服务,否则返回错误消息,提示用户再次登录。
  6. 用户注销登录时,web应用服务将存储在浏览器cookie中的授权令牌清除,并注销redis中的令牌。

对于移动应用,通过用户名和密码的方式获取授权,整个流程交互如下,

  1. 用户打开移动应用,应用提示用户登录
  2. 用户输入用户名和密码,若登录成功,则将授权令牌返回给移动应用,存储在手机上的应用存储空间。
  3. 进入应用后,移动应用访问后端服务,授权令牌携带在请求header中
  4. 后端服务中一个通用的web filter对请求header中的授权令牌进行校验,若合法且有效,则用户可以正常访问后端服务,否则提示用户登录。
  5. 用户注销登录时,移动应用将授权令牌清除,并注销redis中的令牌。

由于移动应用无法像web应用一样,通过浏览器cookie的方式自动携带授权信息,移动应用需要自己处理授权信息的存储和请求发送。

2.4 第三方登录架构实现

相比于第一方登录,第三方登录最大的好处在于,可以让用户使用一个常用的第三方账号直接登录,例如微信、QQ、淘宝账号等,省去了用户注册账号的步骤,也免去用户记忆各种应用账号密码的烦恼,方便了用户的快速使用,进而降低用户接入成本。

对于第三方登录,目前各大互联网开放平台大多采用业界标准的OAuth 2.0授权码模式。对于OAuth 2.0的授权码模式和更多详细介绍将有另外一篇文章讨论,这里对其不扩展。

代码实现(待开发)

一个简单的架构实现如下,

图中亮红色线和方格为单点登录架构所需实现的组件和功能,其包括,

  • OAuth 2.0授权服务器:提供用户登录授权,实现跳转返回,授权令牌(token)的颁发、校验和注销
  • Token接口:用于客户端调用,通过授权码换取授权令牌
  • Web filter:获取请求中的授权令牌并校验,若合法则通过请求,否则返回错误消息。

图中有两种应用类型,web应用和移动应用,两种获取授权方式基本一样。

对于web应用,整个流程交互如下,

  1. 用户通过浏览器访问Web服务
  2. 后端服务中一个通用的web filter校验请求,若发现请求中没有授权令牌,则跳转至第三方用户登录服务
  3. 在第三方登录服务中,用户输入用户名和密码,若登录成功,则跳转回web应用,并返回授权码
  4. Web应用将获取到的授权码,调用后端Token接口,该接口将根据授权码+应用ID+应用Secret,向第三方申请授权令牌,若一切正常,第三方颁发授权令牌给Web应用,Web应用将获取到的授权令牌存储在浏览器的cookie中。
  5. 将用户跳转回用户的初始访问页面,此时请求中cookie将自动带上授权令牌
  6. 后端服务的web filter校验请求cookie中的授权令牌,若合法且有效,则用户可以正常访问后端服务,否则返回错误消息,提示用户再次登录。
  7. 用户注销登录时,web应用服务将存储在浏览器cookie中的授权令牌清除,并注销redis中的令牌。

移动应用和web应用的流程类似,整个流程交互如下,

  1. 用户打开移动应用,应用提示用户登录,并将用户导向第三方登录服务
  2. 在第三方登录服务中,用户输入用户名和密码,若登录成功,则跳转回移动应用,并返回授权码给移动应用。
  3. 移动应用将获取到的授权码,调用后端Token接口,该接口将根据授权码+应用ID+应用Secret,向第三方申请授权令牌,若一切正常,第三方颁发授权令牌给移动应用,移动应用将获取到的授权令牌存储在手机上的应用存储空间。
  4. 进入应用后,移动应用访问后端服务,授权令牌携带在请求header中
  5. 后端服务中一个通用的web filter对请求header中的授权令牌进行校验,若合法且有效,则用户可以正常访问后端服务,否则提示用户登录。
  6. 用户注销登录时,移动应用将授权令牌清除,并注销redis中的令牌。

2.5 第一方登录和第三方登录的授权区别

第一方登录和第三方登录之间最大的区别在于授权流程。

第一方登录在用户被认证之后,即刻颁发授权令牌,应用服务一般无需介入授权流程。而第三方登录在用户认证之后,先颁发给授权码给应用服务,应用服务还需根据这个授权码去换取授权令牌,换句话说,应用服务需介入授权流程。

这里有个问题是,为什么在第三方登录中,应用服务会被介入授权流程?主要原因是在第三方登录场景中,除了用户需要被认证,应用服务本身也需要被认证。而在第一方登录场景,只需用户认证,应用服务本身是可信的,其无需被认证。

2.6 登录架构实现小结

为了对比上述两个登录架构实现的不同之处,下面将各自的特点小结为下表,

  第一方登录架构 第三方登录架构
登录功能 由己方提供 由第三方提供
使用第三方的用户账户
登录实现 通过http basic auth OAuth 2.0授权码模式
应用是否可信 可信,应用可以接触用户密码等敏感信息,应用本身无需认证 不可信
应用是否需要认证
应用是否可以接触用户密码等敏感信息
授权过程 登录成功后颁发token 1. 登录成功后返回授权码给应用 
2. 应用根据授权码和应用ID换取token
Web页面的服务请求 通过cookie带上token 通过cookie带上token
移动应用的服务请求 通过header带上token 通过header带上token

3. 权限控制

在互联网应用开发中,安全控制在后端服务中实现。整个权限控制的过程一般会涉及到鉴权和权限控制两个环节。

鉴权的实现方式一般有两种,

  • 通过授权服务器:由于授权令牌是由授权服务器颁发的,所以由授权服务器校验也是自然而然的事情。这种方式会导致授权服务器的访问热点问题,为了缓解热点,缓存是必要配置。
  • 通过加解密:通过授权令牌的加解密方式,确认令牌的合法性。即,授权服务器颁发一个通过公钥加密的授权令牌,在校验的时候若能够通过私钥解密,则该令牌为合法令牌。这种方式有一个缺点是,一旦令牌注销失效后,信息无法及时通知到解密方。对令牌的注销时效性要求不高的场景下,可以使用这种方式,其大大缓解了授权服务器的访问热点问题。

若根据鉴权的架构方式,则可分为分布式和集中式两大类,

  • 分布式:通过后端web服务的filter实现分布式控制,在各个服务应用的运行实例中进行鉴权
  • 集中式:通过网关实现集中式控制,在访问流量的入口进行鉴权

鉴权后访问控制粒度从大到小有如下三种分类,

  • Http方法级别
  • API接口级别
  • API实现级别

下面将对鉴权的架构实现和控制粒度进行详细讨论。

3.1 分布式鉴权架构

分布式鉴权的架构如下图,

在web应用开发中,可以通过web应用服务的filter功能,对所有请求中的授权令牌进行校验,实现分布式鉴权。分布式鉴权实现简单,可以快速实现并使用,但随着应用服务架构的水平和垂直扩展,filter的升级将会成为头痛的问题。

3.2 集中式鉴权架构

集中式鉴权的架构如下图,

通过网关,在访问流量的入口,对所有请求中的授权令牌进行校验,实现集中式鉴权。集中式鉴权减轻了应用服务的接入成本,但会增加了网关的性能负荷。

3.3 分布式和集中式鉴权的优缺点

分布式鉴权和集中式鉴权有各自的优缺点小结为下表,

  分布式鉴权 集中式鉴权
优点 简单,可以分散校验热点 应用服务接入成本低,方便鉴权管理
缺点 filter版本升级困难,需要对所有应用服务进行依赖更新 需要网关的支持,并且鉴权操作将增加网关的性能负荷
应用场景 简单的互联网web应用开发 大型互联网web应用开发

3.4 访问控制的粒度

鉴权后就会得到请求访问的权限,接下来则是根据权限来控制请求访问的允许或禁止。

根据访问控制粒度从大到小,可划分出如下几个控制级别,

  • Http方法级别
  • API接口级别
  • API实现级别

3.4.1 HTTP方法级别

若web应用服务是按照Restful的规范来开发接口服务,则可以根据Restful的定义对Http的不同方法实现不同的访问控制。

根据Restful的规范定义,Http方法具有如下安全性和幂等性的特点,

HTTP方法 Restful定义 安全性 幂等性
GET 获取资源
POST 创建资源
PUT 更新资源
DELETE 删除资源
HEADER 资源元信息
OPTIONS  

表中,安全性和幂等性的概念如下,

  • 安全性是指该方法不改变资源的状态,即不改变后台数据
  • 幂等性是指该方法执行的同一操作多次,其结果保持一致

可以看到,对于安全的HTTP方法,比如GET操作,其访问控制可以宽松。而对于一些非安全操作,则需要根据不同权限来控制访问请求。在实际应用过程中,可以执行如下的权限控制规则,

  • 匿名用户:可以执行GET请求
  • 普通登录用户:可以执行GET、POST、PUT请求
  • 管理员:可以执行所有类别请求

总的来说,根据Http请求的方法和URI进行访问控制。

3.4.2 API接口级别

这个权限控制的粒度深入到代码控制层(Controller),不同的权限,可以访问不同的API接口。

一个spring mvc的代码样例如下,

@Controller
public class TokenApp { @PreAuthorize("hasAuthority('ROLE_ADMIN')")
public Principal getUserInfo(Principal me){
return me;
} }

上面的代码表示,具有管理员角色的权限才能获取当前用户信息。

这个粒度的权限访问控制基本可以满足大多数应用场景需求。

3.4.3 API实现级别

在应用的实现级别进行控制,这个控制粒度非常细,其根据不同权限返回不一样的调用结果,例如,同样是查看学生列表,若是班主任,则返回一个班的学生列表,若是校长,则返回一个学校的学生列表。

4. 小结

本文主要从用户登录和权限控制两大功能方面梳理其架构实现,这些实现可以结合实际的应用场景,进行相应的匹配。

  第一方登录 第三方登录
分布式权限控制 1. 简单web应用场景
2. 登录服务和应用服务相互可信
3. 登录服务和应用服务同域,可以授权共享
1. 简单web应用场景
2. 登录服务和应用服务相互不可信
3. 登录服务和应用服务不同域,各自独立开发部署,无法授权共享
4. 应用和登录服务模块彻底解耦,通过跨域跳转实现用户登录。
集中式权限控制 1. 大型web应用场景,有网关组件部署 1. 大型web应用场景,有网关组件部署
2. 快速接入第三方用户

5. 参考资料

    1. HTTP Authentication: Basic and Digest Access Authentication
    2. TOTP: Time-Based One-Time Password Algorithm

029.[转] SSO单点登录的通用架构实现的更多相关文章

  1. (十一) 整合spring cloud云架构 - SSO单点登录之OAuth2.0登录流程(2)

    上一篇是站在巨人的肩膀上去研究OAuth2.0,也是为了快速帮助大家认识OAuth2.0,闲话少说,我根据框架中OAuth2.0的使用总结,画了一个简单的流程图(根据用户名+密码实现OAuth2.0的 ...

  2. Spring Cloud云架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)

    上一篇我根据框架中OAuth2.0的使用总结,画了SSO单点登录之OAuth2.0 登出流程,今天我们看一下根据用户token获取yoghurt信息的流程: /** * 根据token获取用户信息 * ...

  3. Spring Cloud云架构 - SSO单点登录之OAuth2.0登录流程(2)

    上一篇是站在巨人的肩膀上去研究OAuth2.0,也是为了快速帮助大家认识OAuth2.0,闲话少说,我根据框架中OAuth2.0的使用总结,画了一个简单的流程图(根据用户名+密码实现OAuth2.0的 ...

  4. SSO单点登录 与 CAS

    本文转载自http://www.imooc.com/u/2245641/articles非常好的sso单点登录理解文章 作者: 常明,Java架构师 Web应用系统的演化总是从简单到复杂,从单功能到多 ...

  5. [精华][推荐] CAS SSO单点登录环境搭建及实例

    1.因为是本地模拟sso环境,而sso的环境测试需要域名,所以需要虚拟几个域名出来,步骤如下: 2.进入目录C:\Windows\System32\drivers\etc 3.修改hosts文件 12 ...

  6. CAS SSO单点登录实例

    1.因为是本地模拟sso环境,而sso的环境测试需要域名,所以需要虚拟几个域名出来,步骤如下: 2.进入目录C:\Windows\System32\drivers\etc 3.修改hosts文件 12 ...

  7. 170810、spring+springmvc+Interceptor+jwt+redis实现sso单点登录

    在分布式环境中,如何支持PC.APP(ios.android)等多端的会话共享,这也是所有公司都需要的解决方案,用传统的session方式来解决,我想已经out了,我们是否可以找一个通用的方案,比如用 ...

  8. SSO单点登录实现原理

    SSO单点登录实现原理 只是简要介绍下基于java的实现过程,不提供完整源码,明白了原理,我相信你们可以自己实现.sso采用客户端/服务端架构,我们先看sso-client与sso-server要实现 ...

  9. sso单点登录原理详解

    sso单点登录原理详解     01 单系统登录机制    1.http无状态协议 web应用采用browser/server架构,http作为通信协议.http是无状态协议,浏览器的每一次请求,服务 ...

随机推荐

  1. Bootstrap Bootstrap表格插件bootstrap-table配置与应用小结

    Bootstrap表格插件bootstrap-table配置与应用小结   by:授客 QQ:1033553122 1.   测试环境 win7 JQuery-3.2.1.min.js 下载地址: h ...

  2. 【JS基础语法】---学习roadmap---6 parts

    JS基础语法---roadmap Part 1 - 2: Part 3 - 4:   Part 5 - 6

  3. 微信小程序——仿jqueryValidate表单验证插件WxValidate的二次封装(一)

    在做web开发时,表单验证插件我们前端用的是jqueryValidate,由于个人主要精力是在后台JAVA开发上,为了让插件与后台更好的结合和使用,通过JAVA的自定义组件将表单全部重新写了一边,同时 ...

  4. ABP入门教程4 - 初始化运行

    点这里进入ABP入门教程目录 编译解决方案 重新生成解决方案,确保生成成功. 连接数据库 打开JD.CRS.Web.Host / appsettings.json,修改数据库连接设置Connectio ...

  5. MySQL的事务隔离

    提到事务,你肯定会想到ACID(Atomicity.Consistency.Isolation.Durability,即原子性.一致性.隔离性.持久性),今天我们就来说说其中I,也就是“隔离性”. 数 ...

  6. div里面的元素垂直均匀分布 按钮引发地址栏出现问号 判断一个数组是否为空 div底部居中 路由传参接受参数

    一个固定高度的div的子元素 在垂直 方向上平均分布 .important-dec{ height: 121px; flex-direction: column; display: flex; jus ...

  7. 【CentOS7】CentOS7各个版本镜像下载地址(转)

    链接:https://www.cnblogs.com/caidingyu/p/10679422.html # CentOS7.6 下载地址       # CentOS-7-x86_64-DVD-18 ...

  8. JMeter基础知识系列一

    1.Jmeter简介: Apache Jmeter可以用于对静态和动态的资源(文件.web动态语言-PHP.java.ASP.net.java对象.数据库和查询.FTP服务器等)的性能进行测试.最初用 ...

  9. 05_javaSE面试题:成员变量和局部变量

    题目 /** * 类变量:static修饰的 * 实例变量:不是static修饰的 * * 局部变量:栈 * 实例变量:堆 * 类变量:方法区 * @author kevin * @date 2019 ...

  10. MQ的深入理解

    MQ的深入理解 MQ的作用: 解耦合,降低系统与系统之间的频繁改动 MQ的特点: 复杂的系统解耦合 (主系统将数据放入mq,子系统需要的时候直接从mq中取出数据)复杂链路的异步调用(将必要的链路执行完 ...