Spring Authorization Server授權伺服器入門

碼農小胖哥發表於2022-04-13

11月8日Spring官方已經強烈建議使用Spring Authorization Server替換已經過時的Spring Security OAuth2.0,距離Spring Security OAuth2.0結束生命週期還有小半年的時間,是時候做出改變了。目前Spring Authorization Server已經進入生產就緒階段。今天跟著胖哥的節奏搞一搞Spring Authorization Server授權伺服器框架。

目前Spring Security的體系

在目前的Spring Security 5.x中將OAuth2.0 ClientOAuth2.0 Resource Server進行了模組化。
Spring Security是一定要引入的。

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

如果你要增加OAuth2.0 Client支援,可以引入:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
        </dependency>

如果需要OAuth2.0 Resource Server支援,可以引入:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-oauth2-resource-server</artifactId>
        </dependency>

現在如果你要增加OAuth2.0 Authorization Server支援的話,額外引入下面的依賴就可以了:

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-oauth2-authorization-server</artifactId>
        <!--  截至現在版本  -->
            <version>0.2.0</version>
        </dependency>

至此OAuth2.0三大模組齊活了。

Spring Authorization Server

我們的重點還是回到Spring Authorization Server上,目前該專案已經具備生產就緒能力。研究了幾天後,簡單出了一個DEMO,來幫助希望學習該框架的同學來理解它。

DEMO的流程

本DEMO將對OAuth 2.0的授權碼模式(authorization_code)進行演示。這裡分兩個專案;

  • oauth2-client專案,顧名思義作為OAuth2.0 Client,發起對授權伺服器的請求授權。
  • oauth2-server專案,基於Spring Authorization Server搭建的授權伺服器,提供授權服務。

使用者首先通過/oauth2/authorization/{registrationId}端點向oauth2-client發起請求:

GET /oauth2/authorization/felord HTTP/1.1
Host: 127.0.0.1:8080

OAuth2AuthorizationRequestRedirectFilter攔截後組裝成下面的請求連結向授權伺服器oauth2-server發起授權碼授權:

GET /oauth2/authorize?response_type=code&client_id=felord-client&scope=message.read%20message.write&state=0CI0ziUDEnqMgqW0nzRNRCzLrs-9IMbqJzGZ47Zb0gY%3D&redirect_uri=http://127.0.0.1:8080/foo/bar HTTP/1.1
Host: localhost:9000

授權伺服器oauth2-server攔截到該請求後,會先檢查發起該請求的當前使用者是否認證。如果沒有認證就丟擲401,跳到授權伺服器的登入頁面,然後使用者執行了登入:

POST /login HTTP/1.1
Host: localhost:9000
Content-Type: application/x-www-form-urlencoded

username=felord&password=password&_csrf=301a7baf-9e9a-4b17-acd4-613c809bf7f5

成功登入後進行了302跳轉,繼續執行/oauth2/authorize授權請求。這時會判斷授權請求是否需要使用者授權確認,在本DEMO中使用者授權是需要二次確認的,會跳轉到下面這個頁面:

Spring Authorization Server授權確認頁面

同意授權後,授權伺服器會呼叫redirect_uri並攜帶一個codestateoauth2-client發起請求:

GET /foo/bar?code=MCSJnvhXNyjilBaCyw1sCrrArWk1bzsEdxe5Z3EFbkdLwp8ASmum62n4M7Tz45VNpp_16IWboBnXlgG3LEfgN7MQqkf0-vVZufGrQpvRioRcBbesAiawMt4cspTk06ca&state=-fRunxjpG0aziPXnfcW1Iw1Fy_5_NwlUAgxABPOfAb8= HTTP/1.1 
Host: 127.0.0.1:8080

oauth2-clientOAuth2AuthorizationCodeGrantFilter攔截到redirect_uri後向授權伺服器發起/oauth2/token請求:

POST /oauth2/token?grant_type=authorization_code&code=MCSJnvhXNyjilBaCyw1sCrrArWk1bzsEdxe5Z3EFbkdLwp8ASmum62n4M7Tz45VNpp_16IWboBnXlgG3LEfgN7MQqkf0-vVZufGrQpvRioRcBbesAiawMt4cspTk06ca&redirect_uri=https://127.0.0.1:8080/foo/bar HTTP/1.1Host: localhost:9000Authorization: Basic bWVzc2FnaW5nLWNsaWVudDpzZWNyZXQ=

這裡採用的認證方式是client-authentication-method: client_secret_basic方式,詳見OAuth2.0協議。

授權伺服器將Token返回給客戶端,完成請求,認證客戶端資訊如下:

認證客戶端資訊

到此基於Spring Authorization Server整個授權碼流程完成了。

DEMO地址:https://gitee.com/felord/spring-security-oauth2-tutorial

關注公眾號:Felordcn 獲取更多資訊

個人部落格:https://felord.cn

相關文章