簡體   English   中英

Spring OAuth2 - JWT 令牌在服務器上工作但不在本地主機上?

[英]Spring OAuth2 - JWT token working on server but not on localhost?

我看到myapp能夠在服務器上正確處理 OAuth2 JWT 令牌,但它在本地主機上給出令牌轉換錯誤。

我的流程如下 -

在 Server上, myapp位於我們自定義api-gateway后面

  1. 獲取訪問令牌- 通過 postman,我點擊了 api-gateway 令牌端點,該端點又調用了 authserver 令牌端點。 我得到 OAuth JWT 令牌作為響應。

所以,總而言之,postman
請求: --(creds)--> api-gateway --(samecreds)--> auth-server
響應: jwt 令牌 <-- (same jwt)-- api-gateway <--(jwt)-- auth-server

  1. 接下來,我點擊myapp端點- 再次通過 postman,我點擊 api-gateway 端點,而后者又點擊相應的myapp端點。 我得到了所需的響應。 對於這個請求,在到達 api-gateway 之前,我設置了 header Authorization: Bearer JWT from step1

作為myapp開發人員,我知道 api-gateway 使用相同的 header 機制(即Authorization: Bearer JWT from step1 )將 JWT 令牌重新發送到myapp 從日志中,我看到這與我在訪問api-gateway時在 postman 中提供的值相同

所以,postman 請求:--(jwt)--> api-gateway --(same jwt)--> myapp
並且響應是一些數據,這對於本次討論來說是微不足道的。

解碼后的 JWT Payload 如下:

