1.概念
- 个人理解,权限就是做到对不同用户进行访问限制,前提是保证在权限需求设计范围内不会出现非法也能访问到不该访问到的东西.因此按数据表设计将权限分为:部门,用户,角色,角色权限中间表,权限.(个人觉得一般项目可以考虑部门和角色合为一个),这里用一个具体访问的url地址代表一个权限(也可以使用别的方式).下面用一个例子通过来分析.
2.场景
- 一个超级管理员admin
- 可以访问并且操作网站所有功能
- 经理manager
- 比超级管理员权限少一点
- 销售员soler和采购员buy
- 只能使用部分功能,比经理权限少
- 普通用户customer
- 能使用的功能更少
针对以上来做各种变通分析权限控制的需求
3.需求
表设计:
- 用户表t_user
- 角色表t_role(有父子关系)
- 权限表t_auth(有父子关系)
- 角色和权限中间表t_role_auth
使用技术
- 拦截器来处理
- shiro框架处理
表的使用
- 不管是什么身份的用户,都是通过角色来分配权限,也就是用户选择了角色就相当于选中了应有的权限,禁止用户对t_auth表直接关联
- 权限表中是一条信息对应一个访问地址,并设置上下级关系
对不同用户分配角色
- 超级管理员:
- 这是一个特例,一个项目就一个,可以通过代码来控制,不过为了便于维护,在角色表添加一个叫admin的角色,然后在这个角色下面添加所有的访问地址
- 经理:
- 在角色表里面创建一个叫manager的经理角色,再对这个角色添加对应权限
- 销售员soler和采购员buy
- 在角色表里面分别创建一个soler和buy角色,并对两个角色添加对应权限
- 普通用户customer
- 在角色表中创建一个customer角色,并添加对应权限
相关问题
要是一个销售员除了有soler角色外还有一些其他权限怎么办呢?比如销售员还有部分采购员一部分权限
这种情况可以采用量两种方式解决这个问题:
创建一个新角色(比如soler2)来包含原本soler角色里面的所有权限和新拥有的权限
创建一个新角色,仅包含新拥有权限即可,然后设置该新角色的父级为soler角色,形成从属关系
还有没有其他特殊情况没考虑进来的吗?
- 个人觉得在一个超级管理员情况下,在上面设计里面变通几乎能满足所有常规的中小型项目的权限设计方案.
4.相关技术实现(在spring+springMVC框架下maven项目)
使用拦截器实现
在spring配置文件中添加拦截器配置
<!-- 配置登录拦截器 --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean id="li" class="cn.util.LoginIntercepter" ></bean> </mvc:interceptor> </mvc:interceptors>
2.拦截器处理权限类
- 继承HandlerInterceptorAdapter类
- HandlerInterceptorAdapter类的preHandle()在执行controller对应访问方法前执行,也就是在这个方法里面做权限判断,返回false后权限验证失败,返回true的话进入controller对应的访问方法
- HandlerInterceptorAdapter类的postHandle()在controller对应访问方法后执行
public class LoginIntercepter extends HandlerInterceptorAdapter { private static String [] urls = { "uc/checklogin"}; public static boolean checkUrl(String requestname){ //筛选静态资源 if(requestname==null||requestname.equals("")){ return true; } if(requestname.endsWith(".js")||requestname.endsWith(".css")||requestname.endsWith(".jpg")){ return true; } for (int i = 0; i < urls.length; i++) { if(urls[i].equals(requestname)){ return true; } } return false; } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //1.登录拦截 //2.权限验证,验证当前用户是否拥有当前请求这个权限 HttpSession session = request.getSession(); //获取当前请求的名字 String uri = re