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