OAuth 2.0认证

OAuth 2.0认证

一 认识OAuth2.0

OAuth 2.0 (Open Authorization,开放授权)标准目前被广泛应用在第三方登录场景中

1.1 术语解析

资源所有者

Resource Owner:资源所有者,本文中又称”用户”(user)。

第三方应用程序

Third-party application第三方应用程序,本文中又称”客户端”(client),即上一节例子中的”云冲印”。

用户代理

User Agent:用户代理,本文中就是指浏览器。

HTTP服务提供商(隔离,第三方应用程序无法直接访问, 而是通过认证服务器访问资源服务器)

HTTP serviceHTTP服务提供商,本文中简称”服务提供商”,即上一节例子中的Google。

认证服务器

Authorization server:认证服务器,即服务提供商专门用来处理认证的服务器**。

资源服务器

Resource server:资源服务器,即服务提供商存放用户生成的资源的服务器。它与认证服务器,可以是同一台服务器,也可以是不同的服务器。

知道了上面这些名词,就不难理解,OAuth的作用就是**让”客户端”安全可控地获取”用户”的授权,从而可以和”服务商提供商”进行互动。

二 认证流程

第三方应用获取的访问令牌与用户的密码不同,用户可以再登录的时候,指定访问令牌的权限和有效期

2.1 4种授权模式

  • 授权码模式(authorization code)
  • 授权码(authorization code)方式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌。
  • grant_type: authorization_code
  • 简化模式(implicit)
  • 有些 Web 应用是纯前端应用,没有后端。这时就不能用上面的方式了,必须将令牌储存在前端。RFC 6749 就规定了第二种方式,允许直接向前端颁发令牌。这种方式没有授权码这个中间步骤,所以称为(授权码)”隐藏式”(implicit)。
  • 密码模式(resource owner password credentials)
  • 如果你高度信任某个应用,RFC 6749 也允许用户把用户名和密码,直接告诉该应用。该应用就使用你的密码,申请令牌,这种方式称为”密码式”(password)。
  • grant_type: password
  • 客户端模式(client credentials)
  • 最后一种方式是凭证式(client credentials),适用于没有前端的命令行应用,即在命令行下请求令牌。
  • grant_type: client_credentials

2.2 授权码模式详解

授权码模式(authorization code)是功能最完整、流程最严密安全的授权模式。它的特点就是通过客户端的后台服务器,与”服务提供商”的认证服务器进行互动。

授权码模式流程如下:

  • 用户访问客户端,客户端将用户导向认证服务器
  • response_type:表示授权类型,必选项,此处的值固定为”code”
  • client_id:表示客户端的ID,必选项
  • redirect_uri:表示重定向URI,可选项
  • scope:表示申请的权限范围,可选项
  • state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。
https://b.com/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri="https://a.com/callback"&scope=read
  • 用户选择是否给予客户端授权
  • 假设用户给予授权,认证服务器将用户导向客户端事先指定的”重定向URI”(redirection URI),同时附上一个授权码(每个用户的授权码不同)。
https://a.com/callback?code=AUTHORIZATION_CODE
  • 客户端收到授权码,附上早先的”重定向URI”,向认证服务器申请令牌。这一步是在客户端的 后台服务器 上完成的,对用户不可见。
  • grant_type:表示使用的授权模式,必选项,此处的值固定为”authorization_code”。
  • code:表示上一步获得的授权码,必选项。
  • redirect_uri:表示重定向URI,必选项,且必须与A步骤中的该参数值保持一致。
  • client_id:表示客户端ID,必选项。
https://b.com/oauth/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri="https://a.com/callback"
  • 认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)
  • access_token:表示访问令牌,必选项。
  • token_type:表示令牌类型,该值大小写不敏感,必选项,可以是bearer类型或mac类型。
  • expires_in:表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。
  • refresh_token:表示更新令牌,用来获取下一次的访问令牌,可选项。
  • scope:表示权限范围,如果与客户端申请的范围一致,此项可省略
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{"access_token":"ACCESS_TOKEN","token_type":"bearer","expires_in":2592000,"refresh_token":"REFRESH_TOKEN","scope":"read","uid":100101,"info":{...}}

从上述的流程描述可知,只有第 2 步需要用户进行授权操作,之后的流程都是在客户端的后台和认证服务器后台之前进行”静默”操作,对于用户来说是无感知的

