Java-Security(七):Spring Security方法註解認證啓用

@EnableGlobalMethodSecurity標記啓用方法認證註解類型包含以下3種:

  • prePostEnabled 確定 前置註解[@PreAuthorize,@PostAuthorize,..] 是否啓用
  • securedEnabled 確定安全註解 [@Secured] 是否啓用
  • jsr250Enabled 確定 JSR-250註解 [@RolesAllowed..]是否啓用

方法註解類型一把通過@EnableGlobalMethodSecurity(prePostEnabled = true)設置,一般在MySecurityConfig類上添加@EnableGlobalMethodSecurity(prePostEnabled = true)註解並通過參數指定啓用哪些方法認證註解。

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
}

支持啓用多個註解

一個程序啓用多個類型註解:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true))
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    ...
}

但是隻應該設置一個註解對於行爲類的接口或者類

public interface UserService {
  List<User> findAllUsers();

  @PreAuthorize("hasAnyRole('user')")
  void updateUser(User user);

    // 下面不能設置兩個註解,如果設置兩個,只有其中一個生效
    // @PreAuthorize("hasAnyRole('user')")
  @Secured({ "ROLE_user", "ROLE_admin" })
  void deleteUser();
}

prePostEnabled

先啓用prePostEnabled

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    ...
}

@PreAuthorize 進入方法之前驗證授權。可以將登錄用戶的roles參數傳到方法中驗證。

// 只能user角色可以訪問
@PreAuthorize ("hasAnyRole('user')")
// user 角色或者 admin 角色都可訪問
@PreAuthorize ("hasAnyRole('user') or hasAnyRole('admin')")
// 同時擁有 user 和 admin 角色才能訪問
@PreAuthorize ("hasAnyRole('user') and hasAnyRole('admin')")
// 限制只能查詢 id 小於 10 的用戶
@PreAuthorize("#id < 10")
User findById(int id);

// 只能查詢自己的信息
 @PreAuthorize("principal.username.equals(#username)")
User find(String username);

// 限制只能新增用戶名稱爲abc的用戶
@PreAuthorize("#user.name.equals('abc')")
void add(User user)

@PostAuthorize 該註解使用不多,在方法執行後再進行權限驗證。 適合驗證帶有返回值的權限。Spring EL 提供 返回對象能夠在表達式語言中獲取返回的對象returnObject。如:

// 查詢到用戶信息後,再驗證用戶名是否和登錄用戶名一致
@PostAuthorize("returnObject.name == authentication.name")
@GetMapping("/get-user")
public User getUser(String name){
    return userService.getUser(name);
}
// 驗證返回的數是否是偶數
@PostAuthorize("returnObject % 2 == 0")
public Integer test(){
    // ...
    return id;
}

@PreFilter 對集合類型的參數執行過濾,移除結果爲false的元素

// 指定過濾的參數,過濾偶數
@PreFilter(filterTarget="ids", value="filterObject%2==0")
public void delete(List<Integer> ids, List<String> username)

@PostFilter 對集合類型的返回值進行過濾,移除結果爲false的元素

@PostFilter("filterObject.id%2==0")
public List<User> findAll(){
    ...
    return userList;
}

securedEnabled

先啓用securedEnabled

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true))
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    ...
}

在調用的接口或方法使用如下:

public interface UserService {
    List<User> findAllUsers();
    
    @Secured({"ROLE_user"})
    void updateUser(User user);

    @Secured({"ROLE_admin", "ROLE_user1"})
    void deleteUser();
}

@Secured註解是用來定義業務方法的安全配置。在需要安全[角色/權限等]的方法上指定 @Secured,並且只有那些角色/權限的用戶纔可以調用該方法。

@Secured缺點(限制)就是不支持Spring EL表達式。不夠靈活。並且指定的角色必須以ROLE_開頭,不可省略。

在上面的例子中,updateUser 方法只能被擁有user權限的用戶調用。deleteUser 方法只能夠被擁有admin 或者user1 權限的用戶調用。而如果想要指定"AND"條件,即調用deleteUser方法需同時擁有ADMINDBA角色的用戶,@Secured便不能實現。

這時就需要使用prePostEnabled提供的註解@PreAuthorize/@PostAuthorize

啓用jsr250Enabled

jsr250Enabled註解比較簡單,只有

  • @DenyAll 拒絕所有訪問

  • @RolesAllowed({"USER", "ADMIN"}) 該方法只要具有"USER", "ADMIN"任意一種權限就可以訪問。這裏可以省略前綴ROLE_,實際的權限可能是ROLE_ADMIN

  • @PermitAll 允許所有訪問

 

 

 

參考《https://www.jianshu.com/p/77b4835b6e8e

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章