我会简单阐述以下几个专有名词。
授权和认证
OAuth 2.0
jwt
HTTP Basic
Bearer Token
Mac Token
认证和授权
这是两个不同的概念,比较容易混淆,现放在一起解释。
Authentication 认证
证明你是你。比如账密登录、验证码登录、微信语音登录等。
HTTP Basic
| HTTP Digest
| HTTP Mutual
都是认证的解决方案。
Authorization 授权
授权是指应用软件(资源提供方)通过采用某种方法来确认用户允许第三方应用(资源使用方)对他的保护资源做哪些操作。
OAuth 2.0
OAuth 2.0是一个授权解决方案。它规定了一套传递用户授权决策的标准流程、格式。采用该流程的优点在于用户在享受第三方应用替自己操作的便利时,不必与其共享自己的账号密码,第三方应用使用的是一个短期有效的访问令牌(access token),并且用户能够控制令牌权限范围,以及随时能够让令牌失效。
具体流程是:用户告知授权服务器(QQ用户中心),自己允许客户机应用(某第三方在线PS应用)在其同意的权限范围内(读取某个指定相册),访问自己保存在资源服务器(QQ空间)中的数据资源(照片)。
显然,授权服务器(QQ用户中心)必须先认证用户的身份,才会发放访问令牌给客户机应用(PS应用),客户机应用凭借此访问令牌就能从资源服务器(QQ空间)上访问用户数据资源(读取指定相册的照片)。
需要注意,OAuth 2.0规定了授权服务器必须要对用户进行认证,但它只是授权协议,它不关心授权服务器如何完成认证,授权服务器自行选择认证机制。授权服务器可以在HTTP Basic、Digest、Mutual等密码认证机制中进行选择,也可以选择非密码的认证机制,还可以将两者结合起来使用。
由于:
- OAuth 2.0授权流程比较安全可靠
- 授权服务器这个角色有能力且必须要对用户进行认证,看起来很适合作为用户身份信息的提供方
- 有时候客户机应用也需要使用用户身份信息
于是有人就想,能不能利用OAuth 2.0的授权流程把用户身份信息从授权服务器传递给客户机应用?把它作为一种联合身份认证机制来使用。
能,Github就是这样做的,它利用OAuth 2.0向客户机应用同时提供用户认证、授权两项服务。但是,OAuth 2.0的设计本意是用来做授权的,直接拿来做用户认证会导致一些问题。虽然提供方(Github)能够通过自己做额外设计来解决这些问题,但是当每个提供方采用的额外设计不一致时,整个流程就不再统一规范了,这会给使用方带来不必要的负担。于是就产生了OIDC这个协议,它规定了一套标准的额外设计。
OIDC(OpenID Connect)是一个身份认证协议,它规定了一套把用户身份信息从授权服务器(身份提供方)传递给客户机应用(身份使用方)的标准流程、格式。
JWT
全称Json Web Token
,是一种自包含令牌,区别于读取令牌。
服务端认证完成之后,生成一个JSON对象发给客户端。当然这个json对象会被加密,客户端和服务端会提前约定好加密方式,这里仅展示明文。
1 |
|
服务端不保存任何session数据。以后客户端和服务端的每一次通信都会附上这个json,服务端直接根据json内容判断用户的权限,不会做db查询、session查询等任何动作。
弊端
- 如果破解了加密算法(虽然正式开发会采用非对称加密,但是我们假设工程师们约定了一个非常easy的加密规则),客户端就可以随便篡改json数据伪造身份。
- 主动撤销非常麻烦。一旦 JWT 签发了,在到期之前就会始终有效。
HTTP Basic
全称The Basic HTTP Authentication
。在RFC7617
词条中有以下描述。
This document defines the “Basic” Hypertext Transfer Protocol (HTTP) authentication scheme, which transmits credentials as user-id/password pairs, encoded using Base64.
简单来说,每次请求都带上username和password,服务端校验这两个值是否匹配。
一个请求示例,摘录自RFC7617
1 |
|
dGVzdDoxMjPCow==: 由用户名和密码生成的密文,服务端知道如何还原。
请求头Authorization: Basic encode(username, password)
是规范的写法,不遵守也没关系,但是我们尽量去遵守。
注意这里用的是Authorization 授权
这个单词。
Bearer Token和Mac Token
OAuth2.0定义了token_type
,Bearer Token和Mac Token正是两种不同的token类型。
Bearer Token
A security token with the property that any party in possession of the token (a “bearer”) can use the token in any way that any other party in possession of it can. Using a bearer token does not require a bearer to prove possession of cryptographic key material (proof-of-possession).
我们可以简单地把Bearer Token理解为『客户端传递明文参数(access_token, refresh_token)给服务端』。
正是因为明文传递,Bearer Token必须使用https协议。
Mac Token
在一些不能保证https的场景下,Bearer Token就显得不够安全。Mac Token应运而生。
全称message authentication code token
。不依赖于TLS,适用于http和https。
在使用Mac Token时,客户端需要完成复杂的加密运算,然后将token和加密结果一起传给服务端,服务端会做校验防止数据被伪造。
我们可以简单地把Mac Token理解为『客户端计算mac值,然后传递token、时间戳、mac值给服务端』。
1 |
|
具体的加密和参数规则可以查看标准文件中的示例。