日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
想要控制好權(quán)限,這八個(gè)注解你必須知道!

在講數(shù)據(jù)權(quán)限之前,我們有必要先和大家介紹一下 Spring Security 中的權(quán)限注解,把這個(gè)捋清楚了,再去看 TienChin 項(xiàng)目的權(quán)限注解,你就會發(fā)現(xiàn)非常容易了。

創(chuàng)新互聯(lián)公司2013年開創(chuàng)至今,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢想脫穎而出為使命,1280元甘南做網(wǎng)站,已為上家服務(wù),為甘南各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:13518219792

1. Spring Security 中的權(quán)限注解

Spring Security 中支持多種權(quán)限注解,首先我們需要通過 @EnableGlobalMethodSecurity 注解開啟權(quán)限注解的使用,方式如下:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true, jsr250Enabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
}

在這個(gè)注解中我們一共設(shè)置了三個(gè)屬性:

  • prePostEnabled:這個(gè)表示開啟 Spring Security 提供的四個(gè)權(quán)限注解,@PostAuthorize、@PostFilter、@PreAuthorize 以及 @PreFilter,這四個(gè)注解支持權(quán)限表達(dá)式,支持 SpEL,功能比較豐富。
  • securedEnabled:開啟 Spring Security 提供的 @Secured 注解,該注解不支持權(quán)限表達(dá)式。
  • jsr250Enabled:開啟 JSR-250 提供的注解,主要包括 @DenyAll、@PermitAll 以及 @RolesAllowed 三個(gè)注解,這些注解也不支持權(quán)限表達(dá)式。

以上這些注解的含義分別如下:

  • @PostAuthorize:在目標(biāo)方法執(zhí)行之后進(jìn)行權(quán)限校驗(yàn)。
  • @PostFilter:在目標(biāo)方法執(zhí)行之后對方法的返回結(jié)果進(jìn)行過濾。
  • @PreAuthorize:在目標(biāo)方法執(zhí)行之前進(jìn)行權(quán)限校驗(yàn)。
  • @PreFilter:在目標(biāo)方法執(zhí)行之前對方法參數(shù)進(jìn)行過濾。
  • @Secured:訪問目標(biāo)方法必須具備相應(yīng)的角色。
  • @DenyAll:拒絕所有訪問。
  • @PermitAll:允許所有訪問。
  • @RolesAllowed:訪問目標(biāo)方法必須具備相應(yīng)的角色。

這是所有的,當(dāng)然一般來說我們只要設(shè)置 prePostEnabled=true 就夠用了,也就是前四個(gè)注解基本上就能滿足大部分需求了。

另外還有一種比較“古老”的方法配置基于方法的權(quán)限管理,那就是通過 XML 文件配置方法攔截規(guī)則,目前已經(jīng)很少有用 XML 文件來配置 Spring Security 了,所以對于這種方式我們不做過多介紹。感興趣的小伙伴可以查看官網(wǎng)的相關(guān)介紹:https://docs.spring.io/spring-security/ site/docs/5.4.0/reference/html5/#secure-object-impls。

2. 權(quán)限注解實(shí)踐

接下來我們通過幾個(gè)簡單的案例來學(xué)習(xí)一下上面幾種不同注解的用法。

首先創(chuàng)建一個(gè) Spring Boot 項(xiàng)目,引入 Web 和 Spring Security 依賴,項(xiàng)目創(chuàng)建完成后,添加如下配置文件:

@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class SecurityConfig{
}

為了方便起見,我們將使用單元測試進(jìn)行驗(yàn)證,所以這里就不進(jìn)行額外的配置了,通過 @EnableGlobalMethodSecurity 注解開啟其他權(quán)限注解的使用即可。

接下來創(chuàng)建一個(gè) User 類以備后續(xù)使用:

public class User {
private Integer id;
private String username;

//省略getter/setter
}

準(zhǔn)備工作完成后,我們來逐個(gè)講解一下前面注解的用法。

2.1 @PreAuthorize

@PreAuthorize 注解可以在目標(biāo)方法執(zhí)行之前對其進(jìn)行安全校驗(yàn),在安全校驗(yàn)時(shí),可以直接使用權(quán)限表達(dá)式。例如可以定義如下方法:

@Service
public class HelloService {
@PreAuthorize("hasRole('ADMIN')")
public String hello() {
return "hello";
}
}

這里使用了權(quán)限表達(dá)式 hasRole,表示執(zhí)行該方法必須具備 ADMIN 角色才可以訪問,否則不可以訪問。接下來我們在單元測試中來測試該方法:

