1. 程式人生 > >SpringBoot + Spring Security OAuth2基本使用

SpringBoot + Spring Security OAuth2基本使用

OAuth2.0基本知識

網上關於OAuth2.0的介紹已經很多了,這裡就不做過多的介紹,不太瞭解的朋友可以參考理解OAuth 2.0

Spring Security OAuth2

基本配置

這裡依然使用maven來做管理

<dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth2</artifactId>
</dependency>

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

認證伺服器

在過OAuth2.0有了基本概念後,我們會知道其中有一個服務提供商,我們就先來完成它。
這裡只需要新建一個類,並新增相應的註釋就可以了

@Configuration
@EnableAuthorizationServer
public class MyAuthorizationServerConfig {
}

隨後我們啟動專案,就會發現控制檯有如下的語句列印:

Authorization Server

這就表明Authorization Server已經建立起來了。 我們可根據OAuth的規則來訪問相應的介面。

第三方應用 User authenticates

在有了服務提供商之後,我們就可以根據OAuth的規則,來要求使用者給予授權。 這裡我們以code模式為例。
所以這裡需要第三方應用去呼叫介面

這裡對介面引數做一個簡單的介紹。

  • localhost:8080這裡是我服務的地址以及埠,根據每個人的情況是不同的
  • /oauth/authorize這個是Spring Security OAuth2預設提供的介面
  • response_type:表示授權型別,必選項,此處的值固定為”code”
  • client_id:表示客戶端的ID,必選項。這裡使用的是專案啟動時,控制檯輸出的security.oauth2.client.clientId,當然該值可以在配置檔案中自定義
  • redirect_uri:表示重定向URI,可選項。即使用者授權成功後,會跳轉的地方,通常是第三方應用自己的地址
  • scope:表示申請的許可權範圍,可選項。這一項用於服務提供商區分提供哪些服務資料
  • state:表示客戶端的當前狀態,可以指定任意值,認證伺服器會原封不動地返回這個值。這裡沒有使用到該值

這裡我們訪問到介面後,會出現如下的介面
使用者登入
該介面主要是用於使用者登入的,不然怎麼知道想要哪個使用者的資料呢?

在登入成功後,來到如下介面
授權介面
這裡就是要求使用者授權的介面了,有點類似於我們使用QQ進行第三方登入時候的介面。上面寫有了是哪一個第三方應用需要哪些資料。

我們這裡就點確認授權,這裡就會根據配置的redirect_uri進行跳轉,並且是帶有一個引數的。
這裡我們跳轉到了:https://www.baidu.com/?code=XKxYIx

這個code就是下一步第三方應用向伺服器申請令牌使用的

請求Token

這裡我們拿著上一步獲取到的code,以及專案初始化時列印的clientId和secret去獲取Token。
這裡需要使用POST方法,

POST /oauth/token HTTP/1.1
Host: localhost:8082
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb

請求的Header中有一個Authorization引數,該引數的值是Basic + (clientId:secret Base64值)

  • grant_type:表示使用的授權模式,必選項,此處的值固定為”authorization_code”。
  • code:表示上一步獲得的授權碼,必選項。
  • redirect_uri:表示重定向URI,必選項,且必須與A步驟中的該引數值保持一致。
  • client_id:表示客戶端ID,必選項。

如果請求成功,就可以順利的拿到Token

獲取到Token

請求Token成功後,認證伺服器傳送的HTTP回覆

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

 {
   "access_token":"2YotnFZFEjr1zCsicMWpAA",
   "token_type":"example",
   "expires_in":3600,
   "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
   "example_parameter":"example_value"
 }
  • access_token:表示訪問令牌,必選項。
  • token_type:表示令牌型別,該值大小寫不敏感,必選項,可以是bearer型別或mac型別。
  • expires_in:表示過期時間,單位為秒。如果省略該引數,必須其他方式設定過期時間。
  • refresh_token:表示更新令牌,用來獲取下一次的訪問令牌,可選項。
  • scope:表示許可權範圍,如果與客戶端申請的範圍一致,此項可省略。

資源伺服器

和認證伺服器一樣,這裡實現資源伺服器就很容易了

@Configuration
@EnableResourceServer
public class MyResourceServerConfig {
}

這樣我們就可以用Token來訪問介面了。
例如:

GET /user HTTP/1.1
Host: localhost:8082
Authorization: bearer 9b2aaea4-d161-4636-8883-6756a372e735

這裡Authorization中,bearer 是上一步返回的token_type。

遺留問題

目前基本功能是實現了,但是還有兩個遺留問題需要解決:
1. 現在的Token是存在Session中的,伺服器重啟後原來客戶端的Token就失效了。
2. Token現在是自動生成的,是否可以用JWT來自定義生成呢?

程式碼下載