每日最新頭條.有趣資訊

SpringBoot 跨系統單點登陸的實現

作者 | 代碼忘煩惱

責編 | 屠敏

出品 | CSDN 部落格

什麽是單點登陸

單點登錄(英語:Single sign-on,縮寫為 SSO),又譯為單一簽入,一種對於許多相互關連,但是又是各自獨立的軟體系統,提供訪問控制的屬性。當擁有這項屬性時,當用戶登錄時,就可以獲取所有系統的訪問權限,不用對每個單一系統都逐一登錄。這項功能通常是以輕型目錄訪問協議(LDAP)來實現,在伺服器上會將用戶信息存儲到LDAP數據庫中。相同的,單一退出(single sign-off)就是指,只需要單一的退出動作,就可以結束對於多個系統的訪問權限。

單點登陸帶來的好處

降低訪問第三方網站的風險(不存儲用戶密碼,或在外部管理)

減少因不同的用戶名和密碼組合而帶來的密碼疲勞

減少為相同的身份重新輸入密碼所花費的時間

因減少與密碼相關的調用IT服務台的次數而降低IT成本

單點登陸技術

現在很多語言都擁有自己的單點登陸實現方案,本次案例中我們用SpringBoot Oauh2來實現跨系統的單點登陸。

單點登陸流程

你的項目可能有很多個模塊,如訂單管理、商戶管理、會員管理、財務管理,這些都是需要登陸後才能訪問,當我只要登陸一次,其它的系統都能訪問。

圖源於網絡

上圖是最清晰描述單點登陸的流程,如上圖就是最基本的單點登陸流程。

oauth2 的四種模式:

密碼模式(resource owner password credentials)

授權碼模式(authorization code)

簡化模式(implicit)

客戶端模式(client credentials)

我們一般都用授權碼模式 這個模式用的人也最多。

這幾種模式如果想要了解的更清楚可以看阮一峰老師的oauth2(http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html)。

單點登陸準備工作

首先我們創建一個叫spring_sso_parent 普通的maven工程 作為整個項目的父工程,創建好後,刪除src目錄,並且修改pom.xml的依賴

spring_sso_parent 父工程的依賴如下:

開始編寫單點登陸

我們在spring_sso_parent 父工程中 添加一個子模塊叫oauth_server的SpringBoot工程,依賴如下:

需要注意的是這裡的SpringBoot 版本使用的是父模塊的版本:

我們在oauth_server 中創建一個config的包,並且創建一個WebSecurityConfig的類

這個類使用了兩個注解,@Configuration 讓這個類成為了一個配置類, @Order(1) 這個注解是優先級,使用優先級來加載。

http.requestMatchers() 這個方法下配置的就是security 接收以什麽樣的請求,我們這裡隻接受/login和/oauth/authorize的請求 。

這兩句配置的意思是除了以上請求所有的請求都需要身份認證才能訪問。

這幾個配置的意思是採用form表單登陸默認登陸頁面是/login,任何人都能訪問,關閉csrf的保護。

這裡採用的是AuthenticationManagerBuilder 允許記憶體驗證,這裡我添加了一個用戶名為admin 密碼是 123456,角色是ADMIN的 一個用戶 來模擬數據庫查詢的用戶信息。

PasswordEncoder 是Spring 官方提供的一個md5 密碼加密器,一般用於密碼的加密。

這個就是WebSecurityConfig的配置

下面我們在config中繼續創建一個叫OauthServerConfig的類

這個類上也使用了兩個注解,@Configuration 這個注解成為Spring的一個配置類,@EnableAuthorizationServer 注解是開啟授權伺服器認證。

這個類繼承了AuthorizationServerConfigurerAdapter 這個類提供了授權伺服器策略。

這裡我們實現了兩個configure 認證策略方法,分別是AuthorizationServerSecurityConfigurer 和 ClientDetailsServiceConfigurer,而AuthorizationServerSecurityConfigurer提供了十幾個配置的方法,這裡我們不會多去深入。

