Spring Security 與 OAuth2 介紹

我的 OAuth2 所有文章

摘要:使用OAuth2 認證的好處就是你只須要一個帳號密碼,就能在各個網站進行訪問,而面去了在每一個網站都進行註冊的繁瑣過程,如:不少網站均可以使用微信登陸,網站做爲第三方服務、微信做爲服務提供商json

OAuth2 角色

  • resource owner:資源全部者(指用戶)
  • resource server:資源服務器存放受保護資源,要訪問這些資源,須要得到訪問令牌(下面例子中的 Twitter 資源服務器)
  • client:客戶端表明請求資源服務器資源的第三方程序(下面例子中的 Quora)客戶端同時也多是一個資源服務器
  • authrization server:受權服務器用於發放訪問令牌給客戶端(下面例子中的 Twitter 受權服務器)

OAuth2 工做流程例子

  • 客戶端 Quora 將本身註冊到受權服務器上
  • 用戶訪問 Quora 主頁,它顯示了各類登錄選項
  • 當用戶點擊使用 Twitter 登錄時,Quora 打開一個新窗口,將用戶重定向到 Twitter 的登錄頁面上
  • 在這個新窗口中,用戶使用他的帳號密碼登錄了 Twitter
  • 若是用戶以前未受權 Quora 應用程序使用他們的數據,則 Twitter 要求用戶受權 Quora 來訪問用戶信息權限,若是用戶已受權 Quora,此步驟則被跳過
  • 通過正確的身份驗證,Twitter 將用戶和一個身份驗證代碼重定向到 Quora 的重定向 URI
  • Quora 發送客戶端 ID、客戶端令牌和身份驗證代碼到 Twitter
  • Twitter 驗證這些參數後,將訪問令牌發送到 Quora
  • 成功獲取訪問令牌後用戶被登錄到 Quora 上,用戶登陸 Quora 後點擊他們的我的資料頁面
  • Quora 從 Twitter 資源服務器請求用戶的資源,併發送訪問令牌
  • Twitter 資源服務器使用 Twitter 受權服務器驗證訪問令牌
  • 成功驗證訪問令牌後,Twitter 資源服務器向 Quora 提供所須要的資源
  • Quora 使用這些資源,並最終顯示用戶的我的資料頁面
 

OAuth2 受權模式(出自阮一峯OAuth2博客)

受權碼模式

  • 受權碼模式是功能最完整、流程最嚴密的受權模式,它的特色是經過客戶端的後臺服務器,與「服務器提供」的認證服務器進行互動
 
9434708-a464c0c64ca6ee9a.png
  • 它的步驟以下:
    • (A)用戶訪問客戶端,後者將前者導向認證服務器
    • (B)用戶選擇是否給予客戶端受權
    • (C)假設用戶給予受權,認證服務器將用戶導向客戶端事先指定的「重定向 URI」,同時附上一個受權碼
    • (D)客戶端收到受權碼,附上早先的「重定向 URI」向認證服務器申請令牌,這一步是在客戶端的後臺服務器上完成的,對用戶不可見
    • (E)認證服務器覈對了受權碼和重定向URI,確認無誤後向客戶端發送令牌和更新令牌
  • 上述步驟中所須要的參數:
    • A步驟中,客戶端申請認證的 URI,包含如下參數:
      • repsone_type:受權類型,必選,此處固定值「code」
      • client_id:客戶端的ID,必選
      • client_secret:客戶端的密碼,可選
      • redirect_uri:重定向URI,可選
      • scope:申請的權限範圍,可選
      • state:客戶端當前的狀態,能夠指定任意值,認證服務器會原封不動的返回這個值
      GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz
      &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
      Host: server.example.com
    • C步驟中,服務器迴應客戶端的URI,包含如下參數:
      • code:表示受權碼,必須按,該碼有效期應該很短,一般10分鐘,客戶端只能使用一次,不然會被受權服務器拒絕,該碼與客戶端 ID 和 重定向 URI 是一一對應關係
      • state:若是客戶端請求中包含着歌參數,認證服務器的迴應也必須如出一轍包含這個參數
      HTTP/1.1 302 Found Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA &state=xyz 
    • D步驟中,客戶端向認證服務器申請令牌的HTTP請求,包含如下參數:
      • grant_type:表示使用的受權模式,必選,此處固定值爲「authorization_code」
      • code:表示上一步得到的受權嗎,必選
      • redirect_uri:重定向URI,必選,與步驟 A 中保持一致
      • client_id:表示客戶端ID,必選
      POST /token HTTP/1.1
      Host: server.example.com
      Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
      Content-Type: application/x-www-form-urlencoded
      
      grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
      &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
    • E步驟中,認證服務器發送的HTTP回覆,包含如下參數:
      • 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":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter":"example_value" } 
    • 從上面代碼能夠看到,參數使用 JSON 格式發送(Content-Type: application/json),才外,HTTP頭信息中明確指定不得緩存

簡化模式

  • 簡化模式不經過第三方應用程序的服務器,直接在瀏覽器中向認證服務器申請令牌,跳過了「受權碼」這個步驟
 
