簡體   English   中英

REST Web服務的身份驗證

[英]Authentication for REST web services

我開始設計REST Web服務,並且不清楚最佳的身份驗證方法。 該服務將允許個人用戶訪問/管理他們自己的數據,因此需要某種類型的用戶身份驗證。 我一直在看這些選項:

  • OAuth的

OAuth似乎更多的是授權而不是身份驗證。 我計划在服務中本地處理授權,所以我不是在尋找解決方案。 但是,OAuth是否也適用於身份驗證?

  • OpenID的

OpenID當然提供了身份驗證的解決方案,但這更適合允許用戶使用他們的第三方憑據(谷歌,雅虎等)雖然我想支持這一點,但這不是我主要關注的問題,我會絕對允許用戶使用本機憑據(電子郵件/密碼)注冊。

  • HTTP基本身份驗證

這很容易實現,但我的理解是,這可能不是一個非常安全的方法。 此外,似乎需要為每次訪問交換憑據,但我更希望用戶進行一次身份驗證,然后通過會話令牌繼續訪問。

  • 自定義驗證

基本上,滾動我自己的登錄/令牌生成服務,並需要一個有效的令牌來訪問所有其他資源(顯然,一切都將通過SSL)。


除了創建Web服務之外,我還將構建一個代表用戶使用這些服務的客戶端(Web)應用程序,但我不希望應用程序必須存儲用戶信息/憑據等。 所以,像這樣:

用戶(使用電子郵件/密碼或第三方憑據進行身份驗證) - > Web應用程序(使用應用程序ID進行身份驗證) - > Web服務

而且,我想讓其他人也建立客戶端,所以中間層可以是任何第三方應用程序:

用戶(使用電子郵件/密碼或第三方憑據進行身份驗證) - >第三方應用程序(使用應用程序ID進行身份驗證) - > Web服務

我的頂級要求是:

  • 安全(顯然)
  • 本機憑據
  • 支持第三方憑據(谷歌,雅虎,LinkedIn等)
  • 支持多個客戶端(Web應用程序,移動應用程序,第三方應用程序等)
  • 客戶端憑據(只是應用程序ID?)
  • 到期的登錄會話
  • 不需要授權

所以,我的問題是,基於上述情況(如果這太模糊,請告訴我),是否有“最佳”方法? OAuth或OpenID是否合適,或者我是否過於復雜,而應該只使用自己的身份驗證?

編輯:

我想我需要實現以下內容:

1)原生憑證/令牌(通過SSL進行HTTP基本身份驗證?)

2)OpenID“依賴方”允許我的api使用其他地方托管的OpenID(即“支持第三方憑證”)

3)OAuth“Consumer”允許我的api訪問第三方服務(比如訪問用戶的LinkedIn個人資料)。

4)一個OpenID“提供者”,允許人們在別處使用api的本地ID(可選)

5)OAuth“提供商”允許第三方應用代表用戶訪問我的API(可選)

這看起來是對的,還是我讓它變得比它需要的更復雜?

您可以考慮使用JWT(JSON Web Token)查看JWT草案rfc 它肯定會滿足您的安全性和會話到期要求。 然而,作為草案標准,它現在不太可能被廣泛使用,這可能會很快改變,因為JWT是OAuth 2.0的一部分。 JWT很容易在大多數語言中實現,並且已經有很多庫。 作為一個簡單的解釋,JWT令牌由3個部分組成,即標題,正文和簽名。 標題和正文是json對象,它們是basee64url編碼的(字母表與base64的2個最后字符不同),然后用HMAC256(或標題中指定的其他算法)簽名,RFC解釋了如何准確生成此簽名。 您可能想要檢查此在線令牌生成器

JWT是http標頭和查詢參數友好。

要考慮的一個好選擇是“共享密鑰身份驗證”。 這是Amazon Web服務和Windows Azure存儲服務使用的身份驗證類型。 我們在我們開發的REST服務中使用了共享密鑰身份驗證。 您可以在Google上快速搜索“共享密鑰身份驗證”,您將獲得大量詳細信息。

