SpringBoot使用攔截器Interceptor實(shí)現(xiàn)統(tǒng)一角色權(quán)限校驗(yàn)
一、定義注解annotation
通用功能定義在tg-book-common中
我們最終實(shí)現(xiàn)的效果是:加了@Role注解以后,這個(gè)接口只有管理員才能訪問,學(xué)生訪問接口就會報(bào)錯(cuò):無權(quán)限!
下面定義一個(gè)角色注解
,通過@Target 指定作用于方法
上。
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface Role { /** * 角色id數(shù)組,默認(rèn)1-管理員 **/ int[] roleIds() default { 1 }; }
定義roleIds,是保留擴(kuò)展性。若后面擴(kuò)展出【校長】等其它角色,我們可以通過int數(shù)組來任意組合角色,只要擁有int數(shù)組中的任意角色id即可訪問該接口。
二、攔截角色注解
1. 在攔截器哪里攔截?
顯然,首先需要【用戶身份認(rèn)證】通過,然后再校驗(yàn)角色!即在AuthInterceptor的preHandle的保存至授權(quán)上下文之前:AuthContextInfo.setAuthInfo(authInfo);
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 。。。省略一大堆用戶身份認(rèn)證代碼。。。 // TODO 校驗(yàn)角色:寫在這! // 校驗(yàn)成功, 保存至認(rèn)證上下文 AuthContextInfo.setAuthInfo(authInfo); return true; }
2. 如何攔截角色注解?
可以通過將handler轉(zhuǎn)成HandlerMethod以后,通過getAnnotation來獲??!
HandlerMethod handlerMethod = (HandlerMethod) handler; Role role = handlerMethod.getMethod().getAnnotation(Role.class); if (role != null) { // 走到這,說明方法上加了@Role }
3. 角色如何讀取?
前2步以后,我們就拿到了當(dāng)前登錄的userId,也拿到了接口要求的roleIds數(shù)組,所以至少有兩種方案:
- 可以通過userId去查一次MySQL,然后判斷一下角色,這種我就不實(shí)現(xiàn)了,你可以自己去查詢實(shí)現(xiàn)!
將roleId保存在token中!
,本文實(shí)現(xiàn)的是另一種方案,是為了擴(kuò)展一下大家的思路,也就是不走M(jìn)ySQL查詢的方案。
AuthContextInfo類中增加字段來承載角色:
private Integer roleId;
loginByPassword中將role設(shè)置到authContextInfo.roleId
authContextInfo.setRoleId(user.getRole());
接著在JwtTokenProvider中定義payload的自定義字段r:
// payload的自定義字段r private static final String CLAIM_ROLE = "r";
在JwtTokenProvider.create中將它保存到token的payload中:
// 自定義 role .withClaim(CLAIM_ROLE, authContextInfo.getRoleId())
在JwtTokenProvider.verify中將它從token中解析出來:
4. 最后做角色校驗(yàn)
拿到了authInfo.getRoleId(),還知道了接口方法要求的roleIds,判斷邏輯太簡單了吧~ 我簡單寫了一下,如下:
// 校驗(yàn)角色 HandlerMethod handlerMethod = (HandlerMethod) handler; Role role = handlerMethod.getMethod().getAnnotation(Role.class); if (role != null) { // 走到這,說明方法上加了@Role boolean isAdmin = false; for (int roleId : role.roleIds()) { if (authInfo.getRoleId().equals(roleId)) { isAdmin = true; break; } } if (!isAdmin) { log.info("[403]無權(quán)限, token={}", token); response.setStatus(HttpServletResponse.SC_FORBIDDEN); // 別忘了返回false return false; } }
三、應(yīng)用:給管理員操作接口加注解
在實(shí)現(xiàn)了通用校驗(yàn)邏輯以后,接下來就是如何應(yīng)用了!
其實(shí)就是:加@Role注解
下面對管理員錄入和修改圖書接口加了注解,其它接口同理~~
四、PostMan測試
使用role=0的賬號調(diào)用管理員API,返回403!
使用管理員賬號則會正常執(zhí)行!就不做截圖了!另外,別忘了提交Git!
以上就是SpringBoot使用攔截器Interceptor實(shí)現(xiàn)統(tǒng)一角色權(quán)限校驗(yàn)的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot Interceptor統(tǒng)一角色權(quán)限校驗(yàn)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java 使用json-lib處理JSON詳解及實(shí)例代碼
這篇文章主要介紹了Java 使用json-lib處理JSON詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-02-02logback的ShutdownHook關(guān)閉原理解析
這篇文章主要為大家介紹了logback的ShutdownHook關(guān)閉原理源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11細(xì)數(shù)Java接口的概念、分類及與抽象類的區(qū)別
下面小編就為大家?guī)硪黄?xì)數(shù)Java接口的概念、分類及與抽象類的區(qū)別。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-11-11