久久精品国产亚洲高清|精品日韩中文乱码在线|亚洲va中文字幕无码久|伊人久久综合狼伊人久久|亚洲不卡av不卡一区二区|精品久久久久久久蜜臀AV|国产精品19久久久久久不卡|国产男女猛烈视频在线观看麻豆

    1. <style id="76ofp"></style>

      <style id="76ofp"></style>
      <rt id="76ofp"></rt>
      <form id="76ofp"><optgroup id="76ofp"></optgroup></form>
      1. 千鋒教育-做有情懷、有良心、有品質(zhì)的職業(yè)教育機(jī)構(gòu)

        手機(jī)站
        千鋒教育

        千鋒學(xué)習(xí)站 | 隨時隨地免費學(xué)

        千鋒教育

        掃一掃進(jìn)入千鋒手機(jī)站

        領(lǐng)取全套視頻
        千鋒教育

        關(guān)注千鋒學(xué)習(xí)站小程序
        隨時隨地免費學(xué)習(xí)課程

        當(dāng)前位置:首頁  >  技術(shù)干貨  > 爆破專欄丨Spring Security系列教程之Spring Security的四種權(quán)限控制方式

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

        來源:千鋒教育
        發(fā)布人:qyf
        時間: 2021-10-27 16:46:00 1635324360

          原創(chuàng):一一哥

          前言:

          在前面的章節(jié)中,一一哥 已經(jīng)給大家介紹了Spring Security的很多功能,在這些眾多功能中,我們知道其核心功能其實就是認(rèn)證+授權(quán)。

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

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

          一. 權(quán)限控制方式

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

          利用Ant表達(dá)式實現(xiàn)權(quán)限控制;

          利用授權(quán)注解結(jié)合SpEl表達(dá)式實現(xiàn)權(quán)限控制;

          利用過濾器注解實現(xiàn)權(quán)限控制;

          利用動態(tài)權(quán)限實現(xiàn)權(quán)限控制。

          對上面說到的四種權(quán)限控制方式,我們接下來分別進(jìn)行講解實現(xiàn)。

          二. 利用Ant表達(dá)式實現(xiàn)權(quán)限控制

          利用Ant表達(dá)式的權(quán)限控制方式,是我們之前一直在使用的權(quán)限控制方式,在進(jìn)行代碼實現(xiàn)之前,我先對這種方式的底層實現(xiàn)進(jìn)行簡單分析。

          1. Spring Security中的權(quán)限控制方法

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

        1.webp

          SecurityExpressionOperations接口中的

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

        2.webp

        3.webp

          2. Spring Security中的權(quán)限控制粒度

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

        4.webp

          3. 代碼實現(xiàn)

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

          那么如果我們需要對URL接口粒度進(jìn)行權(quán)限控制,按如下代碼即可實現(xiàn):

          @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()

          //對跨域請求偽造進(jìn)行防護(hù)---->csrf:利用用戶帶有登錄狀態(tài)的cookie進(jìn)行攻擊的手段

          .csrf()

          .disable();

          }

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

          三. 利用授權(quán)注解結(jié)合SpEl表達(dá)式實現(xiàn)權(quán)限控制

          1. 授權(quán)注解

          除了可以使用上面的Ant表達(dá)式進(jìn)行授權(quán)實現(xiàn),我們也可以在方法上添加授權(quán)注解來權(quán)限控制,常用的授權(quán)注解有3個:

          @PreAuthorize:方法執(zhí)行前進(jìn)行權(quán)限檢查;

          @PostAuthorize:方法執(zhí)行后進(jìn)行權(quán)限檢查;

          @Secured:類似于 @PreAuthorize。

          2. 代碼實現(xiàn)

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

          @Configuration

          @EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)

          public class SecurityConfig extends WebSecurityConfigurerAdapter {

          ...

          ...

          }

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

          @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表達(dá)式進(jìn)行權(quán)限控制更靈活方便,所以開發(fā)時這種寫法很常用。

          四. 利用過濾器注解實現(xiàn)權(quán)限控制

          1. 過濾器注解簡介

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

          2. @PostFilter的用法

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

          @Slf4j

          @RestController

          public class FilterController {

          /**

          * 只返回結(jié)果中id為偶數(shù)的user元素。

          * filterObject是@PreFilter和@PostFilter中的一個內(nèi)置表達(dá)式,表示集合中的當(dāng)前對象。

          */

          @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;

          }

          }

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

        5.webp

          3. @PreFilter的用法

          使用@PreFilter也可以對集合類型的參數(shù)進(jìn)行過濾,當(dāng)@PreFilter標(biāo)注的方法內(nèi)擁有多個集合類型的參數(shù)時,可以通過@PreFilter的filterTarget屬性來指定當(dāng)前是針對哪個參數(shù)進(jìn)行過濾的;而filterObject是@PreFilter中的一個內(nèi)置表達(dá)式,表示集合中的元素對象。

          為了方便測試,我們在Service層中進(jìn)行過濾操作,然后在Controller層中進(jìn)行調(diào)用。

          FilterService類中的方法定義:

          @Slf4j

          @Service

          public class FilterService {

          /**

          * 當(dāng)@PreFilter標(biāo)注的方法內(nèi)擁有多個集合類型的參數(shù)時,

          * 可以通過@PreFilter的filterTarget屬性來指定當(dāng)前是針對哪個參數(shù)進(jìn)行過濾的。

          */

          @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 {

          /**

          * 只返回結(jié)果中id為偶數(shù)的user元素。

          * filterObject是@PreFilter和@PostFilter中的一個內(nèi)置表達(dá)式,表示集合中的當(dāng)前對象。

          */

          @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);

          }

          }

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

        6.webp

          4. 代碼結(jié)構(gòu)

          下圖是上面案例的代碼結(jié)構(gòu),請參考實現(xiàn):

        7.webp

          五. 利用動態(tài)權(quán)限實現(xiàn)權(quán)限控制

          我們知道一個標(biāo)準(zhǔn)的RABC, 權(quán)限系統(tǒng)需要支持動態(tài)配置,Spring Security默認(rèn)是在代碼里約定好權(quán)限,真實的業(yè)務(wù)場景里通常需要可以支持動態(tài)配置角色訪問權(quán)限,即在運(yùn)行時去配置url對應(yīng)的訪問角色。

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

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

        圖片1

        掃碼關(guān)注公眾號【Java架構(gòu)棧】,獲取全套專欄內(nèi)容及代碼

        tags:
        聲明:本站稿件版權(quán)均屬千鋒教育所有,未經(jīng)許可不得擅自轉(zhuǎn)載。
        10年以上業(yè)內(nèi)強(qiáng)師集結(jié),手把手帶你蛻變精英
        請您保持通訊暢通,專屬學(xué)習(xí)老師24小時內(nèi)將與您1V1溝通
        免費領(lǐng)取
        今日已有369人領(lǐng)取成功
        劉同學(xué) 138****2860 剛剛成功領(lǐng)取
        王同學(xué) 131****2015 剛剛成功領(lǐng)取
        張同學(xué) 133****4652 剛剛成功領(lǐng)取
        李同學(xué) 135****8607 剛剛成功領(lǐng)取
        楊同學(xué) 132****5667 剛剛成功領(lǐng)取
        岳同學(xué) 134****6652 剛剛成功領(lǐng)取
        梁同學(xué) 157****2950 剛剛成功領(lǐng)取
        劉同學(xué) 189****1015 剛剛成功領(lǐng)取
        張同學(xué) 155****4678 剛剛成功領(lǐng)取
        鄒同學(xué) 139****2907 剛剛成功領(lǐng)取
        董同學(xué) 138****2867 剛剛成功領(lǐng)取
        周同學(xué) 136****3602 剛剛成功領(lǐng)取
        相關(guān)推薦HOT
        有什么工具能進(jìn)行服務(wù)器性能監(jiān)控?

        一、NagiosNagios是一款廣泛使用的開源監(jiān)控工具,用于監(jiān)控服務(wù)器、網(wǎng)絡(luò)設(shè)備和應(yīng)用程序的狀態(tài)和性能。它支持對各種指標(biāo)的監(jiān)控,如CPU使用率、內(nèi)...詳情>>

        2023-10-14 00:12:36
        應(yīng)用服務(wù)器與Web服務(wù)器有什么區(qū)別?

        一、功能定位不同應(yīng)用服務(wù)器是一種軟件平臺,用于提供各種應(yīng)用程序的運(yùn)行環(huán)境。它負(fù)責(zé)管理和執(zhí)行應(yīng)用程序的邏輯,處理數(shù)據(jù)傳輸和事務(wù)管理等任務(wù)...詳情>>

        2023-10-14 00:05:39
        番茄工作法的優(yōu)點和缺陷都有哪些?

        一、番茄工作法概述番茄工作法是一種時間管理技術(shù),旨在提高工作效率和集中注意力。該方法由弗朗西斯科·西里洛于1980年代開發(fā),并逐漸流行起來...詳情>>

        2023-10-14 00:00:49
        PHP數(shù)組具的特性有哪些?

        一、有序集合PHP數(shù)組是一個有序的數(shù)據(jù)集合,它可以存儲多個值,并使用索引來訪問這些值。索引可以是數(shù)字或字符串,允許你以靈活的方式組織和訪...詳情>>

        2023-10-13 23:46:55
        C語言中定義與聲明的含義是什么?

        一、定義的含義在C語言中,定義是指為變量、函數(shù)或類型分配存儲空間并指定其屬性和初始值的過程。定義的主要含義如下:分配存儲空間:定義一個...詳情>>

        2023-10-13 23:32:41
        快速通道
        油尖旺区| 古蔺县| 萨嘎县| 天峨县| 蕉岭县| 兴国县| 绥化市| 东港市| 三穗县| 丽江市| 福泉市| 南通市| 信阳市| 电白县| 囊谦县| 科技| 新化县| 淮南市| 蛟河市| 清苑县| 麟游县| 东台市| 江陵县| 汝州市| 荆州市| 广东省| 阿鲁科尔沁旗| 蒙阴县| 江都市| 桃江县| 呼图壁县| 华坪县| 凉城县| 高阳县| 漾濞| 左权县| 山东省| 政和县| 阜南县| 高密市| 湖北省|