開發環境:
windows10
intellij idea2018.2
jdk1.8
redis3.2.9
spring boot 2.0.2 release
spring cloud finchley.rc2
spring 5.0.6
項目目錄
eshop —— 父級工程,管理jar包版本
eshop-server —— eureka服務注冊中心
eshop-gateway —— zuul網關
eshop-auth —— 授權服務
eshop-member —— 會員服務
eshop-email —— 郵件服務(暫未使用)
eshop-common —— 通用類
首先建構eshop-auth服務,引入相關依賴
接下來,配置mybatis、redis、eureka,貼一下配置檔案
authapplication添加@enablediscoveryclient和@mapperscan注解。
接下來配置認證伺服器authorizationserverconfig ,并添加@configuration和@enableauthorizationserver注解,其中clientdetailsserviceconfigurer配置在記憶體中,當然也可以從資料庫讀取,以後慢慢完善。
在上述配置中,認證的token是存到redis裡的,如果你這裡使用了spring5.0以上的版本的話,使用預設的redistokenstore認證時會報如下異常:
原因是spring-data-redis 2.0版本中set(string,string)被棄用了,要使用redisconnection.stringcommands().set(…),所有我自定義一個redistokenstore,代碼和redistokenstore一樣,隻是把所有conn.set(…)都換成conn..stringcommands().set(…),測試後方法可行。
配置資源伺服器
配置spring security
可以看到resourceserverconfig 是比securityconfig 的優先級低的。
二者的關系:
resourceserverconfig 用于保護oauth相關的endpoints,同時主要作用于使用者的登入(form login,basic auth)
securityconfig 用于保護oauth要開放的資源,同時主要作用于client端以及token的認證(bearer auth)
是以我們讓securityconfig優先于resourceserverconfig,且在securityconfig 不攔截oauth要開放的資源,在resourceserverconfig 中配置需要token驗證的資源,也就是我們對外提供的接口。是以這裡對于所有微服務的接口定義有一個要求,就是全部以/api開頭。
如果這裡不這樣配置的話,在你拿到access_token去請求各個接口時會報 invalid_token的提示。
另外,由于我們自定義認證邏輯,是以需要重寫userdetailservice
密碼驗證為了友善我使用了不加密的方式,重寫了passwordencoder,實際開發還是建議使用bcryptpasswordencoder。
另外,oauth的密碼模式需要authenticationmanager支援
定義一個controller,提供兩個接口,/api/member用來擷取目前使用者資訊,/api/exit用來登出目前使用者
引入依賴
配置檔案配置
memberapplication主類配置
提供對外接口
配置檔案
zuulapplication主類
spring security配置
接下來分别啟動eshop-server、eshop-member、eshop-auth、eshop-gateway。
先發送一個請求測試一下未認證的效果
擷取認證
使用access_token請求auth服務下的使用者資訊接口
使用access_token請求member服務下的使用者資訊接口
請求member服務的query接口
請求member服務的hello接口,資料庫裡并沒有給使用者hello權限
重新整理token
登出
後續還會慢慢完善,敬請期待!
!
關于代碼和資料表sql已經上傳到github。位址:https://github.com/wya1993/springcloud_oauth2.0。
注意把資料庫和redis替換成自己的位址
原因是在發起請求的時候沒有添加basic auth認證,如下圖:
,添加basic auth認證後會在headers添加一個認證消息頭
添加basic auth認證的資訊在代碼中有展現:
現在用戶端資訊都是存在記憶體中的,生産環境肯定不可以這麼做,要支援用戶端的動态添加或删除,是以我選擇把用戶端資訊存到mysql中。
首先,建立資料表,資料表的結構官方已經給出,位址在
https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/test/resources/schema.sql
其次,需要修改一下sql腳本,把主鍵的長度改為128,longvarbinary類型改為blob,調整後的sql腳本:
調整後的sql腳步也放到了github中,需要的可以自行下載下傳
然後在eshop_member資料庫建立資料表,将用戶端資訊添加到oauth_client_details表中
如果你的密碼不是明文,記得client_secret需要加密後存儲。
然後修改代碼,配置從資料庫讀取用戶端資訊
接下來啟動服務測試即可。
擷取授權
擷取使用者資訊
打開資料表發現token這些資訊并沒有存到表中,因為tokenstore使用的是redis方式,我們可以替換為從資料庫讀取。修改配置
重新開機服務再次測試
檢視資料表,發現token資料已經存到表裡了。