spring cloud OAuth2


git地址
https://github.com/a18792721831/studySpringCloud.git

1. 爲什麼需要oauth

在互聯網上,不是所有的資源都是開放的。比如公司內部的機密資料,代碼,方案等,都不是向所有人開放的,而是有選擇性的開放。你是公司的員工,那麼你就能夠訪問資源,如果你不是公司的員工,那麼你就無法訪問。
那麼,程序或者網站如何區分你是否是公司內部的員工呢?
常見的做法有:

  • 公司不開放註冊,然後分配公司內部員工使用用戶名密碼進行驗證訪問。
  • 公司指定用戶才能訪問,比如ip限定。

但是上述的做法如果是公司自己管理或者自己開發的網站或者程序,那麼還湊活使用。
如果公司使用的是第三方託管資源,那麼就不可避免的需要將授權認證信息提供給第三方,這樣第三方纔能進行驗證並允許訪問資源。
如果第三方受到攻擊,那麼會導致大量的信息泄露(記得前一段時間報道,docker hub受到攻擊,導致許多授權信息泄露,github好像也發生過類似的信息,以及企業常見的代碼管理git lab等等)

爲了避免因第三方受到攻擊,而拖累客戶,就需要一個類似互聯網網站證書的機制,通過認證獲取授權(類似從CA獲取證書),然後用戶拿着授權信息去第三方訪問(一般第三方擁有打帶寬,或者更好的資源訪問體驗)。當第三方受到請求後,將授權信息拿到授權認證服務器認證,通過後再允許訪問。

通俗來講:
用戶向第三方說,我要訪問XXX資源,
第三方一看是用戶YY訪問,
接着去問公司,用戶YY是你公司的員工嗎,他有訪問XXX資源的權限嗎?
公司回覆,用戶YY是我公司的員工,有訪問XXX資源的權限。
接着第三方說,用戶YY有權限訪問XXX資源,你去訪問吧
然後用戶YY就拿到了想要訪問的資源。

2. oauth的原理

在1中,我們通俗的理解了oauth的整個流程機制,以及oauth的必要性。不會因第三方拖累公司(一般第三方需要提供的服務多,受到攻擊的可能性大,而公司只指定第三方可以訪問,受到的攻擊幾乎沒有)
接下來看下oauth的一些專有名詞。
oauth的工業標準:
https://tools.ietf.org/html/rfc6749
在這裏插入圖片描述
oauth是基於http授權的。
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

3. oauth的組成

OAuth2協議在Spring Resources中的實現爲Spring OAuth2.Spring Oauth2分爲兩部分:Oauth2 Provider和OAuth2 Client.

3.1 OAuth2 Provider

OAuth2 Provider 負責公開被 OAuth2保護起來的資源。OAuth2 Provider需要配置代表用戶的 OAuth2客戶端信息,被用戶允許的客戶端就可以訪問被OAuth2保護的資源。OAuth2 Provider 通過管理和驗證 OAuth2令牌來控制客戶端是否有權限訪問被其保護的資源。另外,Oauth 2 Provider 還必須爲用戶提供認證 API接口。根據認證 API 接口,用戶提供賬號和密碼等信息,來確認客戶端是否可以被 OAuth2 Provider 授權。這樣做的好處就是第三方客戶端不需要獲取用戶的賬號和密碼,通過授權的方式就可以訪問被OAuth2保護起來的資源。
OAuth2 Provider的角色被分爲Authorization Service(授權服務)和Resource Service(資源服務),通常它們不在同一個服務中,可能一個Authorization Service對應多個 Resource Service。Spring OAuth2 需配合 Spring Security 一起使用,所有的請求由Spring MVC控制器處理,並經過一系列的Spring Security過濾器。
在Spring Security過濾器鏈中有以下兩個節點,這兩個節點是向Authorization Service 獲取驗證和授權的。

  • 授權節點:默認爲/oauth/auhorize。
  • 獲取 Token節點:默認爲/oauth/token。

