一、权限控制系统
权限控制系统即用户登录后,如果操作了不能访问的操作,系统将其拦截。
权限控制系统设计需求:
- 系统功能并不是所有功能都需要被控制,例如登录功能无需校验
设计方案:资源中没有出现的功能将不被过滤 - 系统功能中具有访问控制权限的一定出现在资源定义数据中。
- 用户每次访问某个功能时,必须先进行校验,使用拦截器或AOP完成此功能。
1.自定义权限校验拦截器AuthInterceptor
public class AuthInterceptor extends AbstractInterceptor
2.获取当前被拦截的操作信息
String actionName = invocation.getProxy().getAction().getClass().getName();String methodName = invocation.getProxy().getMethod();String allName = actionName + "." + methodName;
3.启动服务器,测试是否拦截到操作信息
4.获取所有的资源信息
首先注入ResourceEbi,使用struts2的自动装配模式
private ResEbi resEbi;//struts会自动的装配 public void setResEbi(ResEbi resEbi) { this.resEbi = resEbi; }
获取所有资源信息
检测调用资源是否存在于全资源列表中
//由直接在拦截器里面进行资源查询的时候,每次都需要查询,这样会使得程序的效率很低,//因此在这里使用监听器,在程序加载的时候就加载好,这样后面就不会再进行查询String allRes = ServletActionContext.getServletContext().getAttribute("allRes").toString();if(!allRes.contains(allName)){ return invocation.invoke();}
5.根据用户登陆数据,获取登录人所具有的资源数据,其中关联关系靠角色维护,即员工->角色->资源
获取登陆用户的所有资源
注:session中的登陆用户数据中如果未对关联数据进行初始化无法直接获取
//在登录成功的时候,查询该用户的所有权限List resList = resEbi.getResByEm(loginEm.getUuid());StringBuilder sbf = new StringBuilder();for (ResModel rm : resList) { sbf.append(rm.getText()); sbf.append(",");}
全部代码
public class AuthInterceptor extends AbstractInterceptor{ private ResEbi resEbi;//struts会自动的装配 public void setResEbi(ResEbi resEbi) { this.resEbi = resEbi; } public String intercept(ActionInvocation invocation) throws Exception { String actionName = invocation.getProxy().getAction().getClass().getName(); String methodName = invocation.getProxy().getMethod(); String allName = actionName + "." + methodName; System.out.println(allName); //由直接在拦截器里面进行资源查询的时候,每次都需要查询,这样会使得程序的效率很低, //因此在这里使用监听器,在程序加载的时候就加载好,这样后面就不会再进行查询 String allRes = ServletActionContext.getServletContext().getAttribute("allRes").toString(); if(!allRes.contains(allName)){ return invocation.invoke(); } EmpModel em = (EmpModel) ActionContext.getContext().getSession().get(EmpModel.EMP_LOGIN_USER_OBJECT_NAME);// System.out.println("-----==-----");// System.out.println(em.getResAll());// System.out.println("-----==-----"); //在登录的时候将用户的权限查询出来提高程序的效率 if(em.getResAll().contains(allName)){ return invocation.invoke(); } throw new AppException("对不起你没有访问权限!"); }}
二、全资源获取优化
系统中每个用户的每个操作均需要依赖拦截器进行校验,其中的功能如果性能过低将使整体系统性能下降。对其中的数据获取进行优化。
由于权限校验时,每次需要判定调用资源是否存在于所有资源列表中,以此判定当前操作是否需要权限拦截,所以需要将该数据的获取进行优化。
将此类数据的共享范围扩大至应用程序范围,将该数据获取后,放置在ServletContext范围内。
1.开发Web监听器
public class AllResLoadListener implements ServletContextListener
2.监听器初始化时,获取全资源信息,并将其加载到ServletContext范围内。为后期判定方便,将数据初始化为字符串信息,方便查询,减少集合迭代次数。
public void contextInitialized(ServletContextEvent event) { ServletContext sc = event.getServletContext(); WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(sc); ResEbi resEbi = (ResEbi) ctx.getBean("resEbi"); List resList = resEbi.getAll(); StringBuilder sbf = new StringBuilder(); for(ResModel temp :resList){ sbf.append(temp.getText()); sbf.append(","); } //放入sc中 sc.setAttribute("allRes", sbf.toString()); }
3.配置Web监听器
4.在权限拦截器中获取资源,断开原始获取资源方式
String allRes = ServletActionContext.getServletContext().getAttribute("allRes").toString();if(!allRes.contains(allName)){ return invocation.invoke();}
三、总结
这里主要是通过java监听器来实现权限的控制和对资源的启动的优化。
如果想获取更多源码或者视频教程,欢迎关注我的微信公众号
好好学java
,在公众号里,回复:java基础、html5、javaEE基础、struts2、spring、redis、luncene、oracle
等,将可获得以上的优质视频教程及源码。