springSecurity的學習筆記--使用spring-Security完成表單登陸,手機驗證碼登陸,第三方登陸
環境搭建好後,之後的練習進入了一個十分痛苦的階段!! 但是與此同時,收穫也是比較可觀的。 老師通過詳細的視訊講解,完成了表單登陸,包括賬號密碼和驗證碼登陸,手機驗證碼登陸,第三方登陸。 每一個部分都進行了開發步驟說明,思路引領,以及程式碼重構!!!
通過以往的學習經驗,我知道唯有將學習的內容以筆記的形式固定下來,才有可能學習到所學習內容的50%左右。 否則無論學習當時是如何的自信,認為自己掌握的如何如何爾爾,當經過時間的淘洗,剩下的唯有一句話:“我曾經學過!”。 這對正在學習階段的那個自己是極為不負責的!! 所以無論怎樣我要寫筆記!!
但是這麼多的內容,企圖用一篇文章寫下來是不現實的。 中間還有那麼多的步驟,以及那些可貴的思想!! 但是魚和熊掌不可兼得。 廢話就這麼多。
重要的依賴檔案:
<dependency> <groupId>org.springframework.social</groupId> <artifactId>spring-social-security</artifactId> </dependency> <dependency> <groupId>org.springframework.social</groupId> <artifactId>spring-social-config</artifactId> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> </dependency>
程式碼結構:
理解:springsecurity的核心是:過濾器。 所有的操作均以過濾鏈為核心展開!!
表單登陸要素:
1.過濾鏈上進行註冊:
如何註冊???:
如何開放註冊頁面???:
2.自定義憑證邏輯。
表單+圖形驗證碼登陸要素:
1.定義圖形驗證碼的處理邏輯。 它的原理是,前端請求進來,生成一個驗證碼並寫入session(該session針對使用者的),將驗證碼寫入到圖片流中,進行混淆。 之後寫入到請求的輸出流中。 封裝過後的程式碼如下:
對整個邏輯進行了分層抽象的實現。:
第一層:
第二層:
第三層:
到此為止,關於圖形驗證碼的生成過程及相關的邏輯就完成了!! 但是這不是核心。。 我們知道所有的東西都要圍繞過濾鏈來進行。 所以重心應該是過濾器邏輯!!
2.進行過濾器的核心配置:
它包含兩個內容: 攔截的路徑,以及過濾處理。
3.將過濾器放到過濾鏈進行註冊:
這樣便完成了圖片驗證碼與賬號密碼的登陸邏輯。
手機驗證碼登陸要素:
手機驗證碼實際上的處理邏輯與圖片驗證碼的處理邏輯類似,只是圖片驗證碼是通過寫入響應,以流的形式直接作用於前端。 手機驗證碼是通過簡訊服務商傳送給使用者的手機。 但是它們的驗證原理仍然是一樣的。 第一步生成驗證碼並寫入session, 第二步,傳送給終端(瀏覽器,或者手機)。 第三部,驗證!。
老師已經進行了極為完美的抽象與封裝,所以我們可以很方便的實現呼叫。 它的傳送實現已經在上文中貼上。
然而它的本質不同在於: 它的信用憑證!!!
因為它不是與表單登陸使用同一個信用憑證,所以我們要單獨處理 過濾器的邏輯,以及信用提供商的邏輯。 但是,整個過程任然是以過濾器為核心,並由此衍生的程式碼邏輯而已!!
1.定義憑證:
2.定義憑證提供商:
2.簡訊驗證碼的過濾器:
過濾的核心流程通過抽象類進行封裝。 我們只需覆寫:
4.將簡訊驗證碼的驗證邏輯註冊到過濾鏈中:
注意,這個過濾器與註冊登陸過濾器二者無限後順序。 但是二者是邏輯上互斥的。 也就是說某次認證,只需要通過二者其一即可。
以上是簡訊驗證碼的相關邏輯環境。 經測試一切正常。
第三方登陸的要素:
第三方登陸主要是基於OAUTH協議。 所以與其說學習第三方登陸的實踐。 倒不如說學習OAUTH協議。 但是畢竟現在自己還是能力有限,所以還是慢慢來,記錄一下qq的第三方登陸的開發的過程。 當然它的核心任然是圍繞過濾器展開。
1.過濾器的來源:
2.過濾器在過濾器鏈條的註冊:
3.配置OAUTH的相關構件:
api:
serviceProvider:
需要注意,在這個途中有一個特別重要的實體: 授權碼。。
connectionFactory:
connecAdapter:
針對qq所定製的oauth2模板:
4.配置邏輯上的“令牌”提供者:
到此,整個第三方登陸的流程就完成了。測試一切正常!
過程還是比較多,比較的雜亂!
看了老師的視訊以及自己親自實踐後,來討論它如何以過濾器為核心展開的???
第一,由特定的過濾器攔截相關的地址。 對攔截到的地址進行引數判定! 若有授權碼“code"屬性,認為是從第三方發來的。 用以完成接下來的獲取令牌的邏輯! 若沒有,則認為是使用者訪問的,將之匯入到相應的第三方進行認證,其目的是為了獲得授權碼!! 這個轉換的關鍵在於回撥地址。
第二,api充當邏輯上的憑證,connectionFacotry充當邏輯上的憑證提供者。 唯有憑證提供者在容器中存在,整個攔截過程才會生效。 否則本次攔截無效,由其它攔截器處理。
第三,上面兩步核心的配置均不是由我們直接操作完成的。 至少在spring-boot中是這樣。
第四,要完成自定義的攔截地址,以及自定義的providerId配置實現:
第三方認證登陸並註冊邏輯實現:
spring-social會為第三方登陸維護一張資料表。 它的相關實現:
表結構位於UsersConnectionRepository同級包下。
這就產生了認證後登陸,與直接自動登陸的邏輯需求。
1.認證後註冊登陸的實現:(觸發條件: 在表中沒有查到資訊,並且上下文中沒有(connectionSignup的實現,由spring-social提供)
預設為/signup。 自定義的實現:
注意,該地址預設為一個資源檢視地址。 。換言之,它必須開放!!即不能用攔截器進行攔截的地址。
為了在註冊的時候完成與第三方相關資訊相連線。 需要提供一個工具類:
它的使用示例:
2.認證後自動登陸的實現:(只需破環滿足上一個條件的條件即可)。如:
最重要的一點完了說:
因為這個與簡訊驗證碼一樣,也是獨立的。 為他提供憑證支撐的userServiceDetail必須實現介面:SocialUserDetailsService
第三方繫結與解綁的實現:
由spring-social自動附帶的功能。
直接看程式碼說話:
微信第三方登陸的實現:
qq同理可得。
與qq的一些區別:
那麼微信的關鍵就是,這個openId如何獲得呢??且看下文:
就這樣吧。 回顧的時候,發現還有記住我功能,以及 session管理的相關內容沒有記錄。 吃了飯再找個實踐記錄一下吧!