前言
CMS随着功能的增加,不同角色用户的介入,需要建立一套合理的用户权限体系,实现功能权限的统一授权,提高信息系统的安全性和可控性。
数据库设计
相关对象及其关系:用户
、角色
、菜单
、权限
- 用户~角色:多对多
- 用户~权限:多对多
- 角色~权限:多对多
- 权限~菜单:多对一
获取数据
- 用户角色:默认角色列表、该用户所授权的角色列表
- 用户权限:默认角色对应的权限列表、该用户所授权的角色列表、该用户直接授权的权限列表
- 用户菜单:该用户的权限列表对应的菜单集
- 角色权限:该角色所授权的权限列表
- 角色菜单:该角色的权限列表对应的菜单集
拦截器过滤请求
流程图
代码
/**
* 校验指定用户是否有权限访问该请求路径
* @Title: verifyPermission
* @Desc: 校验指定用户是否有权限访问该请求路径
* @param userID 用户ID
* @param request 当前请求
* @param handlerMethod
* @return true-有权限 false-无权限
*/
private boolean verifyPermission(long userID, HttpServletRequest request, HandlerMethod handlerMethod) {
// 是否需要校验权限
boolean isRequire = true;
// 当前请求的路径
String servletPath = request.getServletPath();
// 获取类(或方法)注解RequirePermission
Class<?> clazz = handlerMethod.getBeanType();
Method method = handlerMethod.getMethod();
boolean isClzAnnotation = clazz.isAnnotationPresent(RequirePermission.class);
boolean isMethondAnnotation = method.isAnnotationPresent(RequirePermission.class);
// 如果方法和类声明中同时存在这个注解,那么方法中的会覆盖类中的设定。
if(isMethondAnnotation) {
isRequire = method.getAnnotation(RequirePermission.class).require();
}else if(isClzAnnotation) {
isRequire = clazz.getAnnotation(RequirePermission.class).require();
}
if(!isRequire) {
return true;
}
// 获取用户所有的权限串
Set<String> permissionStrSet = permissionFacade.listPermissionStrByUserID(userID);
if(CollectionUtils.isEmpty(permissionStrSet)) {
return false;
}
for (String permissionStr : permissionStrSet) {
if(StringUtils.endsWith(servletPath, permissionStr)) {
return true;
}
}
return false;
}