OAuth
Last Edited Time
Feb 9, 2022 07:33 AM
date
Jan 3, 2018
slug
oauth
status
Published
tags
OAuth
Notebook
必读系列
summary
OAuth 相关介绍, 原文总结的比较好, 早期工作拿来给国外同事培训用了
type
Post
Oauth 1.0
作者:郭无心
链接:https://www.zhihu.com/question/19851243/answer/75070070
来源:知乎
+----------+ +----------+
| |--(A)- Obtaining a Request Token --------->| |
| | | |
| |<-(B)- Request Token ----------------------| |
| | (Unauthorized) | |
| | | |
| | +--------+ | |
| |>-(C)-| -+-(C)- Directing ---------->| |
| | | -+-(D)- User authenticates ->| |
| | | | +----------+ | Service |
| Consumer | | User- | | | | Provider |
| | | Agent -+-(D)->| User | | |
| | | | | | | |
| | | | +----------+ | |
| |<-(E)-| -+-(E)- Request Token ------<| |
| | +--------+ (Authorized) | |
| | | |
| |--(F)- Obtaining a Access Token ---------->| |
| | | |
| |<-(G)- Access Token -----------------------| |
+----------+ +----------+
- Get request token /oauth/1.0/request_token
**GET Params**
oauth_consumer_key // we need the consumer key to limit the consumer app privilege
oauth_signature_method // for encryption
oauth_signature // for encryption
oauth_timestamp // used with oauth_nonce together, because the server will not store all oauth_nonces(maybe only store for one hour)
oauth_nonce // prevent call current api mutiple times, the service provider will reject duplicate call
oauth_version //specific the oauth version
**Response**
oauth_token //request token, like the session id of current Authorization
oauth_token_secret //will use this field to get access token, determain current session is is yours
- Authorize (Normally popup window): /oauth/1.0/authorize
**GET**
oauth_token // request token (unauthorized)
oauth_callback // callback url after user authorize
**Response**
oauth_token // request token (authorized)
- Get access token: /oauth/1.0/access_token
**GET Params**
oauth_consumer_key
oauth_token // request token (authorized)
oauth_token_secret // request token secret, used to prevent user using fake request token
oauth_signature_method
oauth_signature
oauth_timestamp
oauth_nonce
oauth_version
**Response**
oauth_token // access token
oauth_token_secret // access secret
- if we don’t use request token, we need to call get access_token api. In that case, after the user Authorization and redirect to call back url, the consumer app will never know who’s access token
- 注:整个操作流程中,需要注意涉及两种 Token,分别是 Request Token 和 Access Token,其中 Request Token 又涉及两种状态,分别是未授权和已授权。
- Security issues: 1. 如果 Service Provider 没有限制回调地址(应用设置没有限定根域名一致),那么攻击者可以把 oauth_callback 设置成成自己的 URL,当 User 完成授权后,通过这个 URL 自然就能拿到 User 的 Access Token; 2. 如果 Consumer 不使用回调地址(桌面或手机程序),而是通过 User 手动拷贝粘贴 Request Token 完成授权的话,那么就存在一个竞争关系,只要攻击者在 User 授权后,抢在 User 前面发起请求,就能拿到 User 的 Access Token。
SO WE NEED THE OAUTH 1.0a
Oauth 1.0a
To fix oauth 1.0 security issues: 1. Consumer 申请 Request Token 时,必须传递 oauth_callback,而 Consumer 申请 Access Token 时,不需要传递 oauth_callback。通过前置 oauth_callback 的传递时机,让 oauth_callback 参与签名,从而避免攻击者假冒 oauth_callback; 2. Service Provider 获得 User 授权后重定向 User 到 Consumer 时,返回 oauth_verifier,它会被用在 Consumer 申请 Access Token 的过程中。攻击者无法猜测它的值
- Get request token /oauth/1.0a/request_token
**GET Params**
oauth_consumer_key
oauth_signature_method
oauth_signature
oauth_timestamp
oauth_nonce
oauth_version
oauth_callback // to prevent hacker change the callback url when applying access token
**Response**
oauth_token
oauth_token_secret
oauth_callback_confirmed // that field means the service provider support oauth 1.0a
- Authorize (Normally popup window): /oauth/1.0a/authorize
**GET**
oauth_token // request token (unauthorized)
**Response**
oauth_token // request token (authorized)
oauth_verifier // this field will be used in applying access token, otherwise if the hacker call consumer callback url directly with his request token. And the real user's account will bind with hacker's openid after the callback script finished.
- Get access token: /oauth/1.0a/access_token
**GET Params**
oauth_consumer_key
oauth_token // request token (authorized)
oauth_token_secret
oauth_signature_method
oauth_signature
oauth_timestamp
oauth_nonce
oauth_version
oauth_verifier
**Response**
oauth_token // access token
oauth_token_secret // access secret
Oauth2.0
In Oauth1.0a, we add a oauth_verifier after user authorization
In Oauth2.0, we remove the request token feature, and add state field both in /oauth/2.0/authorize sending and receiveing; In this case, oauth_verifier and state have same purpose
Authorization Code mode
+----------+
| resource |
| owner |
| |
+----------+
^
|
(B)
+----|-----+ Client Identifier +---------------+
| -+----(A)-- & Redirection URI ---->| |
| User- | | Authorization |
| Agent -+----(B)-- User authenticates --->| Server |
| | | |
| -+----(C)-- Authorization Code ---<| |
+-|----|---+ +---------------+
| | ^ v
(A) (C) | |
| | | |
^ v | |
+---------+ | |
| |>---(D)-- Authorization Code ---------' |
| Client | & Redirection URI |
| | |
| |<---(E)----- Access Token -------------------'
+---------+ (w/ Optional Refresh Token)
- Authorize /oauth/2.0/authorize
**GET**
response_type = code
client_id
redirect_uri
scope
state
**Response**
code
state
- Get access token: /oauth/2.0/access_token
**GET Params**
grant_type = authorization_code
code
client_id
client_secret
redirect_uri
**Response**
access_token
token_type
expires_in
refresh_token
Implicit Grant Code mode
+----------+
| Resource |
| Owner |
| |
+----------+
^
|
(B)
+----|-----+ Client Identifier +---------------+
| -+----(A)-- & Redirection URI --->| |
| User- | | Authorization |
| Agent -|----(B)-- User authenticates -->| Server |
| | | |
| |<---(C)--- Redirection URI ----<| |
| | with Access Token +---------------+
| | in Fragment
| | +---------------+
| |----(D)--- Redirection URI ---->| Web-Hosted |
| | without Fragment | Client |
| | | Resource |
| (F) |<---(E)------- Script ---------<| |
| | +---------------+
+-|--------+
| |
(A) (G) Access Token
| |
^ v
+---------+
| |
| Client |
| |
+---------+
- Authorize /oauth/2.0/authorize
**GET**
response_type = token
client_id
redirect_uri
scope
state
**Response**
access_token
token_type
expires_in
scope
state
Resource Owner Password Credentials mode and Client Credentials mode
+----------+
| Resource |
| Owner |
| |
+----------+
v
| Resource Owner
(A) Password Credentials
|
v
+---------+ +---------------+
| |>--(B)---- Resource Owner ------->| |
| | Password Credentials | Authorization |
| Client | | Server |
| |<--(C)---- Access Token ---------<| |
| | (w/ Optional Refresh Token) | |
+---------+ +---------------+
- Get access token: /oauth/2.0/token (Resource Owner Password Credentials mode)
**GET**
grant_type = password
username
password
scope
**Response**
access_token
token_type
expires_in
refresh_token
- Get access token: /oauth/2.0/token (Resource Owner Password Credentials mode)
**GET**
grant_type = client_credentials
client_id
client_secret
scope
**Response**
access_token
token_type
expires_in