亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

Spring實現擁有者權限驗證的方法示例

2024-07-14 08:43:53
字體:
來源:轉載
供稿:網友

問題描述

在做權限驗證的時候,我們經常會遇到這樣的情況:教師擁有多個學生,但是在處理學生信息的時候,教師只能操作自己班級的學生。所以,我們要做的就是,當教師嘗試處理別的班的學生的時候,拋出異常。

實體關系

用戶1:1教師,教師m:n班級,班級1:n學生

Spring,擁有者,權限驗證

實現思路

findById為例。因為從整體上看,用戶學生m:n的關系,所以在調用這個接口的時候,獲取該學生的所有用戶,然后跟當前登錄用戶進行對比,如果不在其中,拋出異常。

利用切面,我們可以在findById、update、delete方法上進行驗證。

注解

我們會在方法上添加注解,以表示對該方法進行權限驗證。

@Target(ElementType.METHOD)     // 注解使用在方法上@Retention(RetentionPolicy.RUNTIME) // 運行時生效public @interface AuthorityAnnotation {  /**   * 倉庫名   */  @Required  Class repository();}

因為我們需要獲取出學生,但是并不限于學生,所以就要將倉庫repository作為一個參數傳入。

實體

上面我們說過,需要獲取學生中的用戶,所以我們可以在實體中定義一個方法,獲取所有有權限的用戶:getBelongUsers()

但是,我們知道,學生和用戶沒用直接的關系,而且為了復用,在對其他實體進行驗證的時候也能使用,可以考慮創建一個接口,讓需要驗證的實體去實現他。

Spring,擁有者,權限驗證

這樣,我們可以在讓每個實體都集成這個接口,然后形成鏈式調用,這樣就解決了上面你的兩個問題。

public interface BaseEntity {  List<User> getBelongToUsers();}

教師:

@Entitypublic class Teacher implements YunzhiEntity, BaseEntity {  ...  @Override  public List<User> getBelongToUsers() {    List<User> userList = new ArrayList<>();    userList.add(this.getUser());    return userList;  }}

班級:

@Entitypublic class Klass implements BaseEntity {  ...  @Override  public List<User> getBelongToUsers() {    List<User> userList = new ArrayList<>();    for (Teacher teacher: this.getTeacherList()) {      userList.addAll(teacher.getBelongToUsers());    }    return userList;  }}

學生:

@Entitypublic class Student implements BaseEntity {  ...  @Override  public List<User> getBelongToUsers() {    return this.getKlass().getBelongToUsers();  }}

切面

有了實體后,我們就可以建立切面實現驗證功能了。

