struts2拦截器实现权限控制

转载请注明出处:http://blog.csdn.net/wklken/archive/2011/04/23/6342985.aspx

 

在使用struts2框架开发一个办公OA系统时候,需要使用到权限控制

 

除了判定是否登陆之外,还必须对每个action的访问实现权限控制,因为如果用户登陆成功了,而且以前拥有某个权限的访问,记录下访问的action,而现在没有权限了,也能直接在地址栏输入action路径直接访问,这将使权限这一模块毫无用处。

 

因为没有用到命名空间,这里对于涉及命名空间的没有控制

 

解决思路:【先看这个,懂了以下代码就明白了】

    我们知道struts2的拦截器可以很方便实现对action的访问拦截,先行判断然后再决定是否能够访问。我的实现方法是:

    1.左侧菜单的树形每一列对应一个子模块,也对应一个权限控制ID,若是用户拥有权限,显示,没有,不显示

    2.配置一个xml文件,包含所有权限ID以及其对应的子模块的action,由于某些模块可能使用相同的action,将存在同名的action配置【待会实现注意】

    3.定义一个servlet,在web.xml中配置其启动优先,服务器启动加载

    4.在servlet中,启动是使用插件读入xml文件内容,转化为一个hashmap,键值为action的name属性,value为对应权限id的组合字符串,以空格隔开

    5.hashmap放入application

    6.在struts.xml中定义拦截器的package,定义一个拦截器,配置拦截器栈,其他需要使用到拦截器的package在配置是使用extends这个拦截器package

    7.用户登陆后从数据库查询权限,转为一个hashmap,权限id为键值【为了查询方便】,放入session

    8.实现拦截器,从session中取用户权限,从application中取action映射权限ID的map,从拦截器的invocation中取此次访问的action在配置文件中的actionName

      先判定是否登陆,否,转login.jsp

      是,判定用户是否有访问此action的权限,否,跳到消息页,是,通过

实现步骤:

1.关于左侧菜单的显示,是标签和js等的内容,不再解释,这里主要是地址栏非法访问的控制

2.配置xml文件  authority.xml,配置对应的权限id和其可使用的action【name属性为在struts.xml中配置action的name属性】

[xhtml]  view plain copy print ?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <total>  
  4.   
  5. <!-- //卷库管理-->  
  6. <authority id="18">  
  7. <action name="addRecord"/>  
  8. <action name="deleteRecord"/>  
  9. <action name="updateRecord"/>  
  10. <action name="getAllRecordList"/>  
  11. <action name="getRecordContent"/>  
  12. </authority>  
  13.   
  14. </total>  

3.定义servlet,启动加载配置

  web.xml中

 

[xhtml]  view plain copy print ?
  1. <servlet>  
  2.   <servlet-name>InitBuild</servlet-name>  
  3.   <servlet-class>interceptor.InitBuild</servlet-class>  
  4.   <load-on-startup>1</load-on-startup>  
  5.   </servlet>  

   对应servlet【省略package import等】

[java]  view plain copy print ?
  1. public class InitBuild extends HttpServlet {  
  2.   
  3.  public void init() throws ServletException {  
  4.   try {  
  5.    String path = this.getServletContext().getRealPath("/");//项目路径  
  6.    this.getServletContext().setAttribute("path", path);  
  7.    this.getServletContext().setAttribute("msg""启动加载完毕");  
  8.    //xml文件路径   
  9.    String xmlPath = path+"WEB-INF/authority.xml";  
  10.    this.getServletContext().setAttribute("xmlpath", xmlPath);  
  11.   
  12.    //调用方法,读入xml文件,转化为hashmap  
  13.    this.getServletContext().setAttribute("authorityMap", InitXmlAuthorInfo.getAuthorityMap(xmlPath));  
  14.     } catch (Exception e) {  
  15.      e.printStackTrace();  
  16.   } }}  
  

4.在3中调用的方法,主要读入xml文件,转为hashmap,这里是用dom4j

[java]  view plain copy print ?
  1. import org.dom4j.Document;  
  2. import org.dom4j.Element;  
  3. import org.dom4j.io.SAXReader;  
  4. public class InitXmlAuthorInfo {  
  5.   
  6.    
  7.  private static Document getDom(String xmlPath) {  
  8.   try {  
  9.    SAXReader reader = new SAXReader();  
  10.    Document document = null;  
  11.   
  12.    document = reader.read(new File(xmlPath));  
  13.    return document;  
  14.   } catch (Exception e) {  
  15.     e.printStackTrace();  
  16.    return null;  
  17.   }  
  18.  }  
  19.    
  20.  public static HashMap<String,String> getAuthorityMap(String xmlPath)  
  21.  {  
  22.   HashMap<String,String> authorityMap = new HashMap<String,String>();  
  23.   Document document = getDom(xmlPath);  
  24.   Element rootElm = document.getRootElement();  
  25.   for (Iterator i = rootElm.elementIterator(); i.hasNext();) {  
  26.    Element element = (Element) i.next();  
  27.        
  28.    String id = element.attributeValue("id");  
  29.      
  30.    List<Element> temp = element.elements();  
  31.    for (int j = 0,length = temp.size();j<length; j++) {  
  32.      String actionName = temp.get(j).attribute("name").getText();  
  33.     //action是否重名  
  34.   
  35.     if(authorityMap.containsKey(actionName))  
  36.     {  
  37.       authorityMap.put(actionName,authorityMap.get(actionName)+" "+id);  
  38.     }else{  
  39.      authorityMap.put(actionName,id);  
  40.     }  
  41.      }  
  42.    }  
  43.   return authorityMap;  
  44.  }  
  45. }  