@SpringBootTest
class BasedOnMethodApplicationTests {
@Autowired
HelloService helloService;
@Test
@WithMockUser(roles = "ADMIN")
void preauthorizeTest01() {
String hello = helloService.hello();
assertNotNull(hello);
assertEquals("hello", hello);
}
}

通過 @WithMockUser(roles = "ADMIN") 注解設(shè)定當(dāng)前執(zhí)行的用戶角色是 ADMIN,然后調(diào)用 helloService 中的方法進(jìn)行測試即可。如果將用戶角色設(shè)置為其他字符,那單元測試就不會通過。

當(dāng)然,這里除了 hasRole 表達(dá)式之外,也可以使用其他權(quán)限表達(dá)式,甚至也可以同時(shí)使用多個(gè)權(quán)限表達(dá)式,如下所示:

@Service
public class HelloService {
@PreAuthorize("hasRole('ADMIN') and authentication.name=='javaboy'")
public String hello() {
return "hello";
}
}

表示訪問者名稱必須是 javaboy,而且還需要同時(shí)具備 ADMIN 角色,才可以訪問該方法。此時(shí)通過如下代碼對其進(jìn)行測試:

@SpringBootTest
class BasedOnMethodApplicationTests {
@Autowired
HelloService helloService;
@Test
@WithMockUser(roles = "ADMIN",username = "javaboy")
void preauthorizeTest01() {
String hello = helloService.hello();
assertNotNull(hello);
assertEquals("hello", hello);
}
}

在 @PreAuthorize 注解中,還可以通過 # 引用方法的參數(shù),并對其進(jìn)行校驗(yàn),例如如下方法表示請求者的用戶名必須等于方法參數(shù) name 的值,方法才可以被執(zhí)行:

@PreAuthorize("authentication.name==#name")
public String hello(String name) {
return "hello:" + name;
}

測試方法如下:

@Test
@WithMockUser(username = "javaboy")
void preauthorizeTest02() {
String hello = helloService.hello("javaboy");
assertNotNull(hello);
assertEquals("hello:javaboy", hello);
}

當(dāng)模擬的用戶名和方法參數(shù)相等時(shí),單元測試就可以通過。

2.2 @PreFilter

@PreFilter 主要是對方法的請求參數(shù)進(jìn)行過濾,它里邊包含了一個(gè)內(nèi)置對象 filterObject 表示要過濾的參數(shù),如果方法只有一個(gè)參數(shù),則內(nèi)置的 filterObject 對象就代表該參數(shù);如果方法有多個(gè)參數(shù),則需要通過 filterTarget 來指定 filterObject 到底代表哪個(gè)對象:

@PreFilter(value = "filterObject.id%2!=0",filterTarget = "users")
public void addUsers(List users, Integer other) {
System.out.println("users = " + users);
}

上面代碼表示對方法參數(shù) users 進(jìn)行過濾,將 id 為奇數(shù)的 user 保留。

然后通過單元測試對該方法進(jìn)行測試:

@Test
@WithMockUser(username = "javaboy")
void preFilterTest01() {
List users = new ArrayList<>();
for (int i = 0; i < 10; i++) {
users.add(new User(i, "javaboy:" + i));
}
helloService.addUsers(users, 99);
}

執(zhí)行單元測試方法,addUsers 方法中只會打印出 id 為奇數(shù)的 user 對象。

2.3 @PostAuthorize

@PostAuthorize 是在目標(biāo)方法執(zhí)行之后進(jìn)行權(quán)限校驗(yàn)??赡苡行』锇闀X得奇怪,目標(biāo)方法都執(zhí)行完了才去做權(quán)限校驗(yàn)意義何在?其實(shí)這個(gè)主要是在 ACL 權(quán)限模型中會用到,目標(biāo)方法執(zhí)行完畢后,通過 @PostAuthorize 注解去校驗(yàn)?zāi)繕?biāo)方法的返回值是否滿足相應(yīng)的權(quán)限要求。

不過呢,即使你的權(quán)限模型不是 ACL,也沒關(guān)系,也有可能用到這個(gè)注解,反正記得它的作用:方法執(zhí)行完成后,根據(jù)用戶的權(quán)限信息過濾出需要返回給用戶的數(shù)據(jù)。

從技術(shù)角度來講,@PostAuthorize 注解中也可以使用權(quán)限表達(dá)式,但是在實(shí)際開發(fā)中權(quán)限表達(dá)式一般都是結(jié)合 @PreAuthorize 注解一起使用的。@PostAuthorize 包含一個(gè)內(nèi)置對象 returnObject,表示方法的返回值,開發(fā)者可以對返回值進(jìn)行校驗(yàn):

