SpringSecurityOauth2系列學習(一):初認Oauth2


系列導航

SpringSecurity系列

SpringSecurityOauth2系列

初認Oauth2

hello!我又來啦!

之前我們學習了前后端分離的SpringSecurity架構,但是在微服務滿天飛的今天,前面學習的這種架構已經不適用了。

誒那么有沒有一種適用於微服務的安全框架呢?

當然就是SpringSecurityOauth2了。

有的小伙伴一看,這不還是SpringSecurity嘛,后面加了一個Oauth2后綴,啥是Oauth2啊?

別急,我們先來看看Oauth2的概念

Oauth2的概念

先說OAuth,OAuth是Open Authorization的簡寫。

OAuth協議為用戶資源的授權提供了一個安全的、開放而又簡易的標准。與以往的授權方式不同之處是

OAuth的授權不會使第三方觸及到用戶的帳號信息(如用戶名與密碼),即第三方無需使用用戶的用戶名與

密碼就可以申請獲得該用戶資源的授權,因此OAuth是安全的。

OAuth2.0是OAuth協議的延續版本,但不向前兼容(即完全廢止了OAuth1.0)。

使用場景

假設,A網站是一個打印照片的網站,B網站是一個存儲照片的網站,二者原本毫無關聯。

如果一個用戶想使用A網站打印自己存儲在B網站的照片,那么A網站就需要使用B網站的照片資源才行。

按照傳統的思考模式,我們需要A網站具有登錄B網站的用戶名和密碼才行,但是,現在有了OAuth2,只需要A網

站獲取到使用B網站照片資源的一個通行令牌即可!這個令牌無需具備操作B網站所有資源的權限,也無需永久有

效,只要滿足A網站打印照片需求即可。

這么聽來,是不是有點像單點登錄?NONONO!千萬不要混淆概念!單點登錄是用戶一次登錄,自己可以操作其

他關聯的服務資源。OAuth2則是用戶給一個系統授權,可以直接操作其他系統資源的一種方式。

但SpringSecurity的OAuth2也是可以實現單點登錄的!

總結一句:SpringSecurity的OAuth2可以做服務之間資源共享,也可以實現單點登錄!

角色說明

  • 應用(客戶端):客戶端就是一個要訪問用戶賬號的應用,需要得到用戶的允許后才可以得到授權
  • API服務(資源服務):資源服務通常提供API用於訪問用戶的授權客戶端訪問的信息
  • 授權服務:讓用戶批准或拒絕請求的服務,嚴格來說,認證不屬於這個服務的職責,雖然往往認證和授權都在一個服務。當然授權服務也可以是資源服務
  • 用戶(資源所有者):授權客戶端訪問資源服務器的主體

通常,作為作為OAuth2的客戶端 ,需要上傳這幾個字段:

  • Application name:應用名
  • HomepageURL:主頁,主要是域名
  • Authorization callback URL:回調地址,授權成功后返回的URL

然后系統對於每個客戶端會生成Client ID(必要,應用工具唯一標識)和Client Secret(非必要,可以理解為應用的密碼),請求授權要求客戶端傳入這兩個值進行授權

OAuth2.0中主流的四種授權方式

為了說明四種模式先准備一張圖