5.配置拦截器和拦截器栈  struts.xml中配置

 

[xhtml]  view plain copy print ?
  1. <!-- 其他package必须extends此package -->  
  2.  <package name="authorityCheck" extends="struts-default">  
  3.         <interceptors>  
  4.         <!-- 在package中配置   注意,login不需要定义此拦截器,定义权限控制拦截器 -->  
  5.           <interceptor name="authority" class="interceptor.AuthorizationInterceptor"/>  
  6.   
  7.         <!-- 定义含“权限检查拦截器”的拦截器栈,注意缺省的拦截器栈“defaultStack”要放在前面 -->  
  8.           <interceptor-stack name="authorityStack">   
  9.   
  10.             <interceptor-ref name="defaultStack"></interceptor-ref>   
  11.             <interceptor-ref name="authority"></interceptor-ref>   
  12.           </interceptor-stack>   
  13.         </interceptors>  
  14.        
  15.   
  16.         <default-interceptor-ref name="authorityStack"></default-interceptor-ref>  
  17.   
  18.   
  19.         <!-- 定义全局处理结果 未登录转到此页-->  
  20.         <global-results>  
  21.         <!-- 逻辑名为login的结果,映射到/login.jsp页面 -->  
  22.         <result name="login">/login.jsp</result>  
  23.         <!-- 无权限进行操作 -->  
  24.         <result name="authorityDeny">/authorityMsg.jsp</result>  
  25.         </global-results>  
  26.  </package>  

6.实现拦截器

 

 

[java]  view plain copy print ?
  1.   package interceptor;  
  2.   
  3. import java.util.Iterator;  
  4. import java.util.Map;  
  5.   
  6. import com.opensymphony.xwork2.Action;  
  7. import com.opensymphony.xwork2.ActionInvocation;  
  8. import com.opensymphony.xwork2.interceptor.AbstractInterceptor;  
  9.   
  10. public class AuthorizationInterceptor extends AbstractInterceptor {  
  11.   
  12.  @Override  
  13.  public String intercept(ActionInvocation invocation) throws Exception {  
  14.   // 获取session   以及application  
  15.   Map session = invocation.getInvocationContext().getSession();  
  16.     
  17.   //判定是否登陆了   未登录 打回登陆页面   用户登陆成功必须将UserID放入session  
  18.   if(session.get("UserID") == null)  
  19.   {  
  20.    System.out.println("AUTHOR ERROR:未登录");  
  21.    return Action.LOGIN;  
  22.   }  
  23.     
  24.   Map application = invocation.getInvocationContext().getApplication();  
  25.     
  26.   //获取全局的权限列表   这个是前面服务器启动加载servlet时候放入application的  
  27.   Map globalAuthorityMap = (Map)application.get("authorityMap");  
  28.     
  29.   //1.判不为空  
  30.   //2.从session取用户权限列表  
  31.   //3.取action的name  
  32.   //4.根绝action的name取权限字符串  
  33.   //5.切分,校验,某一个有就发,全部没有转发消息页面  
  34.     
  35.   //获取用户的权限列表   用户登陆成功将其拥有所有权限的id放入hashmap键值,整个放入session  
  36.   Map userAuthorityMap = (Map)session.get("AuthMap");  
  37.       
  38.   //获取请求的action的name  
  39.   String actionName = invocation.getProxy().getActionName();  
  40.     
  41.   String authorStr = (String)globalAuthorityMap.get(actionName);  
  42.     
  43.   
  44. //切分,当初对于不同权限访问同一action配置空格隔开的字符串  
  45.   String[] authorList = authorStr.split(" ");  
  46.   
  47.    for (int i = 0; i < authorList.length; i++) {  
  48.     if(userAuthorityMap.containsKey(authorList[i]))  
  49.    {  
  50.     return invocation.invoke();  
  51.    }  
  52.    }  
  53.   session.put("authorityMag""对不起,您没有权限进行此操作");  
  54.   return "authorityDeny";  
  55.   }  
  56.   
  57. }  

7.其他package的配置

  注,登陆注销的action不需要

  

[xhtml]  view plain copy print ?
  1. <package name="record" extends="authorityCheck">  
  2.   
  3.    <action name="getRecordContent" class="com.oa.team4.action.RecordAction"  
  4.    method="getRecordContent">  
  5.    <result name="success">/record/edit_record.jsp</result>  
  6.    </action>  
  7.   
  8.   </package>  
  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值