Spring Security實現OAuth2.0受權服務 - 基礎版

 

1、OAuth2.0協議

一、OAuth2.0概述

OAuth2.0是一個關於受權的開放網絡協議。git

該協議在第三方應用與服務提供平臺之間設置了一個受權層。第三方應用須要服務資源時,並非直接使用用戶賬號密碼登陸服務提供平臺,而是經過服務提供平臺的受權層獲取token令牌,用戶能夠在受權時指定token的權限範圍和有效期。第三方應用獲取到token之後,才能夠訪問用戶資源。github

 

OAuth 2.0定義了四種受權方式:web

  • 受權碼模式(authorization code):功能最完整、流程最嚴密的受權模式。特色是經過第三方應用的後臺服務器,與服務提供平臺的認證服務器進行互動獲取資源。
  • 簡化模式(implicit):不經過第三方應用服務器,直接在瀏覽器中向認證服務器申請token令牌,跳過了受權碼這個步驟。全部步驟在瀏覽器中完成,token對用戶可見,且第三方應用不須要認證。
  • 密碼模式(resource owner password credentials):用戶向第三方應用提供本身的用戶名和密碼。第三方應用使用這些信息,向服務提供平臺索要受權。在這種模式中,用戶必須把本身的密碼給第三方應用,可是第三方應用不得儲存密碼。這一般用在用戶對第三方應用高度信任的狀況下,好比第三方應用是操做系統的一部分,或者由一個著名公司出品。而認證服務器只有在其餘受權模式沒法執行的狀況下,才能考慮使用這種模式。
  • 客戶端模式(client credentials):指第三方應用以本身的名義,而不是以用戶的名義,向服務提供平臺進行認證。嚴格地說,客戶端模式並不屬於OAuth框架所要解決的問題。在這種模式中,用戶直接向第三方應用註冊,第三方應用以本身的名義要求服務提供平臺提供服務,其實不存在受權問題。

 

二、受權碼模式

假設有X用戶、A系統、B系統,X是A系統中的用戶,B系統須要訪問A系統獲取X用戶的信息。spring

  • B系統中放置向A系統申請受權的入口;
  • X用戶點擊進入A系統受權頁,若是未登陸須要登陸;
  • X用戶容許受權給B系統;
  • A系統重定向到B系統,並攜帶authorization_code受權碼;
  • B系統使用authorization_code受權碼到A系統獲取token令牌;
  • B系統能夠使用token令牌到A系統獲取用戶資源。

 

再舉個受權碼模式的例子:某網站QQ快速登陸、帳號綁定。apache

  • 用戶點擊網站的QQ登陸圖標
  • 頁面跳轉到QQ提供的受權頁,若是PC上沒有登陸QQ帳號,須要登陸
  • 用戶容許受權
  • 重定向到網站回調地址,攜帶受權碼authorization_code
  • 網站使用受權碼獲取token
  • 使用token拉取QQ帳號信息
  • 使用QQ帳號信息登陸、帳號綁定等

 

三、文檔和例子

百度搜索「oauth2.0」瀏覽器

 

QQ互聯官方文檔,http://wiki.connect.qq.com安全

 

2、Spring Security概述

Spring Security是一個用於快速實現Web應用安全、認證的框架,能夠快速和Spring Boot整合。服務器


開發者能夠編寫配置類繼承WebSecurityConfigurerAdapter類,重寫config方法自定義登陸頁面、登陸失敗邏輯、權限不足邏輯等,而且能夠編寫Filter實現更加複雜的圖片驗證碼、短信驗證碼功能。網絡


Spring Security也能夠快速實現OAuth2.0受權服務器和資源服務器。在一個Spring Boot應用中,能夠使用@EnableAuthorizationServer註解實現受權服務器,使用@EnableResourceServer註解實現資源服務器。app

 

例如

1 @SpringBootApplication
2 @EnableAuthorizationServer
3 @EnableResourceServer
4 public class BasicOauth2Application {
5 
6     public static void main(String[] args) {
7         SpringApplication.run(BasicOauth2Application.class, args);
8     }
9 }

 

在application.properties文件配置client-id和client-secret參數

security.oauth2.client.client-id=net5ijy
security.oauth2.client.client-secret=123456

 

3、Spring Security實現OAuth2.0基礎

一、引入依賴

 1 <parent>
 2     <groupId>org.springframework.boot</groupId>
 3     <artifactId>spring-boot-starter-parent</artifactId>
 4     <version>1.5.13.RELEASE</version>
 5 </parent>
 6 
 7 <dependencies>
 8     <dependency>
 9         <groupId>org.springframework.boot</groupId>