3.1.1 授權服務Authorization Server

在配置Authorization Server時,需要考慮客戶端從用戶獲取訪問令牌的授權類型。Authorization Server需要配置客戶端的詳細信息和令牌服務實現。
在任何實現了AuthorizationServerConfigurer接口的類上加@EnableAuthorizationServer註解,開啓Authorization Server的功能,以Bean的形式注入Spring IoC容器中,並需要實現以下3個配置:

其整體實現如圖:
https://naotu.baidu.com/file/1465ee54a758ba989953f8518f028172?token=14b06e4991ef8660
在這裏插入圖片描述

    1. ClientDetailsServiceConfigurer:配置客戶端信息
    1. AuthorizationServerEndpointsConfigurer:配置授權的Token節點和服務
    1. AuthorizationServerSecurityConfigurer:配置Token節點的安全策略

3.1.1.1 ClientDetailServiceConfigurer

客戶端的配置信息既可以放在內存中,也可以放在數據庫中。
需要配置以下信息:

  • clientId:客戶端id,需要在Authorization Server中是唯一的
  • secret:客戶端的密碼
  • scope:客戶端的域
  • authorizedGrantTypes:認證類型
  • authorities:權限信息

3.1.1.2 AuthorizationServerEndpointsConfigurer

在默認情況下,AuthorizationServerEndpointsConfigurer配置開啓了所有的驗證類型,除了密碼類型的驗證,密碼配置只有配置了authrizationManager的配置纔會開啓。
AuthorizationServerEndpointsConfigurer的配置由以下組成:

  • authorizationManager:只有配置了這個,密碼認證纔會開啓。
  • userDetailsService:配置獲取用戶認證信息的接口。
  • authorizationCodeServices:配置驗證碼服務。
  • implicaitGranter:配置管理implict驗證的狀態。
  • tokenGranter:配置Token Granter
    Token的策略現在有以下三種:
  1. InMemoryTokenStore:Token存儲在內存中
  2. JdbcTokenStore:Token存儲在數據庫中
  3. JwtTonkenStore:採用JWT形式

3.1.1.3 AuthorizationServerSecurityConfigurer

如果資源服務和授權服務是在同一個服務中,用默認的配置即可,不需要做其他任何的配置。但是如果資源服務和授權服務不在同一個服務中,則需要做一些額外配置。如果採用RemoteTokenService(遠程Token校驗),資源服務器的每次請求所攜帶的Token都需要從授權服務器做校驗。此時需要配置"/oauth/check_token"校驗節點的校驗策略。

3.1.2 資源服務Resource Server

Resource Server提供了收OAuth2保護的資源,可以是API接口、HTML頁面、js文件等。Spring OAuth2提供了實現此類保護功能的Spring Security認證過濾器。在加了@Configuration的註解的配置類上加@EnableResourceServer註解,開啓Resource Server的功能。

  1. tokenServices:定義Token Service.比如可以配置ResourceServerTokenServices類,配置Token是如何編碼解碼。如果Resource Server和Authorization Server在同一個工程上,就不需要配置tokenServices。也可以使用RemoteTokenService類,採用遠程授權方式,這個時候也不需要tokenService.
  2. resourceId:配置資源id

3.2 OAuth2 Client

OAuth2 Client(客戶端)用於訪問被OAuth2保護起來的資源。客戶端需要提供用於存儲用戶的授權碼和訪問令牌的機制,需要配置如下兩個選項。
在這裏插入圖片描述
http://naotu.baidu.com/file/93e43f7235046ba93909e83fb992d034?token=482eebbed3e161ba

3.2.1 Protected Resource Configuration

