![](/img/trans.png)
[英]Protecting the service using OAuth2, JWT token not working Spring cloud
[英]Spring OAuth2 - JWT token working on server but not on localhost?
我看到myapp
能夠在服務器上正確處理 OAuth2 JWT 令牌,但它在本地主機上給出令牌轉換錯誤。
我的流程如下 -
在 Server上, myapp
位於我們自定義api-gateway
后面
所以,總而言之,postman
請求: --(creds)--> api-gateway --(samecreds)--> auth-server
響應: jwt 令牌 <-- (same jwt)-- api-gateway <--(jwt)-- auth-server
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 后面運行,而是直接命中
所以,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
客戶端發出令牌。 我還不確定這個領域是微不足道的還是重要的。
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 庫如下 -
org.springframework.security:spring-security-oauth2-jose:5.4.2
org.springframework.cloud:spring-cloud-starter-oauth2:2.1.3.RELEASE
並且給出錯誤的 class 是: OAuth2AuthenticationProcessingFilter.java ( API Doc )
抱歉,我不會回答您的問題(@Toerktumlare 是對的,您的安全配置丟失),而是會嘗試解釋為什么我不會將 API 網關設為 OAuth2 客戶端。
簡單地說,API 網關的作用是作為系統資源的黑匣子,這可以使其被視為資源服務器,但在我看來,它應該對 OAuth2(和其他身份驗證機制)保持透明。 保持簡單:
在您的場景中:
api-gw-client
作為客戶端 ID,您的授權服務器如何實現基於客戶端的處理(例如檢查請求的范圍對於客戶端是否合法,或者將客戶端權限添加到訪問令牌)?R1
和R2
資源服務器期望來自不同頒發者的身份,或者C1
和C2
客戶端不針對同一授權服務器對用戶進行身份驗證)呢? 此外,您的客戶端必須知道在每個 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.