鉴权方案

424 阅读7分钟

常见的鉴权方案

  • 每种鉴权方案的实现原理
  • 这种鉴权方案的优缺点
  • 极简的代码实现

1、HTTP Basic Authentication

实现的关键: http协议中响应头字段WWW-Authenticate和请求头Authorization

1.1、认证过程

1. 客户端向服务器请求数据,请求的内容可能是一个网页或者是一个ajax异步请求,此时,假设客户端尚未被验证,则客户端提供如下请求至服务器
2. 服务器向客户端发送验证请求代码401,并在响应头添加字段WWW-Authenticate: XXXX。 服务器返回的响应数据大抵如下

HTTP/1.0 401 Unauthorised
Server: SokEvo/1.02
WWW-Authenticate: Basic
Content-Type: text/html
Content-Length: xxx

3. 当符合http规范的客户端(如Chrome,FIREFOX)收到401返回值时,将自动弹出一个登录窗口,要求用户输入用户名和密码。
4. 用户输入用户名和密码后,客户端会将用户名及密码以BASE64加密方式加密,并将密文写入到请求头的Authorization字段当中,(浏览器自动将${username}:${passwrod}进行base64加密,并添加认证类型Basic)此时客户端发送的求信息则变成如下内容

  Get /index.html HTTP/1.0
  Host:www.google.com
  Authorization: Basic d2FuZzp3YW5n

5. 服务器收到上述请求信息后,将Authorization字段后的用户信息取出、解密,将解密后的用户名及密码与用户数据库进行比较验证,如用户名及密码正确,服务器则根据请求,将所请求资源发送给客户端

优点: 实现简单,快捷。
缺点: 因为base64加密可逆,所以安全性极低。

2、session-cookie

第二种这个方式是利用服务器端的session(会话)和浏览器端的cookie来实现前后端的认证

标准session-cookie认证主要分为以下几步:
1,服务器在接受客户端首次访问时在服务器端创建seesion,然后保存seesion(通常保存在redis中),然后给这个session生成一个唯一的标识字符串,然后在响应头中种下这个唯一标识字符串。
2:浏览器中收到请求响应的时候会解析响应头,然后将session_id保存在本地cookie中,浏览器在下次http请求时请求头中会带上该域名下的cookie信息
3:服务器在接受客户端请求时会去解析请求头cookie中的session_id,然后根据这个session_id去找服务器端保存的该客户端的session,然后判断该请求是否合法.

缺点:
1、保存session信息需要增加服务器的开销,而且不利于扩展。
2、依赖浏览器的cookie,所以对APP等移动应用不友好。
3、依赖cookie,所以安全性隐患相对较大。
一篇很不错的session-cookie实现教程: medium.com/@evangow/se…

3、Token

使用基于 Token 的身份验证方法,大概的流程是这样的:

  1. 客户端使用用户名跟密码请求登录
  2. 服务端收到请求,去验证用户名与密码
  3. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
  4. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
  5. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
  6. 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

4、JWT原理

JWT 的原理是,服务器认证以后,生成一个 JSON 对象,发回给用户,就像下面这样。

{
  "姓名": "张三",
  "角色": "管理员",
  "到期时间": "2018年7月1日0点0分"
}

以后,用户与服务端通信的时候,都要发回这个 JSON 对象。服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名(详见后文)。

服务器就不保存任何 session 数据了,也就是说,服务器变成无状态了,从而比较容易实现扩展。 JWT 的三个部分依次如下。 Header(头部) Payload(负载) Signature(签名)

4.1、header

Header 部分是一个 JSON 对象,描述 JWT 的元数据,通常是下面的样子。

{
  "alg": "HS256",
  "typ": "JWT"
}

上面代码中,alg属性表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256);typ属性表示这个令牌(token)的类型(type),JWT 令牌统一写为JWT。

4.2、Payload

Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。JWT 规定了7个官方字段,供选用。

iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号

除了官方字段,你还可以在这个部分定义私有字段,下面就是一个例子。

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

注意,JWT 默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这个部分。

4.3、Signature

Signature 部分是对前两部分的签名,防止数据篡改。

首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。

算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就可以返回给用户。

4.4、refreshToken

为了减少assessToken被盗用的风险,所以会将assessToken的有效期设置为较短。 添加refreshToken用于刷新assessToken.

特点: 1、token 使服务端无状态化,有利于扩展 2、token 也可以配合session使用。且token比cookie更为安全 3、token一旦颁发,在有效期内无法取消。除非在服务器部署特殊逻辑。

5、SSO

接下来我们探讨一个企业应一定绕不过的课题:单点登录。

在单点登录领域,CAS(Central Authentication Service,中文名是中央认证服务) 是一个被高频使用的解决方案。因此,这里介绍一下利用CAS 实现SSO。而CAS 的具体实现又可以依赖很多种协议,比如OpenID、OAuth、SAML 等,这里重点介绍一下CAS 协议。

5.1、 CAS 协议中的几个重要概念

简单介绍一下CAS 协议中的几个重要概念,一开始看概念可能很模糊,可以先过一遍,再结合下面的流程图来理解。

  • CAS Server:用于认证的中心服务器

  • CAS Clients:保护CAS 应用,一旦有未认证的用户访问,重定向至CAS Server 进行认证

  • TGT & TGC:用户认证之后,CAS Server 回生成一个包含用户信息的TGT (Ticket Granting Ticket) 并向浏览器写一个cookie(TGC,Ticket Granting Cookie),有啥用后面流程会讲到

  • ST:在url 上作为参数传输的ticket,受保护应用可以凭借这个ticket 去CAS Server 确认用户的认证是否合法

5.2 以豆瓣为例理解CAS协议

(1)第一次登陆豆瓣读书流程

  • A: 浏览器请求访问 豆瓣读书。
  • B: 豆瓣读书 引导浏览器 重定向 到 豆瓣用户中心。携带 Service参数
  • C: 在 用户中心 完成登录,建立全局会话。
    • 验证 Service
    • 生成TGT
    • 在浏览器记录CASTGC,即TGT.id,即 建立全局会话
  • D: CAS服务器产生Service Ticket,并 重定向 到业务系统。
    • 用TGT 签发 ST
    • 重定向到 Service代表的 豆瓣读书 路由
    • 并携带 ST
  • E: 豆瓣读书 用Service Ticket 向 用户中心服务器 兑换用户信息。
    • 豆瓣读书服务器获取 ST
    • 豆瓣读书在后台用 ST 向 用户中心服务器 兑换用户信息,官方使用xml传输信息(本文用JSON代替)
    • 兑换成功后,豆瓣读书 用Session或Cookie 记录用户的登录状态,即 建立局部会话。
(2)第二次登陆豆瓣读书流程

(3) 第一次登陆豆瓣电影流程

5.3 单点登出

实现教程:medium.com/brightlab-t…
参考文档:developers.onelogin.com/quickstart

优点:
1、提高用户效率
2、方便管理与开发