<pre id="13q3s"><s id="13q3s"><menu id="13q3s"></menu></s></pre>
          <tr id="13q3s"><s id="13q3s"></s></tr>

          千鋒教育-做有情懷、有良心、有品質的職業教育機構

          領取全套視頻

          關注千鋒學習站小程序
          隨時隨地免費學習課程

          當前位置:首頁  >  關于學院  >  技術論壇  >  正文

          爆破專欄丨Spring Security系列教程之Spring Security的四種權限控制方式

          時間:2021-10-27 16:46     來源:千鋒教育 作者:qyf
          分享: 更多

            原創:一一哥

            前言:

            在前面的章節中,一一哥 已經給大家介紹了Spring Security的很多功能,在這些眾多功能中,我們知道其核心功能其實就是認證+授權。

            在前面我們分別基于內存模型、基于默認的數據庫模型、基于自定義數據庫模型實現了認證和授權功能,但是不管哪種方式,我們對某個接口的攔截限制,都是通過編寫一個SecurityConfig配置類,在該類的configure (Http Security http)方法中,通過http. authorize Requests ( ). antMatchers ("/admin/**")...這樣的代碼進行的權限控制。

            這種權限控制方法雖然也可以實現對某些接口的攔截或放行,但是不夠靈活,其實Spring Security對接口的攔截或放行的寫法,還有另外的方式,接下來請跟我學習一下吧!

            一. 權限控制方式

            在Spring Security 中,我們既可以使用 Spring Security 提供的默認方式進行授權,也可以進行自定義授權,總之在Spring Security中權限控制的實現方式是比較靈活多樣的。在Spring Security 中,對接口的攔截或放行,有四種常見的權限控制方式:

            利用Ant表達式實現權限控制;

            利用授權注解結合SpEl表達式實現權限控制;

            利用過濾器注解實現權限控制;

            利用動態權限實現權限控制。

            對上面說到的四種權限控制方式,我們接下來分別進行講解實現。

            二. 利用Ant表達式實現權限控制

            利用Ant表達式的權限控制方式,是我們之前一直在使用的權限控制方式,在進行代碼實現之前,我先對這種方式的底層實現進行簡單分析。

            1. Spring Security中的權限控制方法

            在Spring Security中,有一個Security Expression Operations 接口,在該接口中定義了一系列的方法,用于用戶權限的設置,如下圖:

          1.webp

            SecurityExpressionOperations接口中的

            這些方法作用如下圖所示:

          2.webp

          3.webp

            2. Spring Security中的權限控制粒度

            這個接口有一個SecurityExpressionRoot子類,該類提供了基于表達式的權限控制實現方式。而這個SecurityExpressionRoot 又有兩個實現子類,分別用于實現 URL Web接口粒度的權限控制和方法粒度的權限控制,如下圖所示:

          4.webp

            3. 代碼實現

            從上面的小節中,我們知道在Spring Security中,支持2種粒度的權限控制,即URL Web接口粒度 和方法粒度,而我們這里所謂的 Ant表達式授權控制方式,就是通過Ant表達式來控制 URL 接口的訪問權限。

            那么如果我們需要對URL接口粒度進行權限控制,按如下代碼即可實現:

            @Override

            protected void configure(HttpSecurity http) throws Exception {

            http.authorizeRequests()

            .antMatchers("/admin/**")

            .hasRole("ADMIN")

            .antMatchers("/user/**")

            .hasRole("USER")

            .antMatchers("/visitor/**")

            .permitAll()

            .anyRequest()

            .authenticated()

            .and()

            .formLogin()

            .permitAll()

            .and()

            //對跨域請求偽造進行防護---->csrf:利用用戶帶有登錄狀態的cookie進行攻擊的手段

            .csrf()

            .disable();

            }

            以上代碼中,/admin/ 格式的路徑需要 admin 角色才可以訪問,/user/ 格式的路徑需要 user 角色才可以訪問,/visitor/** 格式的路徑可以直接訪問,其他接口路徑則需要登錄后才能訪問。

            三. 利用授權注解結合SpEl表達式實現權限控制

            1. 授權注解

            除了可以使用上面的Ant表達式進行授權實現,我們也可以在方法上添加授權注解來權限控制,常用的授權注解有3個:

            @PreAuthorize:方法執行前進行權限檢查;

            @PostAuthorize:方法執行后進行權限檢查;

            @Secured:類似于 @PreAuthorize。

            2. 代碼實現

            要想利用以上3個授權注解進行權限控制,我們首先需要利用@EnableGlobalMethodSecurity注解開啟授權注解功能,代碼如下:

            @Configuration

            @EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)

            public class SecurityConfig extends WebSecurityConfigurerAdapter {

            ...

            ...

            }

            然后在具體的接口方法上利用授權注解進行權限控制,代碼如下:

            @RestController

            public class UserController {

            @Secured({"ROLE_USER"})

            //@PreAuthorize("principal.username.equals('user')")

            @GetMapping("/user/hello")

            public String helloUser() {

            return "hello, user";

            }

            @PreAuthorize("hasRole('ADMIN')")

            @GetMapping("/admin/hello")

            public String helloAdmin() {

            return "hello, admin";

            }

            @PreAuthorize("#age>100")

            @GetMapping("/age")

            public String getAge(@RequestParam("age") Integer age) {

            return String.valueOf(age);

            }

            @GetMapping("/visitor/hello")

            public String helloVisitor() {

            return "hello, visitor";

            }

            }

            可以看出,這種寫法明顯比利用Ant表達式進行權限控制更靈活方便,所以開發時這種寫法很常用。

            四. 利用過濾器注解實現權限控制

            1. 過濾器注解簡介

            在Spring Security中還提供了另外的兩個注解,即@PreFilter和@PostFilter,這兩個注解可以對集合類型的參數或返回值進行過濾。使用@PreFilter和@PostFilter時,Spring Security將移除對應表達式結果為false的元素。

            2. @PostFilter的用法

            @PostFilter注解主要是用于對集合類型的返回值進行過濾,filterObject是@PostFilter中的一個內置表達式,表示集合中的元素對象。

            @Slf4j

            @RestController

            public class FilterController {

            /**

            * 只返回結果中id為偶數的user元素。

            * filterObject是@PreFilter和@PostFilter中的一個內置表達式,表示集合中的當前對象。

            */

            @PostFilter("filterObject.id%2==0")

            @GetMapping("/users")

            public ListgetAllUser() {

            Listusers = new ArrayList<>();

            for (int i = 0; i < 10; i++) {

            users.add(new User(i, "yyg-" + i));

            }

            return users;

            }

            }

            我們啟動瀏覽器進行測試,可以看到測試接口中只返回了id為偶數的元素。

          5.webp

            3. @PreFilter的用法

            使用@PreFilter也可以對集合類型的參數進行過濾,當@PreFilter標注的方法內擁有多個集合類型的參數時,可以通過@PreFilter的filterTarget屬性來指定當前是針對哪個參數進行過濾的;而filterObject是@PreFilter中的一個內置表達式,表示集合中的元素對象。

            為了方便測試,我們在Service層中進行過濾操作,然后在Controller層中進行調用。

            FilterService類中的方法定義:

            @Slf4j

            @Service

            public class FilterService {

            /**

            * 當@PreFilter標注的方法內擁有多個集合類型的參數時,

            * 可以通過@PreFilter的filterTarget屬性來指定當前是針對哪個參數進行過濾的。

            */

            @PreFilter(filterTarget = "ids", value = "filterObject%2==0")

            public ListdoFilter(Listids, Listusers) {

            log.warn("ids=" + ids.toString());

            log.warn("users=" + users.toString());

            return ids;

            }

            }

            在Controller中定義一個測試接口:

            @Slf4j

            @RestController

            public class FilterController {

            /**

            * 只返回結果中id為偶數的user元素。

            * filterObject是@PreFilter和@PostFilter中的一個內置表達式,表示集合中的當前對象。

            */

            @PostFilter("filterObject.id%2==0")

            @GetMapping("/users")

            public ListgetAllUser() {

            Listusers = new ArrayList<>();

            for (int i = 0; i < 10; i++) {

            users.add(new User(i, "yyg-" + i));

            }

            return users;

            }

            @Autowired

            private FilterService filterService;

            @GetMapping("/users2")

            public ListgetUserInfos() {

            Listids = new ArrayList<>();

            for (int i = 0; i < 10; i++) {

            ids.add(i);

            }

            Listusers = new ArrayList<>();

            for (int i = 0; i < 10; i++) {

            users.add(new User(i, "yyg-" + i));

            }

            return filterService.doFilter(ids, users);

            }

            }

            我們啟動瀏覽器進行測試,可以看到測試接口中只返回id為偶數的元素。

          6.webp

            4. 代碼結構

            下圖是上面案例的代碼結構,請參考實現:

          7.webp

            五. 利用動態權限實現權限控制

            我們知道一個標準的RABC, 權限系統需要支持動態配置,Spring Security默認是在代碼里約定好權限,真實的業務場景里通常需要可以支持動態配置角色訪問權限,即在運行時去配置url對應的訪問角色。

            而Spring Security中的動態權限,主要是通過重寫攔截器和決策器來進行實現,最簡單的方法就是自定義一個Filter去完成權限判斷。其實這里涉及到的代碼,基本和Spring Security關系不大,主要是在傳統的Filter進行實現,我這里就不再進行描述了,感興趣的同學可以自行實現!

            至此,我就給各位介紹了Spring Security中的4種進行權限控制的方式,各位可以結合自己的項目需求進行選擇。

          圖片1

          掃碼關注公眾號【Java架構棧】,獲取全套專欄內容及代碼

          相關文章

          • 北京總部地址:北京市海淀區寶盛北里西區28號中關村智誠科創大廈4層
            北京沙河校區:北京市昌平區沙陽路18號北京科技職業技術學院廣場服務樓
            咨詢電話:400-811-9990
            面授課程:HTML5大前端培訓、JavaEE+分布式開發培訓、Python全棧+人工智能培訓、全鏈路UI/UE設計培訓、云計算培訓、全棧軟件測試培訓、大數據+人工智能培訓、智能物聯網+嵌入式培訓、Unity游戲開發培訓、Go語言開發培訓、PHP全棧+服務器集群培訓、網絡安全培訓、網絡營銷培訓、好程序員
            認證課程:軟考、Adobe認證、PMP認證、紅帽RHCE認證
          • 深圳校區地址:深圳市寶安區寶安大道5010號西部硅谷B座A區6層A605/B座C區1層108
            咨詢電話:400-811-9990
            面授課程:HTML5大前端培訓、JavaEE+分布式開發培訓、Python全棧+人工智能培訓、全鏈路UI/UE設計培訓、云計算培訓、全棧軟件測試培訓、大數據+人工智能培訓、智能物聯網+嵌入式培訓、Unity游戲開發培訓、Go語言開發培訓、PHP全棧+服務器集群培訓、網絡安全培訓、網絡營銷培訓、好程序員
            認證課程:軟考、Adobe認證、PMP認證、紅帽RHCE認證
          • 上海校區地址:上海市寶山區同濟支路199號智慧七立方3號樓2-4層
            咨詢電話:400-811-9990
            面授課程:HTML5大前端培訓、JavaEE+分布式開發培訓、Python全棧+人工智能培訓、全鏈路UI/UE設計培訓、云計算培訓、全棧軟件測試培訓、大數據+人工智能培訓、智能物聯網+嵌入式培訓、Unity游戲開發培訓、Go語言開發培訓、PHP全棧+服務器集群培訓、網絡安全培訓、網絡營銷培訓、好程序員
            認證課程:軟考、Adobe認證、PMP認證、紅帽RHCE認證
          • 廣州校區地址:廣州市白云區永平街永泰學山塘學山文化創意谷A1棟六樓
            咨詢電話:400-811-9990
            面授課程:HTML5大前端培訓、JavaEE+分布式開發培訓、Python全棧+人工智能培訓、全鏈路UI/UE設計培訓、云計算培訓、全棧軟件測試培訓、大數據+人工智能培訓、智能物聯網+嵌入式培訓、Unity游戲開發培訓、Go語言開發培訓、PHP全棧+服務器集群培訓、網絡安全培訓、網絡營銷培訓、好程序員
            認證課程:軟考、Adobe認證、PMP認證、紅帽RHCE認證
          • 鄭州二七區校區地址:鄭州市二七區航海中路60號海為科技園C區10層
            鄭州高新區校區地址:鄭州市高新區金梭路與銀杏路交叉口教育科技產業園南門D座4層
            咨詢電話:400-811-9990
            面授課程:HTML5大前端培訓、JavaEE+分布式開發培訓、Python全棧+人工智能培訓、全鏈路UI/UE設計培訓、云計算培訓、全棧軟件測試培訓、大數據+人工智能培訓、智能物聯網+嵌入式培訓、Unity游戲開發培訓、Go語言開發培訓、PHP全棧+服務器集群培訓、網絡安全培訓、網絡營銷培訓、好程序員
            認證課程:軟考、Adobe認證、PMP認證、紅帽RHCE認證
          • 大連校區地址:遼寧省大連市高新園區愛賢街10號大連設計城A座901
            咨詢電話:400-811-9990
            面授課程:HTML5大前端培訓、JavaEE+分布式開發培訓、Python全棧+人工智能培訓、全鏈路UI/UE設計培訓、云計算培訓、全棧軟件測試培訓、大數據+人工智能培訓、智能物聯網+嵌入式培訓、Unity游戲開發培訓、Go語言開發培訓、PHP全棧+服務器集群培訓、網絡安全培訓、網絡營銷培訓、好程序員
            認證課程:軟考、Adobe認證、PMP認證、紅帽RHCE認證
          • 武漢金融港校區地址:武漢市東新區光谷大道77號金融港B18棟三、四層
            咨詢電話:400-811-9990
            面授課程:HTML5大前端培訓、JavaEE+分布式開發培訓、Python全棧+人工智能培訓、全鏈路UI/UE設計培訓、云計算培訓、全棧軟件測試培訓、大數據+人工智能培訓、智能物聯網+嵌入式培訓、Unity游戲開發培訓、Go語言開發培訓、PHP全棧+服務器集群培訓、網絡安全培訓、網絡營銷培訓、好程序員
            認證課程:軟考、Adobe認證、PMP認證、紅帽RHCE認證
          • 成都校區地址:成都市高新區肖家河沿街138號肖家河大廈三樓
            咨詢電話:400-811-9990
            面授課程:HTML5大前端培訓、JavaEE+分布式開發培訓、Python全棧+人工智能培訓、全鏈路UI/UE設計培訓、云計算培訓、全棧軟件測試培訓、大數據+人工智能培訓、智能物聯網+嵌入式培訓、Unity游戲開發培訓、Go語言開發培訓、PHP全棧+服務器集群培訓、網絡安全培訓、網絡營銷培訓、好程序員
            認證課程:軟考、Adobe認證、PMP認證、紅帽RHCE認證
          • 西安校區地址:西安市雁塔區高新六路52號立人科技C座西區4樓
            咨詢電話:400-811-9990
            面授課程:HTML5大前端培訓、JavaEE+分布式開發培訓、Python全棧+人工智能培訓、全鏈路UI/UE設計培訓、云計算培訓、全棧軟件測試培訓、大數據+人工智能培訓、智能物聯網+嵌入式培訓、Unity游戲開發培訓、Go語言開發培訓、PHP全棧+服務器集群培訓、網絡安全培訓、網絡營銷培訓、好程序員
            認證課程:軟考、Adobe認證、PMP認證、紅帽RHCE認證
          • 杭州旺田校區:浙江省杭州市上城區九堡鎮旺田書畫城A座4層
            咨詢電話:400-811-9990
            面授課程:HTML5大前端培訓、JavaEE+分布式開發培訓、Python全棧+人工智能培訓、全鏈路UI/UE設計培訓、云計算培訓、全棧軟件測試培訓、大數據+人工智能培訓、智能物聯網+嵌入式培訓、Unity游戲開發培訓、Go語言開發培訓、PHP全棧+服務器集群培訓、網絡安全培訓、網絡營銷培訓、好程序員
            認證課程:軟考、Adobe認證、PMP認證、紅帽RHCE認證
          • 青島校區地址:青島市市北區龍城路31號卓越世紀中心4號樓5層
            咨詢電話:400-811-9990
            面授課程:HTML5大前端培訓、JavaEE+分布式開發培訓、Python全棧+人工智能培訓、全鏈路UI/UE設計培訓、云計算培訓、全棧軟件測試培訓、大數據+人工智能培訓、智能物聯網+嵌入式培訓、Unity游戲開發培訓、Go語言開發培訓、PHP全棧+服務器集群培訓、網絡安全培訓、網絡營銷培訓、好程序員
            認證課程:軟考、Adobe認證、PMP認證、紅帽RHCE認證
          • 重慶校區地址:重慶市高新區科園一路2號大西洋國際12-1
            咨詢電話:400-811-9990
            面授課程:HTML5大前端培訓、JavaEE+分布式開發培訓、Python全棧+人工智能培訓、全鏈路UI/UE設計培訓、云計算培訓、全棧軟件測試培訓、大數據+人工智能培訓、智能物聯網+嵌入式培訓、Unity游戲開發培訓、Go語言開發培訓、PHP全棧+服務器集群培訓、網絡安全培訓、網絡營銷培訓、好程序員
            認證課程:軟考、Adobe認證、PMP認證、紅帽RHCE認證
          • 長沙校區地址:湖南省長沙市岳麓區麓谷企業廣場A2棟三單元306號
            咨詢電話:400-811-9990
            面授課程:HTML5大前端培訓、JavaEE+分布式開發培訓、Python全棧+人工智能培訓、全鏈路UI/UE設計培訓、云計算培訓、全棧軟件測試培訓、大數據+人工智能培訓、智能物聯網+嵌入式培訓、Unity游戲開發培訓、Go語言開發培訓、PHP全棧+服務器集群培訓、網絡安全培訓、網絡營銷培訓、好程序員
            認證課程:軟考、Adobe認證、PMP認證、紅帽RHCE認證
          • 哈爾濱校區地址:哈爾濱市松北區世澤路689號 科技創新城4號樓405
            咨詢電話:400-811-9990
            面授課程:HTML5大前端培訓、JavaEE+分布式開發培訓、Python全棧+人工智能培訓、全鏈路UI/UE設計培訓、云計算培訓、全棧軟件測試培訓、大數據+人工智能培訓、智能物聯網+嵌入式培訓、Unity游戲開發培訓、Go語言開發培訓、PHP全棧+服務器集群培訓、網絡安全培訓、網絡營銷培訓、好程序員
            認證課程:軟考、Adobe認證、PMP認證、紅帽RHCE認證
          • 南京校區地址:南京市建鄴區應天大街780號弘輝產業園1棟2層
            咨詢電話:400-811-9990
            面授課程:HTML5大前端培訓、JavaEE+分布式開發培訓、Python全棧+人工智能培訓、全鏈路UI/UE設計培訓、云計算培訓、全棧軟件測試培訓、大數據+人工智能培訓、智能物聯網+嵌入式培訓、Unity游戲開發培訓、Go語言開發培訓、PHP全棧+服務器集群培訓、網絡安全培訓、網絡營銷培訓、好程序員
            認證課程:軟考、Adobe認證、PMP認證、紅帽RHCE認證
          • 太原校區地址:太原市小店區長治路230號能源互聯網大廈6層
            咨詢電話:400-811-9990
            面授課程:HTML5大前端培訓、JavaEE+分布式開發培訓、Python全棧+人工智能培訓、全鏈路UI/UE設計培訓、云計算培訓、全棧軟件測試培訓、大數據+人工智能培訓、智能物聯網+嵌入式培訓、Unity游戲開發培訓、Go語言開發培訓、PHP全棧+服務器集群培訓、網絡安全培訓、網絡營銷培訓、好程序員
            認證課程:軟考、Adobe認證、PMP認證、紅帽RHCE認證
          • 沈陽校區地址:遼寧省沈陽市渾南區世紀路16號東大軟件園B園B1座A201
            咨詢電話:400-811-9990
            面授課程:HTML5大前端培訓、JavaEE+分布式開發培訓、Python全棧+人工智能培訓、全鏈路UI/UE設計培訓、云計算培訓、全棧軟件測試培訓、大數據+人工智能培訓、智能物聯網+嵌入式培訓、Unity游戲開發培訓、Go語言開發培訓、PHP全棧+服務器集群培訓、網絡安全培訓、網絡營銷培訓、好程序員
            認證課程:軟考、Adobe認證、PMP認證、紅帽RHCE認證
          • 合肥校區地址:合肥市包河區徽州大道396號東方廣場B座12A
            咨詢電話:400-811-9990
            面授課程:HTML5大前端培訓、JavaEE+分布式開發培訓、Python全棧+人工智能培訓、全鏈路UI/UE設計培訓、云計算培訓、全棧軟件測試培訓、大數據+人工智能培訓、智能物聯網+嵌入式培訓、Unity游戲開發培訓、Go語言開發培訓、PHP全棧+服務器集群培訓、網絡安全培訓、網絡營銷培訓、好程序員
            認證課程:軟考、Adobe認證、PMP認證、紅帽RHCE認證
          • 千鋒教育服務號

            了解千鋒動態
            關注千鋒教育服務號

          • 千鋒教育移動站

            掃一掃快速進入
            千鋒移動端頁面

          • 千鋒互聯服務號

            掃碼匿名提建議
            直達CEO信箱

          [an error occurred while processing the directive] 日韩亚洲AV人人夜夜澡人人爽
          <pre id="13q3s"><s id="13q3s"><menu id="13q3s"></menu></s></pre>
                <tr id="13q3s"><s id="13q3s"></s></tr>