領先一步
VMware 提供培訓和認證,助您加速進步。
瞭解更多今天,我很高興地宣佈您擁有了一項新的超能力:使用 Spring Authorization Server 在 Spring Initializr 上建立應用程式!
沒錯,是時候開始您的 OAuth2 之旅,成為您一直都知道自己能成為的英雄了!在這篇文章中,我將解釋如何充分利用您的新超能力以及去哪裡學習更多。
Spring Authorization Server 是一個基於 Spring Security 構建的開源框架,允許您建立自己的符合標準的 OAuth2 授權伺服器或 OpenID Connect 提供商。它實現了各種 OAuth2 和 OIDC 相關規範中的許多協議端點,使您可以更專注於應用程式和使用者,而不是流程和規範。由於它位於 Spring Security 之上,因此也可以用於建立認證中心,以將其他認證協議適配到 OAuth2。
您可以在參考指南的概述中瞭解更多關於 Spring Authorization Server 的資訊。
從試圖熄滅所有生命的邪惡生物手中拯救世界的旅程總要從某個地方開始,您成為 OAuth2 英雄的旅程也毫不例外!要開始,請下載此示例應用程式,或者前往start.spring.io並將 OAuth2 Authorization Server 依賴項新增到您的專案中。
然後,在您喜歡的 IDE 中開啟專案,並將以下內容新增到 application.properties
spring.security.oauth2.authorizationserver.client.client-1.registration.client-id=admin-client
# the client secret is "secret" (without quotes)
spring.security.oauth2.authorizationserver.client.client-1.registration.client-secret={bcrypt}$2a$10$jdJGhzsiIqYFpjJiYWMl/eKDOd8vdyQis2aynmFN0dgJ53XvpzzwC
spring.security.oauth2.authorizationserver.client.client-1.registration.client-authentication-methods=client_secret_basic
spring.security.oauth2.authorizationserver.client.client-1.registration.authorization-grant-types=client_credentials
spring.security.oauth2.authorizationserver.client.client-1.registration.scopes=user.read,user.write
或者,您可以將 application.properties 重新命名為 application.yml 並新增以下內容
spring:
security:
oauth2:
authorizationserver:
client:
client-1:
registration:
client-id: "admin-client"
# the client secret is "secret" (without quotes)
client-secret: "{bcrypt}$2a$10$jdJGhzsiIqYFpjJiYWMl/eKDOd8vdyQis2aynmFN0dgJ53XvpzzwC"
client-authentication-methods: "client_secret_basic"
authorization-grant-types: "client_credentials"
scopes: "user.read,user.write"
要啟動應用程式,請執行以下命令
./gradlew bootRun
這將為您提供一個開箱即用的應用程式,具有以下功能
當然,功能不止於此,您可以檢視功能列表以獲取完整列表。
那麼我們能用它做什麼呢?使用上面的例子,我們將從最容易理解的客戶端憑據流開始。我將在命令列上使用 HTTPie 進行演示,您可以在家(或工作中)跟著操作。
執行以下命令
http -f POST :8080/oauth2/token grant_type=client_credentials scope='user.read' -a admin-client:secret
這將產生類似以下的響應
{
"access_token": "eyJraWQiOiJhMWZjM2JhOC0zY2IwLTRkZjAtYTQwNS03ZDhhY2YxYTY4NGIiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJhZG1pbi1jbGllbnQiLCJhdWQiOiJhZG1pbi1jbGllbnQiLCJuYmYiOjE2ODQ1MjYzOTgsInNjb3BlIjpbInVzZXIucmVhZCJdLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAiLCJleHAiOjE2ODQ1MjY2OTgsImlhdCI6MTY4NDUyNjM5OH0.sHDGoQGDpdBuhvdiIpFeeCtTUeU860FBeV23rS6Zqb8tjq_Pytj_Y4Xl6pBB2R5rTAZdMg0cwLvICVYBz-x-hGz2UbHFtYGmo24byb3iKGqBb2BjtY5mMuYQOdnW_PgUVV4vtElhTYkkN_uET4CZ3zxIhgPEc2Yvtt0-d2lGwXzkDiHb_US1zDSUO36nqs4cesMD-yzy5tVmr1e2c6Klojyv6nFN1edfTn7Ci5GvEeB4lDnQdm3ZJr4fyxSiSrq7T34ghj6fMqYn_-lazpoc-wWPB5I35NM0TkUyDw2e_XobqIm6oXG0tBDujL2SK6P05n5MDKkGhgsQlT_ER9gmqA",
"expires_in": 299,
"scope": "user.read",
"token_type": "Bearer"
}
響應中的 access_token 是一個簽名的 JWT,可用於向具有 user.read 範圍的 OAuth2 資源伺服器發出認證請求,以訪問受保護資源。換句話說,只需一個 Spring Boot 應用程式和幾個屬性,我們就能輕鬆地鑄造簽名的 JWT 並開始使用 OAuth2 保護應用程式。當然,使用 Spring Security 設定資源伺服器也同樣簡單,但我將把這作為對您未曾發現的超能力的一次考驗。
為了保持簡單,我們使用自省端點測試這個令牌。
注意:請記住,令牌將在 5 分鐘後過期。
執行以下命令,確保將實際的 access_token 貼上到示例中
export TOKEN=eyJraW...
http -f POST :8080/oauth2/introspect token=$TOKEN -a admin-client:secret
這將產生類似以下的響應
{
"active": true,
"aud": [
"admin-client"
],
"client_id": "admin-client",
"exp": 1684526698,
"iat": 1684526398,
"iss": "https://:8080",
"nbf": 1684526398,
"scope": "user.read",
"sub": "admin-client",
"token_type": "Bearer"
}
如果您看到這個響應
{
"active": false
}
那麼令牌很可能已過期。
如果您想深入瞭解正在發生的事情,可以啟用跟蹤日誌記錄以獲取額外的除錯詳細資訊。您還可以將令牌的過期時間縮短到極短,例如 30 秒,以便更容易獲得過期令牌。
將以下內容新增到您的 application.properties
logging.level.org.springframework.security=trace
spring.security.oauth2.authorizationserver.client.client-1.token.access-token-time-to-live=30s
或者如果您使用 application.yml,請新增以下內容
logging:
level:
org.springframework.security: trace
spring:
security:
oauth2:
authorizationserver:
client:
client-1:
registration:
...
token:
access-token-time-to-live: 30s
然後重啟應用程式,並再次嘗試上述步驟。發出自省請求後,您將看到類似以下的行
FilterChainProxy : Trying to match request against DefaultSecurityFilterChain [...] (1/2)
FilterChainProxy : Securing POST /oauth2/introspect
FilterChainProxy : Invoking DisableEncodeUrlFilter (1/25)
...
有兩件有趣的事情正在發生。在日誌中的幾行之後,您將看到類似以下的輸出
...
FilterChainProxy : Invoking OAuth2ClientAuthenticationFilter (14/25)
ProviderManager : Authenticating request with JwtClientAssertionAuthenticationProvider (1/18)
ProviderManager : Authenticating request with ClientSecretAuthenticationProvider (2/18)
ClientSecretAuthenticationProvider : Retrieved registered client
ClientSecretAuthenticationProvider : Validated client authentication parameters
ClientSecretAuthenticationProvider : Authenticated client secret
OAuth2ClientAuthenticationFilter : Set SecurityContextHolder authentication to OAuth2ClientAuthenticationToken
...
這告訴我們客戶端(我們的 CLI)透過 ClientSecretAuthenticationProvider 使用 HTTP 基本認證成功進行了認證。這就是為什麼我們收到 200 OK 響應,但透過日誌確認令牌自省請求成功會很好。幾行之後,您將看到這樣的輸出
...
FilterChainProxy : Invoking OAuth2TokenIntrospectionEndpointFilter (22/25)
ProviderManager : Authenticating request with OAuth2TokenIntrospectionAuthenticationProvider (1/18)
TokenIntrospectionAuthenticationProvider : Retrieved authorization with token
TokenIntrospectionAuthenticationProvider : Did not introspect token since not active
...
在這裡我們看到 OAuth2TokenIntrospectionAuthenticationProvider 正在處理請求,但令牌未啟用。因此,我們可以確認請求成功且令牌已過期。
我們只觸及了您新超能力所能做的事情的皮毛!我希望您記住的最重要的事情是,您現在可以使用 Spring Initializr 建立自己的個人 OAuth2 和 OpenID Connect 遊樂場,其中包含 Spring Authorization Server。
當您準備好時,我鼓勵您閱讀參考指南,其中包含有關每個功能和可用配置選項的詳細資訊。我特別推薦操作指南:如何使用社交登入進行認證,這是學習和探索的好方法。
也許瞭解 OAuth2 和 Spring Authorization Server 的最佳方式是構建一個包含(至少)三個應用程式的示例 OAuth2 架構
檢視可用的示例,它們演示了所有這三個應用程式,並嘗試只使用 Spring Initializr 構建自己的應用程式!一旦您完成了這些,未來就真的由您決定了!
現在去拯救世界吧!
註釋