bg2014051205.png
  • 它的步驟以下:
    • (A)客戶端將用戶導向認證服務器
    • (B)用戶決定是否給予客戶端受權
    • (C)假設用戶給予受權,認證服務器將用戶導向客戶端指定的「重定向URI」,並在URI的Hash部分包含了訪問令牌
    • (D)瀏覽器向資源服務器發出請求,其中不包括上一步收到的Hash值
    • (E)資源服務器返回一個網頁,其中包含了代碼能夠獲取Hash值中的令牌
    • (F)瀏覽器執行上一步得到的腳本,取出令牌
    • (G)瀏覽器將令牌發給客戶端
  • 上述步驟中所須要的參數:
    • A步驟中,客戶端發出HTTP請求,包含如下參數:
      • response_type:表示受權類型,此處固定值爲"token",必選
      • client_id:表示客戶端ID,必選
      • redirect_uri:表示重定向URI,可選
      • scope:表示權限範圍,可選
      • state:表示客戶端當前狀態,可指定任意值,認證服務器會原封不動返回這個值
      GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz
      &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
      Host: server.example.com
    • C步驟中,認證服務器迴應客戶端的URI,包含如下參數:
      • access_token:表示訪問令牌,必選
      • token_type:表示令牌類型,該值大小寫不敏感,必選
      • expires_in:表示過時時間,單位爲秒
      • scope:表示權限範圍,若是與客戶端申請的範圍一致,可忽略
      • state:若是客戶端請求中包含這個參數,認證服務器也要返回如出一轍的參數
      HTTP/1.1 302 Found Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA &state=xyz&token_type=example&expires_in=3600 
  • 上面例子中,認證服務器用HTTP頭信息的Location欄,指定瀏覽器重定向的網址,注意,這個網址的Hash部分包含了令牌
  • 根據D步驟,下一步瀏覽器會訪問Location指定的網址,可是Hash部分不會被髮送,接下來的E步驟,服務提供商的資源服務器發送過來的代碼,提取出Hash令牌

密碼模式

  • 密碼模式中,用戶向客戶端提供本身的用戶名和密碼,客戶端使用這些信息向「服務提供商」索要受權瀏覽器

  • 在這種模式中,用戶必須把密碼給客戶端,但客戶端不得存儲密碼,這一般在用戶對客戶端高端信任的狀況下,好比客戶端是操做系統的一部分,由一個著名的公司出品,而認證服務器只有在其它受權模式沒法執行的狀況下,才考慮該模式緩存

 
9434708-6165f69e2bfc8881.png
  • 它的步驟以下:
    • (A)用戶向客戶端提供用戶名和密碼
    • (B)客戶端將用戶名密碼發送認證給服務器,向後者請求令牌
    • (C)認證服務器確認無誤後,向客戶端提供訪問令牌
  • 上述步驟中所須要的參數:
    • B步驟中,客戶端發出HTTP請求,包含如下參數:
      • grant_type:受權類型,必選,此處固定值「password」
      • username:表示用戶名,必選
      • password:表示用戶密碼,必選
      • scope:權限範圍,可選
      POST /token HTTP/1.1
       Host: server.example.com
       Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
       Content-Type: application/x-www-form-urlencoded
      
       grant_type=password&username=johndoe&password=A3ddj3w
    • C步驟中,認證服務器向客戶端發送訪問令牌,下面是一個例子:
      HTTP/1.1 200 OK
       Content-Type: application/json;charset=UTF-8
       Cache-Control: no-store
       Pragma: no-cache
      
       {
         "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter":"example_value" } 

客戶端模式

  • 客戶端模式指客戶端以本身名義,而不是用戶名義,向「服務提供商」進行認證,嚴格地說,客戶端模式不屬於OAuth框架要解決的問題,在這種模式中,用戶直接向客戶端註冊,客戶端以本身名義要求「服務提供商」提供服務
 
bg2014051207.png
  • 它的步驟以下:
    -(A):客戶端向認證服務器進行身份認證,並要求一個訪問令牌
    -(B):認證服務器確認無誤後,向客戶端提供訪問令牌ruby

  • 上述步驟中所須要的參數:bash

    • A步驟中,客戶端發出HTTP請求,包含如下參數:服務器

      • granttype:表示受權類型,此處固定值爲「clientcredentials」,必選
      • scope:表示權限範圍,可選
      POST /token HTTP/1.1
       Host: server.example.com
       Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
       Content-Type: application/x-www-form-urlencoded
       grant_type=client_credentials
    • B步驟中,認證服務器向客戶端發送訪問令牌,下面是一個例子微信

      HTTP/1.1 200 OK
       Content-Type: application/json;charset=UTF-8
       Cache-Control: no-store
       Pragma: no-cache
      
       {
         "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "example_parameter":"example_value" } 

更新令牌

  • 若是用戶訪問的時候,客戶端「訪問令牌」已通過期,則須要使用「更新令牌」申請一個新的令牌
  • 客戶端發出更新令牌請求,包含如下參數:
    • granttype:表示受權模式,此處固定值爲「refreshtoken」,必選
    • refresh_token:表示早前收到的更新令牌,必選
    • scope:表示申請權限範圍,不得超出上一次申請的範圍,若省略該參數,則表示與上一次同樣
    POST /token HTTP/1.1
     Host: server.example.com
     Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
     Content-Type: application/x-www-form-urlencoded
     grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA


本文轉載自併發

做者:林塬app

來源:簡書框架

連接:https://www.jianshu.com/p/68f22f9a00ee

相關文章
相關標籤/搜索