2.3 令牌刷新

  • grant_type参数为refresh_token表示要求更新令牌,此处的值固定为refresh_token,必选项;
  • client_id参数和client_secret参数用于确认身份;
  • refresh_token参数就是用于更新令牌的令牌。

B 网站验证通过以后,就会颁发新的令牌。

https://b.com/oauth/token?grant_type=refresh_token&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&refresh_token=REFRESH_TOKEN

三 2FA双因素认证

常见的双因素认证分为三类:

  • OTP模式:这种模式下,一般需要用户首先持有特殊设备或安装特殊软禁,用户登陆时从特殊设备或软件获取一次验证码;当服务端收到验证码后,用相同的方式生成验证码并比对。此类模式的2FA代表有:HOTP、TOTP、动态令牌等
  • 服务端模式:在此类模式中,验证码由服务端生成,然后第三方途径发送给用户,当服务端收到验证码后,与之前生成的进行比对。 此类模式的2FA代表有:手机验证码、邮箱验证码、图片验证码等
  • 签名模式:这类模式一般由服务端生成挑战码,并由客户端对该挑战码进行签名,再由服务端验签完成。如:UKey等

3.1 OTP(One Time Password)

OTP模式与服务端模式在验证码生成和验证方式上有很大的不同,主要表现在(OTP模式下):

  • 客户端和服务端会分别计算验证码
  • 客户端和服务端计算验证码时,基于事先共享的OTP密钥
  • 由于客户端和服务端分别计算验证码,因此可以容忍网络延迟&临时网络不通

OTP主要技术实现有:

  • HOTP:hash-based one time password,基于计数器的一次密码,该技术需要客户端与服务端共享加密密码K, 以及计数器C, 然后通过如下算法计算一次密码(验证码):
# K:加密密码,作为HMAC密码算法输入,由于只有客户端和服务端共享,因此在不知道K的情况下,无法生成,保证安全性。
# C:计数器,每次使用后C需要+1,需要客户端和服务端同步,保持一致
# h:表示使用密码技术得到的一次密码(但是由于h长度较大,不适合作为验证码,因此需要进一步截取
h = HMAC(K, C)
# otp:一次密码,通过对h进行截取处理(这里的digit代表需要截取的位数,通常情况下为6)
otp = Trunc(h, digit)
  • TOTP:time-based one time password,基于时间的一次密码,该技术需要客户端和服务端共享加密密钥K和更新周期Period并进行时钟同步,然后通过如下算法计算一次密码(验证码):
#  T表示当前时间,T0表示初始时间(一般为0,可省略)
# Period表示更新周期(一般为30秒)
# C表示基于时间生成的计数
C = (T - T0) / Period
# K:加密密码,作为HMAC密码算法输入,由于只有客户端和服务端共享,因此在不知道K的情况下,无法生成,保证安全性。
# C:计数器,客户端和服务端基于本地时间分别计算
# h:表示使用密码技术得到的一次密码(但是由于h长度较大,不适合作为验证码,因此需要进一步截取
h = HMAC(K, C)
# otp:一次密码,通过对h进行截取处理(这里的digit代表需要截取的位数,通常情况下为6)
otp = Trunc(h, digit)

descript

3.2 常见2FA对比

2FA模式 主要代表 安全性 易用性
服务端模式 手机验证码,邮箱验证码 低 (未使用加密技术,容易被窃取) 高(无需额外软件或设备)
OTP Googule Authenticator,Microsoft Authenticator 中(使用了加密技术,客户端和服务端分开生成,可以不依赖于网络环境) 中 (需要安装手机App)
UKey U盾 高 (通过挑战码&数字签名方式进行认证,安全性很高) 低(需要额外的硬件设备,携带不方便)

从上述对比上看:

  • UKey模式虽然提供了最高的安全性,但由于易用性比较低,只有在政务、金融、军工等关键领域才会用到。(该方式也是密评推荐的方式)
  • OTP模式基于手机App,需要进行安装。安装后易用性与手机验证码基本相同,同时该方式可用性比较高。
  • 服务端模式(手机/邮箱验证码)未使用密码技术,安全性较低,但是由于该方式不依赖于额外软硬件设备,易用性也最高。

值得注意的是,不管是手机验证码、TOTP或U盾模式,都不能保证通信的安全,因此需要配合安全通信协议TLS才能保证2FA流程的安全性。TLS原理和应用可

留下评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注

Index