细颗粒度权限控制

细颗粒度权限控制我们采用拦截器完成

具体实现:

第一步:定义一个类 继承MethodFilterInterceptor类

第二步:覆盖doIntercept方法

第三步:通过ActionInvocation 对象获取reques、actiont对象 进而获取方法名

第四步:通过action对象和反射获取方法的反射对象

第五步:获取session中的角色用户信息以及方法上的权限(注解)来校验该用户是否有操作该方法的权限

第六步:在struts.xml中配置

代码实现:

protected String doIntercept(ActionInvocation actioninvocation) throws Exception {
// TODO Auto-generated method stub
//把自定义错误信息  放置到request中
HttpServletRequest request=(HttpServletRequest) actioninvocation.getInvocationContext().get(StrutsStatics.HTTP_REQUEST);
try{

//获取请求的action对象
Object action=actioninvocation.getAction();
//获取请求方法的名称
String methodName=actioninvocation.getProxy().getMethod();
//获取action中的方法的封装类(action中的方法没有参数)
Method method=action.getClass().getMethod(methodName, null);

//action 的返回值
String result=null;

//在完成跳转Action之前完成细颗粒权限控制,控制Action的每个方法 
//检查注解,是否可以操作权限的URl
boolean flag=isCheckLimit(request,method);
if(true){
//运行被拦截的Action,期间如果发生异常会被catch
result=actioninvocation.invoke();

}else{
request.setAttribute("errorMsg", "对不起!您没有权限操作此功能!");
return "errorMsg";
}
return result;
}catch (Exception e) {
/**
* 处理异常
*/
String errorMsg="出现错误信息,请查看日志!";
//通过instanceof 判断到底是什么异常数据类型
if(e instanceof RuntimeException){
//未知的运行异常
RuntimeException re=(RuntimeException)e;
re.printStackTrace();
errorMsg=re.getMessage().trim();
}
/**
* 发送错误消息到页面
*/
request.setAttribute("errorMsg", errorMsg);

/**
*log4j记录日志 
*/
Log log=LogFactory.getLog(actioninvocation.getAction().getClass());
log.error("errorMsg",e);
return "errorMsg";

}

}


/**验证细颗粒权限控制*/
private boolean isCheckLimit(HttpServletRequest request, Method method) {
// TODO Auto-generated method stub
if(method==null){
return false;
}
//获取当前的登陆用户
ElecUser elecUser=(ElecUser) request.getSession().getAttribute("globle_user");
if(elecUser==null){
return false;
}
//获取当前登陆角色的用户(一个用户可能有多个角色)
Hashtable<String,String> ht=(Hashtable<String, String>) request.getSession().getAttribute("globle_role");
if(ht==null || ht.size()<=0){
return false;
}


//处理注解,判断方法上是否存在注解(注解的名称为:AnnotationLimit)
/*
* 例如:
   * @AnnotationLimit(mid="aa",pid="0")
 public String home(){
*/
boolean isAnnotationPresent = method.isAnnotationPresent(AnnotationLimit.class);

//不存在注解(此时不能操作该方法)
if(!isAnnotationPresent){
return false;
}

//存在注解(调用注解)
AnnotationLimit limit = method.getAnnotation(AnnotationLimit.class);

//获取注解上的值
String mid = limit.mid();  //权限子模块名称
String pid = limit.pid();  //权限父操作名称

/**
* 如果登陆用户的角色id+注解上的@AnnotationLimit(mid="aa",pid="0")
*   * 在elec_role_popedom表中存在   flag=true,此时可以访问Action的方法;
*   * 在elec_role_popedom表中不存在 flag=false,此时不能访问Action的方法;
*/
boolean flag = false;
//拦截器中加载spring容器,从而获取Service类,使用Service类查询对应的用户信息
WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());
ElecRoleService elecRoleService = (ElecRoleService)wac.getBean(ElecRoleService.SERVICE_NAME);
//遍历角色ID
if(ht!=null && ht.size()>0){
for(Iterator<Entry<String, String>> ite = ht.entrySet().iterator();ite.hasNext();){
Entry<String, String> entry = ite.next();
//获取角色ID
String roleID = entry.getKey();
flag = elecRoleService.findRolePopedomByID(roleID, mid, pid);
if(flag){
break;
}
}
}

return flag;
}

配置文件代码实现(struts2.xml)

<!-- 自定义拦截器,实现异常处理,实现细颗粒权限控制 -->
<interceptors>
<!-- 声明拦截器 -->
<interceptor name="errorAndLimitInerceptor" class="com.xing.elec.utils.errorAndLimitInerceptor"></interceptor>
<!-- 配置拦截器栈 -->
<interceptor-stack name="myErrorAndLimitInterceptor">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="errorAndLimitInerceptor">
<!-- 该行代码 作用 :让自定义的拦截器对一下方法不起拦截作用 -->
<param name="excludeMethods">menuHome,title,left,change,loading,logout,alermStation,alermDevice,showMenu</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 覆盖底层的拦截器栈,对包中所有action都有效 -->
<default-interceptor-ref name="myErrorAndLimitInterceptor"></default-interceptor-ref>

总结:细颗粒的权限控制总结

1.使用struts2的拦截器

2.定义一个注解(mid,pid),对应权限code和父级权限的code,将注解添加到Action类中的每一个方法

3.每一个Action类的方法上添加注解(mid="",pid=""),表示方法的唯一标识(即 该方法所具有的权限)

4.在struts2的拦截器中,从Session中获取角色ID,获取Action类上的注解(mid和pid),使用角色ID,mid和pid查询角色权限表,判断当前用户是否可以操作该方法

你可能感兴趣的:(细颗粒度权限控制)