該文章將記錄本人在專案中遇到的一個小問題和解決方案。
專案中使用Spring Security做認證和授權,許可權只在前端做了按鈕控制,若沒有許可權的使用者直接通過URL也能存取,該文章主要記錄通過註解方式控制後端URL存取許可權。
許可權控制標配的五張表(關聯關係如下圖所示):
使用者表、角色表、選單表、使用者與角色關聯表、角色與選單關聯表
@Target({ElementType.TYPE, ElementType.METHOD}) // 註解的引數可以根據自己的需要設定
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestPermissions {
String value() default "";
}
private RequestPermissions getAnnotationLog(JoinPoint joinPoint) {
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if (null != method) {
// 返回自定義的註解
return method.getAnnotation(RequestPermissions.class);
}
return null;
}
@Aspect // 標記為一個切面,讓容器讀取
@Component
public class RequestPermissionsAspect {
// @annotation的值為自定義註解類全限定名
@Pointcut("@annotation(com.dome.test.RequestPermissions)")
public void permissionsPointCut() {}
@Before("permissionsPointCut()")
public void doBefore(JoinPoint joinPoint) {
this.handleRequestPermissions(joinPoint);
}
private void handleRequestPermissions(final JoinPoint joinPoint) {
// 獲取註解
RequestPermissions request= this.getAnnotationLog(joinPoint);
// 獲取註解值(許可權名)
String value = requestPermissions.value(); // value="home:menu:list"
// 此處可通過Shiro或者Spring Security獲取使用者擁有的許可權(許可權標識)
List<String> userRoleList = getUserRoleList();
// 許可權業務邏輯處理
TODO
// 許可權業務邏輯處理,例如:判斷使用者擁有的許可權裡是否包含註解value許可權標識
if(!userRoelList.contains(value)){
throw new AnnotationException("您沒有存取許可權,請聯絡管理員新增");
}
}
}
@RequestPermissions("home:menu:list")
@ApiOperation("選單列表")
@GetMapping("/menu/list")
public ResultVO findMenuList(String name) {
return ResultVO.ofSuccess(menuService.findMenuList(name));
}
到這一步後端URL許可權控制的程式碼就完成了,許可權控制有很多種方式,Shiro和Spring Security也有動態許可權控制,由於專案迭代,為了不影響專案原有業務,本人採用了靈活註解的方式控制。
最後,第一次分享技術文章的程式媛,文章如有不合之處歡迎指出,與大家共同進步。