SpringSecurity動態加載用戶角色權限實現登錄及鑒權

      網友投稿 974 2022-05-30

      很多人覺得Spring Security實現登錄驗證很難,我最開始學習的時候也這樣覺得。因為我好久都沒看懂我該怎么樣將自己寫的用于接收用戶名密碼的Controller與Spring Security結合使用,這是一個先入為主的誤區。后來我搞懂了:根本不用你自己去寫Controller。你只需要告訴Spring Security用戶信息、角色信息、權限信息、登錄頁是什么?登陸成功頁是什么?或者其他有關登錄的一切信息。具體的登錄驗證邏輯它來幫你實現。

      一、動態數據登錄驗證的基礎知識

      在本號之前的文章中,已經介紹了Spring Security的formLogin登錄認證模式,RBAC的權限控制管理模型,并且針對Spring Security的登錄認證邏輯源碼進行了解析等等。我們所有的用戶、角色、權限信息都是在配置文件里面寫死的,然而在實際的業務系統中,這些信息通常是存放在RBAC權限模型的數據庫表中的。下面我們來回顧一下其中的核心概念:

      RBAC的權限模型可以從用戶獲取為用戶分配的一個或多個角色,從用戶的角色又可以獲取該角色的多種權限。通過關聯查詢可以獲取某個用戶的角色信息和權限信息。

      在源碼解析的文章中,我們知道如果我們不希望用戶、角色、權限信息寫死在配置里面。我們應該實現UserDetails與UserDetailsService接口,從而從數據庫或者其他的存儲上動態的加載這些信息。

      以上是對一些核心的基礎知識的總結,如果您對這些知識還不是很清晰,建議您先往下讀本文。如果看完本文仍然理解困難,建議您翻看本號之前的文章。

      二、UserDetails與UserDetailsService接口

      UserDetailsService接口有一個方法叫做loadUserByUsername,我們實現動態加載用戶、角色、權限信息就是通過實現該方法。函數見名知義:通過用戶名加載用戶。該方法的返回值就是UserDetails。

      UserDetails就是用戶信息,即:用戶名、密碼、該用戶所具有的權限。

      下面我們來看一下UserDetails接口都有哪些方法。

      public interface UserDetails extends Serializable { //獲取用戶的權限集合 Collection getAuthorities(); //獲取密碼 String getPassword(); //獲取用戶名 String getUsername(); //賬號是否沒過期 boolean isAccountNonExpired(); //賬號是否沒被鎖定 boolean isAccountNonLocked(); //密碼是否沒過期 boolean isCredentialsNonExpired(); //賬戶是否可用 boolean isEnabled(); }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      現在,我們明白了,只要我們把這些信息提供給Spring Security,Spring Security就知道怎么做登錄驗證了,根本不需要我們自己寫Controller實現登錄驗證邏輯。

      三、實現UserDetails 接口

      public class SysUser implements UserDetails{ String password(); //密碼 String username(); //用戶名 boolean accountNonExpired; //是否沒過期 boolean accountNonLocked; //是否沒被鎖定 boolean credentialsNonExpired; //是否沒過期 boolean enabled; //賬號是否可用 Collection authorities; //用戶的權限集合 //省略構造方法 //省略set方法 //省略get方法(即接口UserDetails的方法) }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      我們就是寫了一個適應于UserDetails的java POJO類,所謂的 UserDetails接口實現就是一些get方法。get方法由Spring Security調用,我們通過set方法或構造函數為 Spring Security提供UserDetails數據。

      四、實現UserDetailsService接口

      @Component public class MyUserDetailsService implements UserDetailsService{ @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { //這里從數據庫sys_user表里面查詢實體類對象。loadUser方法可使用Mybatis或JDBC或JPA自行實現。 SysUser sysUser = loadUser(username); // 判斷用戶是否存在 if(user == null) { throw new UsernameNotFoundException("用戶名不存在"); } //從數據庫該用戶所有的角色信息,所有的權限標志 //遍歷所有的ROLE角色及所有的Authority權限(菜單、按鈕)。 //用逗號分隔他們的唯一標志,具體過程自行實現。 sysUser.setAuthorities( AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_AMIN , system:user:delete")); //sysUser.setAccountNonLocked(true或false); return sysUser; } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      SpringSecurity動態加載用戶角色權限實現登錄及鑒權

      16

      17

      18

      19

      20

      21

      22

      通常數據庫表sys_user字段要和SysUser屬性一一對應,比如username、password、enabled。但是比如accountNonLocked字段用于登錄多次錯誤鎖定,但我們一般不會在表里存是否鎖定,而是存一個鎖定時間字段。通過鎖定時間是否大于當前時間判斷賬號是否鎖定,所以實現過程中可以靈活做判斷并用好set方法,不必拘泥于一一對應的形式。

      角色是一種特殊的權限,在Spring Security我們可以使用hasRole(角色標識)表達式判斷用戶是否具有某個角色,決定他是否可以做某個操作;通過hasAuthority(權限標識)表達式判斷是否具有某個操作權限。

      五、最后說明

      至此,我們將系統里面的所有的用戶、角色、權限信息都通過UserDetailsService和UserDetails告知了Spring Security。但是多數朋友可能仍然不知道該怎樣實現登錄的功能,其實剩下的事情很簡單了:

      寫一個登錄界面,寫一個登錄表單,表單使用post方法提交到默認的/login路徑

      表單的用戶名、密碼字段名稱默認是username、password。

      寫一個登錄成功之后的跳轉頁面,比如index.html

      然后把這些信息通過配置方式告知Spring Security ,以上的配置信息名稱都可以靈活修改。如果您不知道如何配置請參考本號之前的文章《formLogin登錄認證模式》。

      期待您的關注

      向您推薦博主的系列文檔:《手摸手教您學習SpringBoot系列-16章97節》

      本文轉載注明出處(必須帶連接,不能只轉文字):字母哥博客。

      Spring

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:WordPress使用淘寶IP地址庫的API顯示評論者的位置信息(二)
      下一篇:滾雪球學 Python 第三輪,Python Web 之 Django 的世界
      相關文章
      亚洲最大视频网站| 亚洲视频一区二区三区| 国产成人高清亚洲一区91| 亚洲精品午夜无码电影网| mm1313亚洲精品国产| 亚洲一区二区三区乱码在线欧洲| 精品亚洲麻豆1区2区3区| 日韩亚洲人成在线综合日本| 久久久久亚洲AV无码专区网站| 亚洲性色AV日韩在线观看| 亚洲AV无码一区东京热| 亚洲国产精品无码久久一线| 亚洲成在人线av| 久久久久久亚洲av成人无码国产| 亚洲AV无码一区东京热久久 | 麻豆亚洲AV永久无码精品久久| 亚洲AV日韩精品久久久久久| 婷婷精品国产亚洲AV麻豆不片| 亚洲无删减国产精品一区| 亚洲黄色在线视频| 久久久久久亚洲Av无码精品专口| 7777久久亚洲中文字幕蜜桃| 亚洲国产精品日韩在线| 色在线亚洲视频www| 亚洲欧美成人av在线观看| 九九精品国产亚洲AV日韩| 亚洲第一区精品日韩在线播放| 国产精品高清视亚洲一区二区| 亚洲中文字幕久久精品蜜桃| 国产精品亚洲精品久久精品| 亚洲国产精品综合久久网络| 亚洲一区爱区精品无码| 久久夜色精品国产嚕嚕亚洲av| 99久久亚洲综合精品成人网| 亚洲免费黄色网址| 亚洲国产精品自在自线观看| 亚洲国产aⅴ综合网| 精品亚洲一区二区| 亚洲电影唐人社一区二区| 一本天堂ⅴ无码亚洲道久久| 青草久久精品亚洲综合专区|