OAuth2.0是一种主流的授权机制,主要用来颁发令牌(token)。
OAuth 的核心就是向第三方应用颁发令牌
令牌(token)与密码(password)
同:作用是一样,都可以进入系统。
异:
- 令牌是短期的,到期会自动失效,用户自己无法修改。密码一般长期有效,用户不修改,就不会发生变化。
- 令牌可以被数据所有者撤销,会立即失效。密码一般不允许被他人撤销。
- 令牌有权限范围(scope)。密码一般是完整权限。
运行流程
运行流程(标准 RFC 6749)
释义:
-
Client
:客户端,第三方应用,可以是浏览器、APP,也可以是内部服务 -
Resource Owner
:资源拥有者,最终用户,他有访问资源的账号与密码,可以简单把资源拥有者理解成人,他在使用客户端访问资源 -
Authorization Server
:认证(授权)服务器,用于认证用户,如果客户端认证通过,则发放给其访问资源服务器的令牌 -
Resource Server
:资源服务器,拥有受保护资源,如果请求包含正确的访问令牌,则可以访问资源,比如给客户端提供 API 服务 -
Access Token
:令牌,用于获取资源
流程
(A)用户(Resource Owner)打开客户端以后,客户端(Client)要求用户给予授权
(B)用户同意给予客户端授权
(C)客户端使用上一步获得的授权,向认证服务器(Authorization Server)申请令牌
(D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌(Access Token)
(E)客户端使用令牌,向资源服务器申请获取资源
(F)资源服务器确认令牌无误,返回被保护的资源信息
上述步骤中,(B)是关键,即用户怎样才能给于客户端授权,oauth2有四种授权方式:
- 授权码(authorization-code):功能最完整、流程最严密的授权模式,适用于那些有后端的 web应用。授权码通过应用传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。目前主流的第三方认证。
- 简化模式,隐藏式(implicit):有些web 应用是纯前端应用,没有后端,必须将令牌储存在前端。没有授权码这个中间步骤,直接向前端颁发令牌。纯前端应用的第三方认证。
- 密码模式(password):高度信任客户端,用户把用户名和密码直接告诉该客户端,该客户端通过用户的密码申请令牌。适用于公司自身搭建(非第三方的)的认证服务器。
- 客户端模式,凭证式(client credentials):不需要用户授权,严格说不属于OAuth框架所要解决的问题,客户端以自己的名义申请令牌。适用于不需要用户参与的完全信任的服务端。
授权码、简化模式需要从客户端跳转到认证服务器让用户授权,再跳转回客户端
密码模式和客户端模式不需要跳转
授权码模式需要通过跳转获取授权码,再通过授权码获取令牌
简化模式通过跳转直接获取到令牌
密码模式不需要跳转,通过账密直接获取令牌不管哪一种授权方式,第三方应用在申请令牌之前,都必须将自己的身份识别码备案在认证服务器:客户端 ID(client ID)和客户端密钥(client secret)。这是为了防止令牌被滥用,没有自身识别码的第三方应用,是不会拿到令牌的。
授权码模式
第三方应用先申请一个授权码,然后再用该码获取令牌。
(A)请求授权码:A 网站(第三方应用)提供一个链接,要求用户跳转到 B 网站(认证服务器)。
https://b.com/oauth/authorize?
response_type=code&
client_id=CLIENT_ID&
redirect_uri=CALLBACK_URL&
scope=read
response_type:表示要求返回授权码(code)
client_id:让 B 知道是谁在请求
redirect_uri:B 接受或拒绝请求后的跳转网址
scope:表示要求的授权范围(这里是只读)
(B)返回授权码:用户跳转后,B 网站会要求用户登录,然后询问是否同意给予 A 网站授权。用户表示同意,这时 B 网站就会跳回redirect_uri参数指定的网址。跳转时,会携带一个授权码。https://a.com/callback?code=AUTHORIZATION_CODE
(C)请求令牌:A 网站拿到授权码以后,A网站的后端向 B 网站请求令牌。
https://b.com/oauth/token?
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET&
grant_type=authorization_code&
code=AUTHORIZATION_CODE&
redirect_uri=CALLBACK_URL
client_id、client_secret:用来让 B 确认 A 的身份(client_secret参数是保密的,因此只能在后端发请求),
grant_type:AUTHORIZATION_CODE表示采用的授权方式是授权码,
code:上一步拿到的授权码
redirect_uri:令牌颁发后的回调网址。
(D)返回令牌:B 网站收到请求以后,就会返回令牌。
简化模式
不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了"授权码"这个步骤
(A)A 网站提供一个链接,要求用户跳转到 B 网站。
https://b.com/oauth/authorize?
response_type=token&
client_id=CLIENT_ID&
redirect_uri=CALLBACK_URL&
scope=read
(BCD)用户跳转到 B 网站,登录后同意给予 A 网站授权。B 网站就会跳回redirect_uri参数指定的跳转网址,并且把令牌作为 URL 参数,传给 A 网站。此时A网站拿到令牌。https://a.com/callback#token=ACCESS_TOKEN
密码模式
用户向客户端提供自己的用户名和密码。客户端使用这些信息,向授权服务器索要授权。
(ABC)A 网站要求用户提供 B 网站的用户名和密码。拿到以后,A 就直接向 B 请求令牌。
https://oauth.b.com/token?
grant_type=password&
username=USERNAME&
password=PASSWORD&
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET
(D)B 网站验证身份通过后,直接给出令牌。此时不需要跳转,A 通过http
响应结果直接拿到令牌。
客户端模式
客户端以自己的名义,而不是以用户的名义,向授权服务器索要授权
(C)A 应用向 B 发出请求。
https://oauth.b.com/token?
grant_type=client_credentials&
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET
(D)B 网站验证通过以后,直接返回令牌。