使用OAuth2ProtectedResourceDeatils類型的Bean來定義受保護的資源,受保護的資源具有以下屬性:

  • Id:資源的Id,在Spring OAuth2中沒有用到,用於客戶端尋找資源,不需要做配置,默認即可。
  • clientId:OAuth2 Client的Id,和之前OAuth2 Provider中配置的一一對應。
  • clientSecret:客戶端密碼,和之前OAuth2 Provider中配置的一一對應。
  • accessTokenUri:獲取Token的API節點
  • scope:客戶端的域
  • clientAuthorizationSchema:有兩種客戶端驗證類型,分別是Http Basic,和Form,默認是Http Basic.
  • userAuthorizationUri:如果用戶需要授權訪問資源,則用戶將被重定向到認證url.

3.2.2 Client Configuration

對於 OAuth2 Client的配置,可以使用@EnableOAuth2Client註解來簡化配置,當然還需要兩個配置:

  • 創建一個過濾器Bean(Bean的id爲oauth2ClientContextFilter),用來存儲當前請求和上下文請求。在請求期間,如果用戶需要進行身份認證,則用戶會被重定向到OAuth2的認證url.
  • 在Reques域內創建AccessTokenRequest類型的Bean.

4. 實例

在這裏插入圖片描述
https://www.processon.com/view/link/5e75aa28e4b011fccea52457

原本打算按照教程,做一個實例,完完整整的練習一遍。
但是吧,沒想到。
在這裏插入圖片描述
傳送門
教程是spring boot 1.x的,對應的OAuth2.x
現在是spring boot 2.x的,對應的OAuth5.2.x
作重要的是:
OAuth5.2.x他們做的改動太大了。
5.2.x做大的改動就是將OAuth2.x中的註解廢棄了,且不兼容。
那麼在5.2.x中是如何實現相同的配置呢?
他們使用了DSL。說白了就是裝飾器配置。。。
在5.2.x中,將所有的配置全部放在了WebSecurityConfigurerAdapter中
也就是說不管你想怎麼配置,全部都在一個類中。
嗯,有些無法適應。
比如:
在這裏插入圖片描述
去掉了@EnableOAuth2Client的註解,替換爲了oauth2Client配置
在這裏插入圖片描述
在這裏插入圖片描述
廢棄了@EnableOAuth2Sso註解,替換爲了oauth2Login()配置
在這裏插入圖片描述
廢棄了@EnableResourceServer註解,而是使用oauth2ResourceServer配置
在這裏插入圖片描述
廢棄了ResourceServerConfigurerAdapter適配器類,將其融入了WebSecurityConfigurerAdapter類。
好多好多,而且開放的issues也很多。
在這裏插入圖片描述

怎麼說呢,不管怎麼改都可以,但是最好還是不要動一些常用的配置。
比如他廢棄了好多的註解,然後都放在了WebSecurityConfigurerAdapter中。
這些方法的配置也沒有很好的註釋說明:
在這裏插入圖片描述
從這裏以下一半的註釋都很少。
就導致,這東西現在不知道該怎麼用,網上的資料也是少的可憐。至少你19年11月之前的資料都是無法用的(可能能用一點點)。
我到現在大概看源碼、找資料花費了大概6個小時,依然沒有成功。
這是我找到一些可能有用的信息:

  1. oauth2的文檔地址:https://oauth.net/2/
  2. 遷移說明:https://github.com/spring-projects/spring-security/wiki/OAuth-2.0-Migration-Guide
  3. spring官方文檔說明:https://spring.io/projects/spring-security-oauth
  4. git的readme文檔:https://github.com/spring-projects/spring-security
  5. oauth2resourceserver-opaque例子:https://github.com/spring-projects/spring-security/tree/master/samples/boot/oauth2resourceserver-opaque
  6. oauth2webclient例子:https://github.com/spring-projects/spring-security/blob/5.3.0.RELEASE/samples/boot/oauth2webclient/src/main/java/sample/config/SecurityConfig.java

這部分先存疑吧,等過段時間,資料豐富了在回來補充。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章