{
  "app-userId": "c54a-4140-9fa0-0f39",
  "user_name": "abc@xyz.com",
  "scope": [
    "all"
  ],
  "exp": 1656929583,
  "authorities": [
    "app1_viewer",
    "app1_modifier",
    "app2_viewer",
    "app2_blog_creator],
  "client_id": "api-gw-client"
  ...
}

請注意 - "client_id": "api-gw-client"字段。 所以 auth-server 正在向api-gateway客戶端發出令牌。


現在在 mylocal dev env 上,即在 localhost 上運行的myapp - 我正在嘗試實現與服務器上類似的流程。

在 localhost 上,myapp 不是在 api-gateway 后面運行,而是直接命中

  1. 獲取訪問令牌 - 通過 postman,我點擊了 api-gateway(與上面的服務器流程相同的服務器實例。即 api-gateway/auth-server 未在 localhost 上運行,但在服務器上運行)令牌端點依次調用 authserver 令牌端點。 我得到 OAuth JWT 令牌作為響應。

所以,postman 請求:--(creds)--> api-gateway --(samecreds) --> auth-server
響應:jwt 令牌 <-- (same jwt)-- api-gateway <--(jwt)-- auth-server

是的,此令牌可以在服務器流程步驟 2 中使用,並且可以正常工作。 解碼后的 JWT 令牌有效負載與我之前發布的相同,即

{
  "app-userId": "c54a-4140-9fa0-0f39",
  "user_name": "abc@xyz.com",
  "scope": [
    "all"
  ],
  "exp": 1656929583,
  "authorities": [
    "app1_viewer",
    "app1_modifier",
    "app2_viewer",
    "app2_blog_creator],
  "client_id": "api-gw-client"
  ...
}

請再次注意 - "client_id": "api-gw-client"字段。 所以 auth-server 正在向api-gateway客戶端發出令牌。 我還不確定這個領域是微不足道的還是重要的。

  1. 接下來,我點擊myapp localhost 端點- 再次通過 postman,但我直接點擊myapp端點(不是通過在 localhost 上運行的 api-gateway)。 對於這個請求,在點擊之前,我Authorization: Bearer JWT from step1

但是這次我得到了錯誤:

paOAuth2AuthenticationProcessingFilter:身份驗證請求失敗:error="invalid_token", error_description="Cannot convert access token to JSON"

我想知道是什么導致了這個錯誤。 我不認為client_id: api-gw-client導致了這種情況。 無論如何,我使用client_id: myapp創建了一個簽名的 jwt 令牌並在請求中使用它。 但我仍然得到同樣的錯誤。
我在 localhost 上使用的key與 auth-server 用於簽名的密鑰匹配(對應)。 我仔細檢查了一遍。 所以它肯定不是一個key問題。

我需要基於 localhost 的設置工作,所以我可以在本地測試我的 api 而無需部署到服務器(在我的情況下部署到服務器非常耗時)。 所以這個設置對於我在最后期限之前完成非常重要。 非常感謝任何答案/建議。


我的項目中使用的 Spring OAuth2 庫如下 -

  1. org.springframework.security:spring-security-oauth2-jose:5.4.2
  2. org.springframework.cloud:spring-cloud-starter-oauth2:2.1.3.RELEASE

並且給出錯誤的 class 是: OAuth2AuthenticationProcessingFilter.javaAPI Doc

抱歉,我不會回答您的問題(@Toerktumlare 是對的,您的安全配置丟失),而是會嘗試解釋為什么我不會將 API 網關設為 OAuth2 客戶端。

簡單地說,API 網關的作用是作為系統資源的黑匣子,這可以使其被視為資源服務器,但在我看來,它應該對 OAuth2(和其他身份驗證機制)保持透明。 保持簡單:

  • 客戶端(UI) 處理用戶登錄(需要時)
  • 資源服務器控制對資源的訪問
  • 網關(如果有的話)應該盡可能保持透明,只為所有資源提供一個入口點。

在您的場景中:

  • 如果您被要求實施多因素身份驗證,您期望會發生什么事情:除了登錄名/密碼之外,還需要生物識別、外部應用程序驗證、Goolgle 身份驗證器令牌或其他任何一項? 除了授權服務器之外,您真的打算在網關中實現所有這些嗎?
  • 如果它總是將api-gw-client作為客戶端 ID,您的授權服務器如何實現基於客戶端的處理(例如檢查請求的范圍對於客戶端是否合法,或者將客戶端權限添加到訪問令牌)?
  • 多租戶場景(網關后面的R1R2資源服務器期望來自不同頒發者的身份,或者C1C2客戶端不針對同一授權服務器對用戶進行身份驗證)呢?
  • 如果某些客戶端和資源服務器使用 OAuth2 以外的東西怎么辦?

此外,您的客戶端必須知道在每個 API 端點(XML、JSON、PDF、multipart 等) Accept和生成的媒體類型並相應地設置Content-type 為什么Authorization header 會有所不同?

在我看來,如果您想節省時間和精力,請使用您的 API 網關僅代理您的資源服務器 離開授權服務器。 對於您不維護但您的客戶需要的外部 API(如果有的話)也是如此(Tweeter feed、Google API 等)。

這就是我總是配置我的資源服務器的方式

  • Authorization header 丟失或無效(格式錯誤、過期、錯誤的頒發者、不良受眾等)=> 401(未經授權)而不是 302(重定向到登錄)
    • 在多租戶場景中,為什么資源服務器要費心弄清楚要重定向到哪個授權服務器?
    • 對於不在瀏覽器中運行的客戶端(例如移動應用程序),重定向的含義應該是什么?
  • Authorization header 有效,但相關聲明未能通過訪問控制(例如權限錯誤或不是預期主題)=> 403(禁止)

客戶端應該知道如何獲取所需的訪問令牌以及如何在發送請求時設置Authorization header(這是您目前使用 Postman 所做的)。 它甚至可以攔截 401 觸發用戶認證,然后重試失敗的資源訪問。 嚴重的 OAuth2 客戶端庫(如 Angular的 angular-auth-oidc-client )提供了此類功能。

使用這樣的客戶端,網關可以充當您的資源服務器(以及授權服務器或外部 API,如果您願意,但為什么呢?),轉發Authorization header 並完全忽略用戶登錄。

暫無
暫無

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

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