@Aspect@Componentpublic class OwnerAuthorityAspect {  private static final Logger logger = LoggerFactory.getLogger(OwnerAuthorityAspect.class.getName());  /**   * 使用注解,并第一個參數為id   */  @Pointcut("@annotation(com.yunzhiclub.alice.annotation.AuthorityAnnotation) && args(id,..) && @annotation(authorityAnnotation)")  public void doAccessCheck(Long id, AuthorityAnnotation authorityAnnotation) {   }    @Before("doAccessCheck(id, authorityAnnotation)")  public void before(Long id, AuthorityAnnotation authorityAnnotation) {  }

首先,我們要獲取到待操作對象。但是在獲取對象之前,我們必須獲取到repository。

這里我們利用applicationContext來獲取倉庫bean,然后再利用獲取到的bean,生成repository對象。

@Aspect@Componentpublic class OwnerAuthorityAspect implements ApplicationContextAware {  private ApplicationContext applicationContext = null;  // 初始化上下文  ......  @Before("doAccessCheck(id, authorityAnnotation)")  public void before(Long id, AuthorityAnnotation authorityAnnotation) {    logger.debug("獲取注解上的repository, 并通過applicationContext來獲取bean");    Class<?> repositoryClass = authorityAnnotation.repository();    Object object = applicationContext.getBean(repositoryClass);    logger.debug("將Bean轉換為CrudRepository");    CrudRepository<BaseEntity, Object> crudRepository = (CrudRepository<BaseEntity, Object>)object;  }  @Override  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {    this.applicationContext = applicationContext;  }}

該類實現了ApplicationContextAware接口,通過setApplicationContext函數獲取到了applicationContext。

接下來,就是利用repository獲取對象,然后獲取他的所屬用戶,再與當前登錄用戶進行比較。

@Before("doAccessCheck(id, authorityAnnotation)")public void before(Long id, AuthorityAnnotation authorityAnnotation) {  logger.debug("獲取注解上的repository, 并通過applicationContext來獲取bean");  Class<?> repositoryClass = authorityAnnotation.repository();  Object object = applicationContext.getBean(repositoryClass);  logger.debug("將Bean轉換為CrudRepository");  CrudRepository<BaseEntity, Object> crudRepository = (CrudRepository<BaseEntity, Object>)object;  logger.debug("獲取實體對象");  Optional<BaseEntity> baseEntityOptional = crudRepository.findById(id);  if(!baseEntityOptional.isPresent()) {    throw new RuntimeException("對不起,未找到相關的記錄");  }  BaseEntity baseEntity = baseEntityOptional.get();  logger.debug("獲取登錄用戶以及擁有者,并進行比對");  List<User> belongToTUsers = baseEntity.getBelongToUsers();  User currentLoginUser = userService.getCurrentLoginUser();  Boolean havePermission = false;  if (currentLoginUser != null && belongToTUsers.size() != 0) {    for (User user: belongToTUsers) {      if (user.getId().equals(currentLoginUser.getId())) {        havePermission = true;        break;      }  }    if (!havePermission) {      throw new RuntimeException("權限不允許");    }  }}

使用

在控制器的方法上使用注解:@AuthorityAnnotation,傳入repository。

@RestController@RequestMapping("/student")public class StudentController {  private final StudentService studentService;  // 學生  @Autowired  public StudentController(StudentService studentService) {    this.studentService = studentService;  }  /**   * 通過id獲取學生   *   * @param id   * @return   */  @AuthorityAnnotation(repository = StudentRepository.class)  @GetMapping("/{id}")  @JsonView(StudentJsonView.get.class)  public Student findById(@PathVariable Long id) {    return studentService.findById(id);  }}

出現的問題

實現之后,進行單元測試的過程中出現了問題。

@Testpublic void update() throws Exception {  logger.info("獲取一個保存學生");  Student student = studentService.getOneSaveStudent();  Long id = student.getId();  logger.info("獲取一個更新學生");  Student newStudent = studentService.getOneUnSaveStudent();  String jsonString = JSONObject.toJSONString(newStudent);  logger.info("發送更新請求");  this.mockMvc    .perform(put(baseUrl + "/" + id)      .cookie(this.cookie)      .content(jsonString)      .contentType(MediaType.APPLICATION_JSON_UTF8))    .andExpect(status().isOk());}

Spring,擁有者,權限驗證

400的錯誤,說明參數錯誤,參數傳的是實體,看下傳了什么:

Spring,擁有者,權限驗證

我們看到,這個字段并不是我們實體中的字段,但是為什么序列化的時候出現了這個字段呢?

原因是這樣的,我們在實體中定義了一個getBelongToUsers函數,然后JSONobject在進行序列化的時候會根據實體中的getter方法,獲取get后面的為key,也就是將belongToUsers看做了字段。

所以就出現了上面傳實體字段多出的情況,從而引發了400的錯誤。

解決

我們不想JSONobject在序列化的時候處理getBelongToUsers,就需要聲明一下,這里用到了注解:@JsonIgnore。這樣在序列化的時候就會忽略它。

@Entitypublic class Student implements BaseEntity {  ......  @JsonIgnore  @Override  public List<User> getBelongToUsers() {    return this.getKlass().getBelongToUsers();  }}

修改后的學生實體如上,其他實現了getBelongToUsers方法的,都需要做相同處理。

總結

 以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩在线观看高清| 欧美人成在线视频| 97视频在线观看免费| 久久久精品免费视频| 国产一区二区久久精品| 亚洲欧美变态国产另类| 91久久嫩草影院一区二区| 亚洲国产精品美女| 亚洲欧美在线一区二区| 97超碰蝌蚪网人人做人人爽| 久久综合免费视频| 国产91热爆ts人妖在线| 九色精品美女在线| 久久久久久国产免费| 欧美国产日韩精品| 成人国产精品一区二区| 国产精品18久久久久久麻辣| 亚洲国产精品成人va在线观看| 中文字幕久久精品| 国产精品一区二区女厕厕| 成人午夜黄色影院| 超碰97人人做人人爱少妇| 国产热re99久久6国产精品| 日韩电影中文字幕一区| 一色桃子一区二区| 国产精品一区二区三区在线播放| 国产日韩在线看片| 久久精品视频中文字幕| 欧美日本亚洲视频| 97人人模人人爽人人喊中文字| 国内精品一区二区三区| 伊人久久大香线蕉av一区二区| 国产精品午夜国产小视频| 91久久国产婷婷一区二区| 成人亚洲欧美一区二区三区| 日韩中文字幕在线| 中文字幕亚洲激情| 不卡av在线播放| 欧美孕妇性xx| 成人久久久久久| 45www国产精品网站| 国产精品久在线观看| 欧美大片免费看| 久久久久久国产精品久久| 日韩欧美精品网站| 午夜免费在线观看精品视频| 色偷偷av一区二区三区| 国产日产久久高清欧美一区| 日韩精品极品视频| 最新91在线视频| 亚洲福利小视频| 亚洲一区二区三区乱码aⅴ蜜桃女| 国产精品免费视频xxxx| 亚洲免费视频一区二区| 欧美精品一区三区| 国产精品高潮在线| 久久香蕉频线观| 亚洲开心激情网| 久操成人在线视频| 亚洲国产精品热久久| 在线观看精品自拍私拍| 日本精品一区二区三区在线播放视频| 一本色道久久88综合亚洲精品ⅰ| 亚洲精品国产suv| 国产日韩欧美在线| 国产欧美欧洲在线观看| 中文字幕日韩av综合精品| 国产+成+人+亚洲欧洲| 国产精品免费一区| 精品无人国产偷自产在线| 日本亚洲欧美三级| 日韩精品高清视频| 国内精品一区二区三区| 国产91精品高潮白浆喷水| 欧美日韩国产中文精品字幕自在自线| 欧美极度另类性三渗透| 国产一区二区三区高清在线观看| 欧美日韩电影在线观看| 法国裸体一区二区| 国产一区深夜福利| 久久久亚洲国产| 欧美日韩国产一区二区三区| 日韩av快播网址| 欧美床上激情在线观看| 精品福利一区二区| 欧美在线一级va免费观看| 欧美激情一二三| 亚洲日本aⅴ片在线观看香蕉| 欧美一级电影免费在线观看| 欧美黑人一级爽快片淫片高清| 日韩视频在线免费| 国产精品黄色av| 色综合久久88色综合天天看泰| 亚洲欧美日韩久久久久久| 国产精品日韩久久久久| 欧美日本黄视频| 91av在线网站| 欧美激情va永久在线播放| 成人免费激情视频| 日本高清视频一区| 国产精品免费视频久久久| 亚洲精选一区二区| 亚洲性av在线| 黄色一区二区在线观看| 日韩中文字幕第一页| 国产女精品视频网站免费| 日韩成人av网址| 国语自产偷拍精品视频偷| 亚洲free性xxxx护士hd| 欧美一级淫片videoshd| 欧美大秀在线观看| 性色av香蕉一区二区| 欧美做爰性生交视频| 91久久在线播放| 日韩美女写真福利在线观看| 国产精品日日摸夜夜添夜夜av| 国产精品wwww| 国产精品久久久久久久久男| 成人网中文字幕| 亚洲精品网站在线播放gif| 久久99国产精品久久久久久久久| www.午夜精品| 欧美精品一区在线播放| 亚洲国模精品一区| 国产婷婷97碰碰久久人人蜜臀| 国产精品video| 亚洲直播在线一区| 91亚洲精品在线观看| 疯狂做受xxxx高潮欧美日本| 中文字幕亚洲综合久久| 国产亚洲视频在线观看| 国产精品久久久久久久av大片| 国模视频一区二区三区| 欧美视频一区二区三区…| 久久艳片www.17c.com| 538国产精品视频一区二区| 国产欧美一区二区白浆黑人| 亚洲色图五月天| 国产精品成人av性教育| 亚洲欧洲日本专区| 九九九久久国产免费| 亚洲欧美日韩爽爽影院| 国产亚洲精品久久久优势| 国产美女精品视频| 久久天堂av综合合色| 伊人久久五月天| 欧美高清电影在线看| 亚洲天堂av在线免费观看| 欧美色欧美亚洲高清在线视频| 久久人人爽人人爽人人片av高清| 久久久精品视频成人| 欧美在线xxx| 亚洲经典中文字幕| 亚洲天堂av在线免费观看| 91亚洲国产成人久久精品网站| 久久久久久亚洲精品不卡| 亚洲第一精品夜夜躁人人爽| 91人人爽人人爽人人精88v| 国产精品女视频| www.99久久热国产日韩欧美.com| 欧美成人精品三级在线观看| 精品偷拍各种wc美女嘘嘘| 欧美成人性色生活仑片| 在线亚洲国产精品网|