授權碼模式(authorization code

  • 流程

說明:【A服務客戶端】需要用到【B服務資源服務】中的資源

  1. 第一步:【A服務客戶端】將用戶自動導航到【B服務認證服務】,這一步用戶需要提供一個回調地址,以備【B服務認證服務】返回授權碼使用。

  2. 第二步:用戶點擊授權按鈕表示讓【A服務客戶端】使用【B服務資源服務】,這一步需要用戶登錄B服務,也就是說用戶要事先具有B服務的使用權限。

  3. 第三步:【B服務認證服務】生成授權碼,授權碼將通過第一步提供的回調地址,返回給【A服務客戶端】。

    注意這個授權碼並非通行【B服務資源服務】的通行憑證。

  4. 第四步:這個時候,通常會給用戶彈出一個頁面,詢問用戶是否同意授權給A服務,用戶點擊同意,然后【A服務認證服務】攜帶上一步得到的授權碼向【B服務認證服務】發送請求,獲取通行憑證token。

  5. 第五步:【B服務認證服務】給【A服務認證服務】返回令牌token和更新令牌refresh token。

  • 使用場景

授權碼模式是OAuth2中最安全最完善的一種模式,應用場景最廣泛,可以實現服務之間的調用,常見的微

信,QQ等第三方登錄也可采用這種方式實現。

簡化模式(implicit)

  • 流程

說明:簡化模式中沒有【A服務認證服務】這一部分,全部又【A服務客戶端】與B服務交互,整個過程不再有授權碼,token直接暴露在瀏覽器。

  1. 第一步:【A服務客戶端】將用戶自動導航到【B服務認證服務】,這一步用戶需要提供一個回調地址,以備【B服務認證服務】返回token使用,還會攜帶一個【A服務客戶端】的狀態標識state。

  2. 第二步:用戶點擊授權按鈕表示讓【A服務客戶端】使用【B服務資源服務】,這一步需要用戶登錄B服務,也就是說用戶要事先具有B服務的使用權限。

  3. 第三步:【B服務認證服務】生成通行令牌token,token將通過第一步提供的回調地址,返回給【A服務客戶端】。

  • 使用場景

    適用於A服務沒有服務器的情況。比如:純手機小程序,JavaScript語言實現的網頁插件等。

密碼模式(resource owner password credentials)

  • 流程
  1. 第一步:直接告訴【A服務客戶端】自己的【B服務認證服務】的用戶名和密碼

  2. 第二步:【A服務客戶端】攜帶【B服務認證服務】的用戶名和密碼向【B服務認證服務】發起請求獲取token。

  3. 第三步:【B服務認證服務】給【A服務客戶端】頒發token。

  • 使用場景

    此種模式雖然簡單,但是用戶將B服務的用戶名和密碼暴露給了A服務,需要兩個服務信任度非常高才能使用。

客戶端模式(client credentials)

  • 流程

    說明:這種模式其實已經不太屬於OAuth2的范疇了。A服務完全脫離用戶,以自己的身份去向B服務索取token。換言之,用戶無需具備B服務的使用權也可以。完全是A服務與B服務內部的交互,與用戶無關了。

  1. 第一步:A服務向B服務索取token。

  2. 第二步:B服務返回token給A服務。

  • 使用場景

    A服務本身需要B服務資源,與用戶無關。

JWS/JWK

Oauth2中返回的token其實也有很多種類型,SpringSecurityOauth2中授權服務器如果不做配置,那么默認返回的其實只是一串UUID。

那么我們使用怎樣的token呢?當然還是JWT啦!

SpringSecurityOauth2中授權服務器簽發的token還是使用非對稱加密進行簽名,但是其內部已經實現了相關邏輯,不再需要我們自己去寫邏輯,配置好之后直接使用即可。

不過這里還需要了解一個術語:JWS/JWK

JWT火爆之后,人們對於其安全性做了很多討論,其簽名也是人們討論的話題之一。JWT支持使用不同的算法進行簽名,但是沒有一個統一的方式。

JWS就是JWT簽名的驗證數據完整性的不同的加密機制

JWK就是簽名加密密鑰的JSON結構。一般情況下,對於簽名需要有一個不對稱加密,需要有密鑰對進行加密。

公鑰和私鑰。公鑰加密需要私鑰來解密,同樣的私鑰加密需要公鑰來解密。

一般公鑰和私鑰放在不同的地方,私鑰保存在服務器上面,而公鑰保存在客戶端。公鑰可以公開,私鑰保密。

簽發token使用私鑰加密,簽名。token的內容是公開的,但是token的簽名驗證需要公鑰去解密驗證,沒有私鑰是偽造不出來私鑰加密的簽名的。只要驗證成功,說明這個token是使用私鑰簽發的,是可以信任的

流程:

  1. 客戶端請求Access Token,資源服務器返回一個使用JWS簽名的一個JWT,這里的JWS包含一個Kid,其為一種加密形式的唯一標識,表示了應該使用說明方式進行加密。
  2. 客戶端請求資源,將使用JWS簽名的一個JWT傳遞給資源服務器,資源服務器會向授權服務器請求一個公鑰,授權服務器會把JWK(即Kid對應的這種密鑰結構)返回給資源服務器,之后資源服務器就使用這個公鑰去驗證簽名,去驗證權限。

加密流程

加密流程也就是創建JWT的過程

拿私鑰進行非對稱加密,將kid和其kid value寫入jws的header中,然后在進行Claims聲明進行編碼

然后將jws header放入簽名這個字段里面去,進行編碼

最后就形成了有header,有cliams,有簽名的一個jwt

解密流程

拿到JWT之后,去請求一個公鑰,對這個JWT進行一個解析

解析完成之后,得到簽名,然后取出其中Kid為key對應的Kid value

然后將Kid value設置到簽名當中

然后在去驗證簽名是否正確


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM