理解OAuth2.0


OAuth2.0是什么?

  OAuth2.0是方便给第三方应用程序授权的标准授权协议(RFC749),注意是授权协议(authentication ),不是认证(authorization).

OAuth2.0相关名词定义

  1. Resource Owner: 资源拥有者,也就是一般用户
  2. Third-party Application: 第三方应用
  3. User Agent: 用户代理,可以是浏览器等
  4. Authorization server: 认证服务器
  5. Resource server: 资源服务器,一般是Api接口,等等需要被保护的资源.

理解OAuth2.0

OAuth2.0的应用是很广泛的,作为开发者可以

  • 可以将自己的应用程序作为微信第三方客户端接入,获取用户拥有者在微信的头像,性别,等用户信息
  • 结合时下流行的SpringCloud,搭建授权服务器,资源服务器,为分布式服务做统一的认证

下面理解下流程最完善的的授权码模式, 其他模式就很好理解了.

1.资源拥有者(即用户),使用浏览器(客户端代理)访问第三方应用(SPA),SPA将资源拥有者导向认证中心

[GET] /uaa/authorize?
response_type=code
&client_id=s6BhdRkqt3
&state=mark
&redirect_uri=www.client.example.com/xx

参数解释

response_type:	表示授权类型,必选,授权码模式这步固定为"code"
client_id:	表示客户端的ID,必选
redirect_uri:	表示重定向的url,可选
scope:		表示申请选项的范围,可选
state:		表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值(可以标记页面位置)

假设用户登录认证中心,并且授权第三方客户端的请求

则UAA跳转到redirect_uri并且附加授权码

http://client.example.com/xx
?code=12345
&state=mark

2.前端服务器从回调地址中获取授权码并且携带存储在前端服务器的client_secret,到认证中心获取令牌.

这个步骤在后台完成对用户不可见.

注意客户端密钥不能放在浏览器(用户代理),因为这样是不安全的,应该放在客户端的后台服务器.

[POST]
/uaa/authorize
grant_type=authorization_code
&code=12345
&redirect_uri=https://client.example.com/xx

参数说明

参数说明:
response_type:	表示授权类型,必选,授权码模式这步固定为"authorization_code",必选
code:		授权码,必选
redirect_uri:	重定向URL,必选
client_id:	客户端ID.必选

3.认证服务器核对授权码和回调地址,颁发令牌

令牌的样式和存储方式是多种多样的,可以存放在Redis中,也可以是不需要后台存储的JWT令牌

{
"access_token":"123456",
"token_type":"example",
"expires_in":3600,
"refresh_token":"654321",
}

4.第三方应用携带令牌访问资源服务器,资源服务器携带令牌去授权服务器,验证权限通过,则可以访问资源。

思考

1.资源服务器每次都需要和UAA交互,验证令牌,这样是否影响性能?

每次调用资源服务器的API,都需要资源服务器和认证中心验证令牌,可不可以优化?
使用JWT令牌,资源服务器自身使用密钥校验令牌的是否正确.(JWT防篡改,但是不加密安全的)

2.使用JWT有没有其他问题?

使用JWT,减轻了压力,但是JWT令牌在有效期内,无法销毁,无法强制用户下线,或者但设备登录,因此需要权衡业务背景

3. 结合OAuth2.0 如何做单点登录

多个SPA在将用户导向认证中心时,SPA维护与Node的session粘性,前端服务器在此维护与认证中心uua.com的session粘性,即可实现单点登录

参考:

(RFC6749)https://datatracker.ietf.org/doc/html/rfc6749
(OAuth2.0)https://oauth.net/2/
(OAuth2.0)https://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html