@PostAuthorize("returnObject.id==1")
public User getUserById(Integer id) {
return new User(id, "javaboy");
}

這個(gè)表示方法返回的 user 對象的 id 必須為 1,調(diào)用才會順利通過,否則就會拋出異常。

然后通過單元測試對該方法進(jìn)行測試:

@Test
@WithMockUser(username = "javaboy")
void postAuthorizeTest01() {
User user = helloService.getUserById(1);
assertNotNull(user);
assertEquals(1,user.getId());
assertEquals("javaboy",user.getUsername());
}

如果調(diào)用時(shí)傳入的參數(shù)為 1,單元測試就會順利通過。

2.4 @PostFilter

@PostFilter 注解是在目標(biāo)方法執(zhí)行之后,對目標(biāo)方法的返回結(jié)果進(jìn)行過濾,該注解中包含了一個(gè)內(nèi)置對象 filterObject,表示目標(biāo)方法返回的集合/數(shù)組中的具體元素:

@PostFilter("filterObject.id%2==0")
public List getAll() {
List users = new ArrayList<>();
for (int i = 0; i < 10; i++) {
users.add(new User(i, "javaboy:" + i));
}
return users;
}

這段代碼表示 getAll 方法的返回值 users 集合中 user 對象的 id 必須為偶數(shù)。

然后我們通過單元測試對其進(jìn)行測試,代碼如下:

@Test
@WithMockUser(roles = "ADMIN")
void postFilterTest01() {
List all = helloService.getAll();
assertNotNull(all);
assertEquals(5, all.size());
assertEquals(2,all.get(1).getId());
}

2.5 @Secured

@Secured 注解也是 Spring Security 提供的權(quán)限注解,不同于前面四個(gè)注解,該注解不支持權(quán)限表達(dá)式,只能做一些簡單的權(quán)限描述。

@Secured({"ROLE_ADMIN","ROLE_USER"})
public User getUserByUsername(String username) {
return new User(99, username);
}

這段代碼表示用戶需要具備 ROLE_ADMIN 或者 ROLE_USER 角色,才能訪問 getUserByUsername 方法。

然后我們通過單元測試對其進(jìn)行測試,代碼如下:

@Test
@WithMockUser(roles = "ADMIN")
void securedTest01() {
User user = helloService.getUserByUsername("javaboy");
assertNotNull(user);
assertEquals(99,user.getId());
assertEquals("javaboy", user.getUsername());
}

注意,這里不需要給角色添加 ROLE_ 前綴,系統(tǒng)會自動添加。

2.6 @DenyAll

@DenyAll 是 JSR-250 提供的方法注解,看名字就知道這是拒絕所有訪問:

@DenyAll
public String denyAll() {
return "DenyAll";
}

然后我們通過單元測試對其進(jìn)行測試,代碼如下:

@Test
@WithMockUser(username = "javaboy")
void denyAllTest01() {
helloService.denyAll();
}

在單元測試過程中,就會拋出異常。

2.7 @PermitAll

@PermitAll 也是 JSR-250 提供的方法注解,看名字就知道這是允許所有訪問:

@PermitAll
public String permitAll() {
return "PermitAll";
}

然后我們通過單元測試對其進(jìn)行測試,代碼如下:

@Test
@WithMockUser(username = "javaboy")
void permitAllTest01() {
String s = helloService.permitAll();
assertNotNull(s);
assertEquals("PermitAll", s);
}

2.8 @RolesAllowed

@RolesAllowed 也是 JSR-250 提供的注解,可以添加在方法上或者類上,當(dāng)添加在類上時(shí),表示該注解對類中的所有方法生效;如果類上和方法上都有該注解,并且起沖突,則以方法上的注解為準(zhǔn)。我們來看一個(gè)簡單的案例:

@RolesAllowed({"ADMIN","USER"})
public String rolesAllowed() {
return "RolesAllowed";
}

這個(gè)表示訪問 rolesAllowed 方法需要具備 ADMIN 或者 USER 角色,然后我們通過單元測試對其進(jìn)行測試,代碼如下:

@Test
@WithMockUser(roles = "ADMIN")
void rolesAllowedTest01() {
String s = helloService.rolesAllowed();
assertNotNull(s);
assertEquals("RolesAllowed", s);
}

這就是常見的方法權(quán)限注解。


新聞名稱:想要控制好權(quán)限,這八個(gè)注解你必須知道!
文章URL:http://www.dlmjj.cn/article/dpoggpc.html