在這里寫了一篇關於此的博客文章。

高級步驟是:

  1. 客戶端組合了REST服務定義的一組唯一數據(元素)。
  2. 使用僅為客戶端和REST服務所知的密鑰對此組合數據進行簽名
  3. 將此簽名作為HTTP標頭的值發送到REST服務
  4. REST服務以與客戶端完全相同的方式計算簽名
  5. 將客戶端發送的簽名與計算的簽名進行比較,如果相同則假設其有效請求,否則拒絕該請求

我的建議是驗證第一個請求,然后設置會話令牌。

前端應用程序將存儲令牌並為每個后續請求提供令牌。

令牌將具有到期時間。 如果在特定時期內未使用令牌,則令牌將過期。

令牌可以與始發IP地址相關聯以增加安全性。

令牌可以作為cookie傳輸,也可以作為URL中的查詢參數之一傳輸。

如果可以接受SSL客戶端身份驗證的麻煩,則可以使用相互SSL身份驗證。 必須為每個客戶端配置服務器信任的證書。 如果您必須以不同方式對待客戶,它可以是相同的證書,也可以是不同的證書。

根據您的要求,我認為OAuth 2.0實際上可能是一個有趣的選擇。 OAuth確實是一種授權協議,但它也使用clientIdclientSecret對客戶端進行Authenticates 您可以使用Client Credential Flow並選擇不包含Refresh Token ,這樣用戶就擁有一個Access Token ,該Access Token在一定時間后過期。 由於OAuth是一種廣泛使用的協議,因此它們已經有許多客戶端和服務器端庫供您和您的客戶使用。

如果您認為OAuth對於您的應用程序來說太沉重或太復雜,我可能會堅持使用HTTPS進行Basic Authentication 但正如我在另一個類似問題的答案中所述,我絕不會發明自己的身份驗證機制。

有關更多信息,您還可以查看我之前給出的類似問題的其他答案: https//stackoverflow.com/a/15003777/849741

您可以使用HTTP Basic Auth,其中轉移的密碼實際上不是密碼而是令牌,客戶端在不同的資源請求上獲取,其中他/她/它必須提供一次且僅一次的密碼(也許甚至在不同的渠道)。 這不能保證中間人攻擊(因為沒有消息簽名),但想法是,你總是可以要求客戶端以某種方式生成動態令牌(即在你自己的auth服務上),然后讓它將該令牌作為密碼替換發送,因此實際密碼不會經常通過線路傳輸。 是的,這看起來像是“自定義身份驗證解決方案”之一,但實際上並不是因為您可以在令牌密碼上強加您想要的規則,例如使用簽名令牌作為會話綁定或重新計算的密碼在每個請求(不共享任何秘密)上,以便服務器可以驗證消息 - 您的需求是什么。 我們的想法是將驗證令牌作為HTTP Basic Auth請求的“密碼”發送,而不是依賴於更復雜的協議,而不是將它們排除在外(根據您的選擇)。

我已經實現並發布了一個允許身份驗證的基本服務作為開源,它可以很容易地更改為允許3元組登錄(如果需要)。 它大約有2年的歷史,用Java編寫,因此你可能想重新考慮這項技術,但是它可以運行,你可以了解它是如何完成的。 在谷歌上找到它,或關注我的博客文章 請注意,該應用不再加載到雲端,但如果您在帳戶中設置該應用,則一切正常。

我建議將Spring Boot用於RESTful Web服務,因為這樣您就可以使用Spring Security根據其模板實現自己的自定義身份驗證。 您可以通過分別擴展或實現其基本安全性類和接口來實現自己的自定義身份驗證。 如果需要,您還可以選擇合並您在Spring Boot中列出的其他auth機制。

如果您只需要授權,則可以使用OAuth 2.0。您可以使用OpenID Connect ,它提供身份驗證並支持OAuth2.0進行授權。 對於OepnID Connect,如果您需要自己設置服務,可以使用許多認證產品,也有許多在線服務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM