為什麼OAuth2裡面在獲取access token之前一定要先獲取code,然後再用code去獲取access token?知乎使用者2016-10-19 17:42:40

更新

先確認一下 oauth2 code 認證的角色

1,client——通常是我們開發的 app

2,owner——使用我們 app 的使用者

3,auth server——在 owner 授權後,為 client 提供介面來訪問資源

認證過程

1,client 獲取code時,auth server是不能確認client的身份的,因為這時auth server只有一個app id,但沒有任何手段來確認 client 使用的是自己的 app id

2,owner 在 auth server 上認證身份,並同意授權給 client

3,auth server 向 client 傳送一個 code,按 oauth2 的協議約定,該 code 透過瀏覽器的 302 重定向傳送給 client

4,client 拿 code 換取 token,首先,這個過程是 client 後臺對 auth server 後臺的,其次,client 需要提供自己的 app secret,這樣就為 auth server 提供了一種驗證 client 的機制

那麼為什麼要這個code?

關鍵還是第三步:auth server 把 code 傳送給 client 這一步不安全,因為 client 可能會用一個 http 協議的介面來接收 code,那麼 code 就會被擷取

如果在這一步把 token 返回去,有 2 個問題

1)必須在第一步就提供 app secret,使 auth server 能夠驗證 client 的身份,這對於 client 的 app secret 來說是不安全的

2)如果 client 指定的 redirect_url 是 http 協議,token 可以在傳輸過程中被擷取導致洩漏

What is the OAuth 2。0 Authorization Code Grant Type?

其中有段話是這樣的

The code exchange step ensures that an attacker isn’t able to intercept the access token, since the access token is always sent via a secure backchannel between the application and the OAuth server。

再延伸一下:

拿到 token 後,client 在後續的請求裡,token 還是直接傳送給 auth server (這個時候其實已經是 resource server 了)的,這個時候就不能截取了嗎?

答案是 https——雖然 oauth2。0 協議沒有明文要求 auth server 使用 https,但實際上 auth server 提供的介面都是 https 的,作為 app 開發者可以留意一下,看看有哪個提供 oauth 認證服務的廠家不用 https 的

原答案

很簡單,client是怎麼拿到code的?

code 是透過瀏覽器重定向獲取的,你在瀏覽器位址列就可以看到,如果這一步不返回code而是直接返回access token,那麼這個token其實已經暴露了

而client拿到code以後換取access token是client後臺對認證伺服器的訪問,不依賴瀏覽器,access token不會暴露出去

為什麼OAuth2裡面在獲取access token之前一定要先獲取code,然後再用code去獲取access token?攢著2018-10-30 17:45:22

想問一下 oauth2回收token之後再獲取為什麼獲取不到了?

為什麼OAuth2裡面在獲取access token之前一定要先獲取code,然後再用code去獲取access token?Lee2020-02-15 21:27:12

因為整個oauth2的流程,不只要資源擁有者同意,還需要驗證客戶端的身份。

整個OAuth2中的授權碼模式分為兩大步驟:

假設 你 是一個客戶端

你首先需要取得資源擁有者的同意:你需要提供app_id給授權認證伺服器,當資源擁有者在授權認證伺服器提供的表單登入成功且同意後,你會取得一個code,這個code跟你提供的app_id所繫結。

你然後需要取得授權認證伺服器的同意:你提供code,授權認證伺服器知道資源擁有者同意了你獲取資源,但是授權認證伺服器需要你證明 你是你的 問題,所以你需要提供app_secret,當code和app_secret同時存在,且app_secret對應你的code所繫結的app_id時,整個授權成功結束。

為什麼OAuth2裡面在獲取access token之前一定要先獲取code,然後再用code去獲取access token?Authing 身份雲2020-11-12 14:51:21

OAuth2 授權碼模式的認證流程中涉及三方:使用者、OAuth2 伺服器(OP,OAuth2 Provider)、應用業務伺服器(SP,Service Provider)。

SP、使用者、OP 的互動目的分為以下幾點:

SP 希望拿到一個可信的身份斷言,從而讓使用者登入。

SP 發起登入,會跳轉到 OP 的認證頁面,OP 讓使用者登入,並授權自己的資訊,然後 OP 將一個授權碼 code 發給 SP。實際上這是在透過引用來傳遞使用者資訊。

SP 收到授權碼 code 後,結合 Client ID 和 Client Secret 到 OP 換取該使用者的 access_token。

SP 利用 access_token 到 OP 去獲取使用者的相關資訊,從而得到一個可信的身份斷言,讓使用者登入。

OAuth2 協議中,使用者登入成功後,OAuth2 認證伺服器會將使用者的瀏覽器回撥到一個回撥地址,並攜帶一個授權碼 code。這個授權碼 code 一般有效期十分鐘且一次有效,用後作廢。這避免了在前端暴露 access_token 或者使用者資訊的風險,access_token 的有效期都比較長,一般為 1~2 個小時。如果洩露會對使用者造成一定影響。

後端收到這個 code 之後,需要使用 Client Id + Client Secret + Code 去 OAuth2 認證伺服器換取使用者的 access_token。在這一步,實際上 OAuth2 Server 對 OAuth Client 進行了認證,能夠確保來 OAuth2 認證伺服器獲取 access_token 的機器是可信任的,而不是任何一個人拿到 code 之後都能來 OAuth2 認證伺服器進行 code 換 token。

如果 code 被駭客獲取到,如果他沒有 Client Id + Client Secret 也無法使用,就算有,也要和真正的應用伺服器競爭,因為 code 一次有效,用後作廢,加大了攻擊難度。

相反,如果不經過 code 直接返回 access_token 或使用者資訊,那麼一旦洩露就會對使用者造成影響。

想獲取更多身份認證相關的內容,請訪問

Authing 的 blog

為什麼OAuth2裡面在獲取access token之前一定要先獲取code,然後再用code去獲取access token?義臻2020-11-12 20:11:23

我先把這個問題翻譯一下:為什麼不是由IDP直接返回Access Token。

回答:在授權碼授權模型中,客戶端和IDP的交流是透過UA(瀏覽器)以302重定向的方式完成的。也就是說IDP給客戶端的一切東西,都要經過UA轉手。

而Access Token是一個訪問token,只要持有該token就可以訪問受保護資源,而不再需要其他任何形式的呼叫者身份認證。

所以問題就變成了:你要給別人一把金庫鑰匙,任何人只要拿著鑰匙就可以進入金庫。而偏偏傳遞鑰匙的過程中要有一個並不被信任的中間人。那為了安全,你的策略是什麼?

在金庫上加認證機制,比如人臉識別,只有人臉識別透過且持有鑰匙的人才能進去金庫。這樣,即便中間人偷了鑰匙,也會因為人臉識別不透過而無法進入金庫。

委託中間人給對方一個臨時憑證,然後告訴對方本人拿著臨時憑證換鑰匙。這樣,即便中間人偷了臨時憑證,也無法和你換鑰匙。

方案一和方案二本質是一樣的,只不過驗證對方身份的過程從由金庫完成到由你自己完成。

很明顯,OAuth選擇了方案二,因為這樣的方案受保護資源一方的接入成本最低。