其中 tokenKeyAccess意思是:oauth2授權伺服器會提供一個/oauth/token_key的url來供資源伺服器獲取公鑰,這個方法就是配置獲取公鑰的權限範圍,它使用的是SpEL表達式且默認不開啟, 這裡我們使用的是permitAll(),讓本身的oauth的訪問不需要授權。

checkTokenAccess意思是:授權伺服器提供一個/oauth/check_token的url來供資源伺服器解碼令牌,該方法就是配置權限範圍,同樣使用的是SpEL表達式且默認不開啟,我們這裡設置的是 isAuthenticated(),檢查access_token需要進行授權。

當客戶端向認證伺服器認證的時候,我們需要判斷這個客戶端是否通過了認證那麽就要使用ClientDetailsServiceConfigurer 它提供了三種認證方式

clients.withClientDetails() :使用數據庫認證

clients.jdbc(): 傳入一個dataSource 這裡可以使用自定義的dataSource

clients.inMemory():記憶體認證 相當於將認證信息 寫死

這樣我們就將授權伺服器配置好了。

下面我們創建一個controller的包。

創建一個LoginController 登陸的控制器

這裡返回的是一個login的 html 頁面:

在創建一個UserInfoController 用於獲取認證成功的用戶信息

applicatin.yml 配置

然後我們創建2個客戶端分別是oauth_client1 和 oauth_client2

oauth_client1 的依賴如下:

同樣創建一個config 包 並且創建一個 Oauth2ClientSeurityConfig這個類

這個類繼承了 WebSecurityConfigurerAdapter 這個SpringSecurity的適配器,實現了HttpSecurity 的 configure 方法。這個類也是兩個注解 @Configuration 成為一個配置類,@EnableOAuth2Sso 啟用Oauth2的單點登陸。

我們再創建一個controller 包 ,並且創建一個 InfoController

index.html 頁面

application.yml

auth-server:是目標認證伺服器

clientId:目標認證伺服器設置的客戶端id

clientSecret:目標認證伺服器設置的密碼

accessTokenUri:從目標認證伺服器獲取令牌token

userAuthorizationUri:從目標認證伺服器請求授權默認url是/oauth/authorize

userInfoUri: 從目標認證伺服器上將認證信息Principal通過形參綁定的方法通過URL的方式獲取用戶信息。

oauth_client2配置和 oauth_client1是一樣的。

我們啟動 認證伺服器oauth_server 和兩個客戶端 oauth_client1 和 oauth_client2。Chrome 瀏覽器訪問 localhost:8881

當我們點擊login的時候會跳轉到認證伺服器進行登陸授權

授權成功後 返回了這個用戶的所有的信息:

我們再去訪問localhost:8082:

當我點擊登陸的時候 ,並沒有出現登陸授權,直接拿到了用戶信息:

注意這裡我們不管是訪問客戶端1還是客戶端2 ,還是n多個客戶端,只要有一個授權成功 那麽訪問其它的客戶端就不需要登陸 就能訪問相關的rest服務了。

總結

oauth2 實現的單點登陸並不是很複雜,歸根結底,Spring幫我們做了太多的底層實現,讓我們實現起來非常的簡單 實現幾個接口就可以搞定授權伺服器的配置,客戶端的配置也非常的簡單。

現在我們流行看到了如百度,我登陸了百度,那麽就可以直接訪問百度貼吧,百度糯米等。單點登陸運用已經使用的非常的廣泛。所以我認為掌握單點登陸是十分有必要的。

GitHub 源碼地址:https://github.com/zhoubiao188/spring_cloud_study

聲明:本文系CSDN部落格原創文章,轉載請聯繫原作者。

【End】

5G進入元年,物聯網發展愈加火爆!你是否身懷絕技、卻無人知曉;別讓你的IoT項目再默默無聞了!繼第一屆AI優秀案例評選活動之後,2019年案例評選活動再度升級,CSDN將評選出TOP 50優秀IoT案例,趕快掃碼參與評選吧!重磅福利,等你來領!

熱 文推 薦

獲得更多的PTT最新消息
按讚加入粉絲團