10         <artifactId>spring-boot-starter-web</artifactId>
11     </dependency>
12     <dependency>
13         <groupId>org.springframework.boot</groupId>
14         <artifactId>spring-boot-starter-security</artifactId>
15     </dependency>
16     <dependency>
17         <groupId>org.springframework.security.oauth</groupId>
18         <artifactId>spring-security-oauth2</artifactId>
19     </dependency>
20 </dependencies>
21 
22 <build>
23     <plugins>
24         <plugin>
25             <groupId>org.apache.maven.plugins</groupId>
26             <artifactId>maven-compiler-plugin</artifactId>
27             <configuration>
28                 <source>1.8</source>
29                 <target>1.8</target>
30                 <encoding>UTF-8</encoding>
31             </configuration>
32         </plugin>
33     </plugins>
34 </build>
View Code

 

二、Spring Boot啓動類配置

加@EnableAuthorizationServer和@EnableResourceServer註解。

1 @SpringBootApplication
2 @EnableAuthorizationServer
3 @EnableResourceServer
4 public class BasicOauth2Application {
5 
6     public static void main(String[] args) {
7         SpringApplication.run(BasicOauth2Application.class, args);
8     }
9 }

 

三、application.properties配置

配置Security登陸用戶

security.user.name=admin
security.user.password=123456

 

配置client-id和client-secret參數

security.oauth2.client.client-id=net5ijy
security.oauth2.client.client-secret=123456

 

四、受保護資源

編寫controller

 1 @RestController
 2 @RequestMapping(value = "/")
 3 public class TestController {
 4 
 5     Logger log = LoggerFactory.getLogger(TestController.class);
 6 
 7     @RequestMapping(value = "order/demo")
 8     public String getDemo() {
 9         Authentication auth = SecurityContextHolder.getContext()
10                 .getAuthentication();
11         log.info(auth.toString());
12         return "Hello world";
13     }
14 }

 

五、測試受權碼模式

1)獲取authorization_code受權碼

使用瀏覽器訪問:
http://localhost:7000/oauth/authorize?response_type=code&client_id=net5ijy&redirect_uri=http://localhost:8080&scope=all

 

地址
http://localhost:7000/oauth/authorize

 

參數

response_type

code

client_id

根據實際的client-id填寫,此處寫net5ijy

redirect_uri

生成code後的回調地址,http://localhost:8080

scope

權限範圍

 

登陸,使用的用戶名、密碼就是在application.properties中配置的admin和123456

security.user.name=admin
security.user.password=123456

 

 

容許受權

 

看到瀏覽器重定向到了http://localhost:8080並攜帶了code參數,這個code就是受權服務器生成的受權碼

 

2)獲取token令牌

使用curl命令獲取token令牌

curl --user net5ijy:123456 -X POST -d "grant_type=authorization_code&scope=all&redirect_uri=http%3a%2f%2flocalhost%3a8080&code=Q1dzfj" http://localhost:7000/oauth/token

 

地址
http://localhost:7000/oauth/token

 

參數

grant_type

受權碼模式,寫authorization_code

scope

權限範圍

redirect_uri

回調地址,http://localhost:8080須要urlencode

code

就是上一步生成的受權碼

 

 

返回值

1 {
2     "access_token": "547e258c-9c88-4130-a6d5-770b6b6ef3a4",
3     "token_type": "bearer",
4     "refresh_token": "19cf0168-913e-4f64-a766-72c0d43928ba",
5     "expires_in": 43199,
6     "scope": "all"
7 }

 

這樣就獲取到了token令牌,該token的訪問權限範圍是all權限,在12小時後失效。

 

3)使用token訪問資源

curl http://localhost:7000/order/demo?access_token=547e258c-9c88-4130-a6d5-770b6b6ef3a4

 

在資源url後面加上access_token參數。

 

六、測試密碼模式

1)獲取token令牌

使用curl命令獲取token令牌

curl --user net5ijy:123456 -X POST -d "grant_type=password&username=admin&password=123456&scope=all" http://localhost:7000/oauth/token

 

地址
http://localhost:7000/oauth/token

 

參數

grant_type

密碼模式,寫password

scope

權限範圍

username

申請受權用戶的用戶名

password

申請受權用戶的密碼

 

 

返回值

1 {
2     "access_token": "20d4f648-2ce4-4198-9f2a-025211efb689",
3     "token_type": "bearer",
4     "refresh_token": "9caccc03-5b81-48f9-a32e-45538c2f779c",
5     "expires_in": 43199,
6     "scope": "all"
7 }

 

這樣就獲取到了token令牌,該token的訪問權限範圍是all權限,在12小時後失效。

 

2)使用token訪問資源

curl http://localhost:7000/order/demo?access_token=20d4f648-2ce4-4198-9f2a-025211efb689

 

4、Github源碼下載

https://github.com/xuguofeng/springsecurityoauth2

相關文章
相關標籤/搜索