SpringBoot使用攔截器Interceptor實現(xiàn)統(tǒng)一角色權(quán)限校驗
一、定義注解annotation
通用功能定義在tg-book-common中
我們最終實現(xiàn)的效果是:加了@Role注解以后,這個接口只有管理員才能訪問,學(xué)生訪問接口就會報錯:無權(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來獲?。?/p>
HandlerMethod handlerMethod = (HandlerMethod) handler;
Role role = handlerMethod.getMethod().getAnnotation(Role.class);
if (role != null) {
// 走到這,說明方法上加了@Role
}3. 角色如何讀取?
前2步以后,我們就拿到了當(dāng)前登錄的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;
}
}三、應(yīng)用:給管理員操作接口加注解
在實現(xiàn)了通用校驗邏輯以后,接下來就是如何應(yīng)用了!
其實就是:加@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

