认证鉴权(火眼)

接口认证,单点登录,访问控制

1 项目概述

1.1 背景和目标

1.1.1 背景

  • 架构前后端分离

  • 后端接口需要进行认证

  • 后端业务逻辑和认证逻辑解耦

1.1.2 目标

对平台所有接口进行访问控制

1.2 名词解释

  • 认证 (authentication): 你是谁 (who you are), 身份验证

  • 鉴权 (authorization): 你可以做什么 (what can you do), 权限验证

  • RBAC (Role-Based policies Access Control) 基于角色的访问控制

  • JWT (Json Web Token), 有 JWS 和 JWE 两种实现方式

    • JWS (JSON Web Signature), 由三个部分组成,"头部 (header). 载荷 (payload). 签名 (signature)"

    • JWE (JSON Web Encryption), 由五个部分组成,"(JWE header).(JWE Encrypted Key).(JWE initialization vector).(JWE Ciphertext).(JWE Authentication Tag)"

2 功能需求

2.1 功能 List

2.1.1 认证

后端的所有接口都可以进行认证

2.1.2 鉴权

用户访问后端接口时进行鉴权

2.2 策略详述

2.2.1 用户场景

//todo

3 设计思路及折衷

3.1 身份验证

3.1.1 认证方式

五种常用的 Web 安全认证方式

互联网概念的 token 认证,大抵是在RESTful流行后提出的,在开始token认证之前,我们先梳理下常见的互联网认证机制。

HTTP Basic Auth

HTTP Basic Auth常见的有两种:

  • 一种是最常见的,即我们在登陆一些web页面时,会让我们输入用户名密码;

  • 另一种是将用户名密码信息通过base64这类算法变成一条字符串在http请求头中增加auth字段,再传输给服务器。

这个属于最原始的认证,缺点比较明显,存在http头中的密码信息容易被抓包获取,用户名密码后端服务器需要在查询数据库里的信息,进行信息比对,这也增加了服务器的负担。

优点

基本认证的一个优点是基本上所有流行的网页浏览器都支持基本认证。

缺点

由于用户名和密码都是 Base64 编码的,而 Base64 编码是可逆的,所以用户名和密码可以认为是明文。所以只有在客户端和服务器主机之间的连接是安全可信的前提下才可以使用。

session+cookie 模式

假设目前我们有一个查询类的web站点,不可以每次查询都要登陆一次,为解决一次登录,可以在固定一段时间内登陆查询,就出现了session+cookie模式。 该模式是第一次拿不出来时使用HTTP Basic Auth,认证成功后,为避免每次都到数据库里校验用户名密码信息,就在主机上存储一份登陆的信息,cookie里同时保存expire time

该模式优缺点都比较明显:session信息需要额外的数据库存储,例如一般需要增加redismemached等应用。在多机负载时,需要考虑session共享; 但好处也是明显的,session信息统一,可以在服务端统一挖掘认证的过期时间或个别用户的过期时间。

简单 token 认证

token认证最常用的应用场景就是查询接口的调用RESTful API,查询接口的信息在没有安全需求时,大家都可以通过getpost方法取得所需信息。 但在有安全需要时一般需要认证后才能获取所需的信息,这时候可以通过先HTTP Basic Auth认证,HTTP Basic Auth认证完成后,服务端返回给客户端一个类似于UUID的唯一标识,我们称之为token。 该token可以在URLhead头里加入,如以下的常见的URL模式:http://api/361way.com/getinfo?token=xxxxxhttp://api.361way.com/getinfo?t=xxxxx,后面再加上相应的查询信息,就可以获取到相应的数据。

token的好处是服务端不需要存储相应信息,但被不怀好意的人从早间获取到该信息时,也容易被利用,非法获取数据。

由于这个简单的token返回串里未返回相应的过期时间信息,如果想增强安全性,一般可以在服务端生成时配合时间戳使用,服务端在接收到client发来带token的信息时, 先检测反解token获取时间戳信息,如果该时间戳在超过某个时间点时凡认为过期,需要重新获取。

OAuth 认证

OAuth(开放授权)是一个开放的授权标准,允许用户让第三方应用访问该用户在某一web服务上存储的私密的资源(如照片、视频、联系人列表),而无需将用户名和密码提供给第三方应用。

OAuth允许用户提供一个令牌,而不是用户名和密码来访问他们存在在特定服务提供者的数据。每一个令牌授权一个特定的第三方系统 (例如,视频编辑网站)在特定的时段(例如,接下来的 2 小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。 这样,OAuth让用户可以授权第三方网站访问他们存储在另外服务提供者的某些特定信息,而非所有内容。

这个理解起来比较绕口,举个例子,如很多网站上面有qq或微信登陆接口,qq或微信提供的就是OAuth认证。 OAuth虽然名字很洋气,其本质还是token谁,仔细研究下上面的话,是不是原理上和上面提到的简单token认证类似,只不过其加了几个callback函数而已。

这里以duoban豆瓣网调用QQOAuth接口为例,其调用方式如下:

优点

缺点

JWT 认证

JSON WEB Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。

一个JWT实际上就是一个字符串,它由三部分组成,头部 (Header)、载荷(Payload)与签名(Signature)。

JWT 字符串示例

这里只简单说下理论。

Payload里存放的存储签发者、签发时间、过期时间、一些数据信息的JSON格式的内容。

载荷 Payload(可以被前端直接解析到的)

这里面的前五个字段都是由 JWT 的标准所定义的。

  • iss: 该 JWT 的签发者(谁发出了令牌)

  • sub: 该 JWT 所面向的用户(它要发给谁)

  • aud: 接收该 JWT 的一方

  • exp(expires): 什么时候过期,这里是一个 Unix 时间戳(到期时间)

  • iat(issued at): 在什么时候签发的

Header里指定存放的是指定使用协议JWT、加密签名的类型,示例如下:

头部 Header

签名 Signature

优点

缺点

3.1.2 折衷

基于 session 和基于 jwt 的方式的主要区别就是用户的状态保存的位置,session 是保存在服务端的,而 jwt 是保存在客户端的。

jwt 的优点

jwt 的缺点

3.2 访问控制

基于角色的访问控制 (Role-Based policies Access Control)

  • 用户 (User)

  • 角色 (Role)

  • 资源 (Resource)

  • 用户 - 角色 关联 (User-Role-Map):用户所分配的角色(一个用户,可以分配多个角色), 用户分组

  • 角色 - 资源 关联 (Role-Resource-Map):某个角色下的用户,可以操作哪些资源,操作权限

4 系统设计

单点登录及认证例子

4.1 模块说明

4.1.1 butterfly-auth

butterfly-auth 即为 cas-client(客户端),含 /auth/verification 认证接口及 /auth/ssologin 单点登录接口

  • /auth/ssologin 单点登录成功后生成 jwt token(通过 pyjwt 实现)

  • /auth/verification 验证 jwt token 是否有效

非单点登录场景可以 /auth/register(注册) 和 /auth/login(登录) 接口

验证 token

Nginx auth_request 请求流程

4.2 访问控制

//todo

5 nginx 配置文件

5.1 butterfly-fe 静态文件

首页

其他静态文件

5.2 butterfly-auth 单点登录

前后端分离后,前端请求后端的请求为 ajax 请求,而我们知道,ajax 是不允许跨域访问的,更不会让浏览器自动重定向

所以说,对于后台可能会返回 302 跳转的请求,都需要修改成在前端进行跳转

5.3 butterfly-app 后端 API

6 传送门

7 他山之石

Last updated