转载:通过struts2拦截器实现权限管理

转自:http://www.360doc.com/content/10/0128/23/284485_14629422.shtml

  1. package com.work.qxgl.login;
  2. import java.util.List;
  3. import java.util.Map;
  4. import javax.servlet.http.HttpServletRequest;
  5. import org.apache.commons.logging.Log;
  6. import org.apache.commons.logging.LogFactory;
  7. import org.apache.struts2.StrutsConstants;
  8. import org.apache.struts2.config.DefaultSettings;
  9. import com.opensymphony.xwork2.Action;
  10. import com.opensymphony.xwork2.ActionInvocation;
  11. import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
  12. import com.work.core.QxglConstants;
  13. import com.work.core.spring.MyBeanUtil;
  14. import com.work.qxgl.model.QxglRole;
  15. import com.work.qxgl.usermodel.UserModelServiceDao;
  16. public class AuthorizationInterceptor extends AbstractInterceptor {
  17.     /**
  18.      * 
  19.      */
  20.     private static final long serialVersionUID = 4949812834762901805L;
  21.     private static Log log = LogFactory.getLog(AuthorizationInterceptor.class);
  22.     @Override
  23.     public String intercept(ActionInvocation invocation) throws Exception {
  24.         // 取得请求的Action名
  25.         String name = invocation.getInvocationContext().getName(); // action
  26.         // 的名称,在xml中配置的
  27.         String namespace = invocation.getProxy().getNamespace(); // 获取到namespace,还能够获取到要执行的方法,class等
  28.         if ((namespace != null) && (namespace.trim().length() > 0)) {
  29.             if ("/".equals(namespace.trim())) {
  30.                 // 说明是根路径,不需要再增加反斜杠了。
  31.             } else {
  32.                 namespace += "/";
  33.             }
  34.         }
  35.         String URL = namespace + invocation.getProxy().getActionName();
  36.         
  37.         URL += ".action";
  38.         log.debug("actionname=" + name + "||fullActionName=" + URL);
  39.         if (name.equals("login") || name.equals("loginAccess")) {
  40.             // 如果用户想登录,则使之通过
  41.             return invocation.invoke();
  42.         }
  43.         Map session = invocation.getInvocationContext().getSession();
  44.         // TODO 在这里判断用户是否已经登陆,更改此方法,和OnLineUserManager联系起来,
  45.         //OnLineUserManager 是线程安全的,效率上可能会比较低!所以暂时还不更改!。
  46.         String success = (String) session.get(QxglConstants.AUTH_SUCCESS);
  47.         log.debug("success=" + success);
  48.         // 如果没有登陆,那么就退出系统
  49.         if (success == null || !"true".equals(success)) {
  50.             log.debug("please login");
  51.             return Action.LOGIN;
  52.         }
  53.         String userid = (String) session.get("userid");
  54.         if (userid == null || "".equals(userid)) {
  55.             log.error("用户id不能为空!");
  56.             return Action.LOGIN;
  57.         }
  58.         // 如果是超级管理员,那么直接返回
  59.         if ("admin1111222233334444555566admin".equals(userid)) {
  60.             return invocation.invoke();
  61.         }
  62.         UserModelServiceDao userModelServiceDao = (UserModelServiceDao) MyBeanUtil
  63.                 .getBean("userModelServiceDao");
  64.         // 获取当前用户所拥有的角色
  65.         List<QxglRole> userRoles = userModelServiceDao.getRoles(userid);
  66.         if (userRoles == null || userRoles.size() < 1) {
  67.             // 没有任何角色
  68.             log.warn("此用户" + userid + "没有任何角色,没有权限执行任何功能");
  69.             return "noPermit";
  70.         }
  71.         List<QxglRole> urlRoles = userModelServiceDao.getRolesByUrl(URL);
  72.         // 如果此URL没有赋给任何角色,说明是合法用户就可以访问
  73.         if (urlRoles == null || urlRoles.size() < 1) {
  74.             log.debug("此资源未赋给任何角色,合法用户就可以访问");
  75.             return invocation.invoke();
  76.         }
  77.         // 根据角色来判断用户是否有权限来使用当前的URL(action)
  78.         boolean flag = false;// 如果有权限访问设置为true;
  79.         int userLen = userRoles.size();
  80.         int urlLen = urlRoles.size();
  81.         QxglRole tempUserRole = null;
  82.         QxglRole tempUrlRole = null;
  83.         
  84.         START:
  85.         for (int i = 0; i < userLen; i++) {
  86.             // 首先初始化
  87.             tempUserRole = null;
  88.             tempUrlRole = null;
  89.             tempUserRole = userRoles.get(i);
  90.             for (int j = 0; j < urlLen; j++) {
  91.                 tempUrlRole = urlRoles.get(j);
  92.                 if (tempUserRole.getId().equals(tempUrlRole.getId())) {
  93.                     flag = true;
  94.                     break START;
  95.                 }
  96.             }
  97.         }
  98.         if (flag) {
  99.             log.debug("success auth");
  100.             return invocation.invoke();
  101.         } else {
  102.             //用户如果在主页面中输入其他的任何链接,系统将自动执行logout动作,因为在/sysmenu/top.jsp中配置了onunload事件。
  103.             log.warn("此用户" + userid + "没有权限执行此功能"+URL);
  104.             return "noPermit";
  105.         }
  106.     }
  107. }

在struts2的配置文件中配置

 

  1.     <package name="qxglmain" extends="struts-default" namespace="/">
  2.         <!-- 自定义拦截器 -->
  3.         <interceptors>
  4.             <interceptor name="auth"
  5.                 class="com.work.qxgl.login.AuthorizationInterceptor" />
  6.             <interceptor name="ourLogger"
  7.                 class="com.work.core.interceptor.LoggingInterceptor" />
  8.             <interceptor name="ourTimer"
  9.                 class="com.work.core.interceptor.TimerInterceptor" />               
  10.             <!-- 自定义拦截器堆栈 -->
  11.             <interceptor-stack name="qxglStack">
  12.                 <interceptor-ref name="auth" /><!--  权限控制 -->
  13.                 <!-- 用来查看每个action执行了多长时间,看执行效率,只所以重新编写,因为xwork的源代码的日志级别低为INFO,我们配置的日志级别为ERROR。所以看不到了 -->
  14.                 <interceptor-ref name="ourTimer" />
  15.                 <interceptor-ref name="ourLogger" />
  16.                 <!-- 
  17.                 <interceptor-ref name="logger" /> -->
  18.                 <!-- 引用默认的拦截器堆栈 -->
  19.                 <interceptor-ref name="defaultStack" />
  20.             </interceptor-stack>
  21.         </interceptors>
  22.         <!-- 重定义默认拦截器堆栈 -->
  23.         <default-interceptor-ref name="qxglStack" />
  24.         <global-results>
  25.             <result name="login" type="redirectAction">login</result>
  26.             <result name="error">/qxgl/error.jsp</result>
  27.             <result name="noPermit">/qxgl/noPermit.jsp</result>
  28.             <result name="input" type="redirectAction">login</result>           
  29.         </global-results>
  30.         <!--  exception的配置必须在global-results后面 -->
  31.         <global-exception-mappings>
  32.             <exception-mapping
  33.                 exception="java.lang.NullPointerException" result="error" />
  34.             <exception-mapping exception="java.lang.Exception"
  35.                 result="error" />
  36.             <exception-mapping
  37.                 exception="com.work.core.exception.StorageException" result="error" />              
  38.         </global-exception-mappings>
  39.         
  40.         <action name="qxglmain"
  41.             class="com.work.qxgl.main.QxglMainAction">
  42.             <result>/qxgl/menutree/qxglmain.jsp</result>
  43.         </action>
  44.         <action name="sysmain"
  45.             class="com.work.qxgl.main.QxglMainAction" method="sysmain">
  46.             <result>/sysmenu/sysMain.jsp</result>
  47.         </action>
  48.         <action name="login" class="com.work.qxgl.login.LoginAction"
  49.             method="login">
  50.             <result>/login.jsp</result>
  51.         </action>
  52.         <action name="logout" class="com.work.qxgl.login.LogoutAction">
  53.             <result>/login.jsp</result>
  54.         </action>
  55.     
  56.         <action name="loginAccess" class="com.work.qxgl.login.LoginAction">
  57.             <result type="redirectAction">sysmain</result>
  58.             <result name="input" >/login.jsp</result>
  59.         </action>
  60.         <action name="listOnLineUsers" class="com.work.qxgl.login.OnLineUserAction">
  61.             <result>/qxgl/onlineuser/onlineuser.jsp</result>
  62.         </action>   
  63.         <action name="kickUser" class="com.work.qxgl.login.OnLineUserAction"
  64.             method="kickUser">
  65.             <result type="chain">listOnLineUsers</result>
  66.         </action>       
  67.         <action name="listMenu" class="com.work.qxgl.main.QxglMainAction"
  68.             method="listMenu">
  69.             <result>/sysmenu/menu.jsp</result>
  70.         </action>       
  71.     </package>

缺点:

struts2的拦截器只能够控制*.action,其他的jsp文件等会被忽略,所以通过struts2的拦截器实现权限控制有一定的缺陷。

 

我们可以通过编写一个filter来控制其他请求的权限

 

  1. package com.work.core.filter;
  2. /**
  3.  * @author wangmingjie
  4.  * @date 2008-8-25下午10:09:26
  5.  */
  6. import java.io.IOException;
  7. import javax.servlet.Filter;
  8. import javax.servlet.FilterChain;
  9. import javax.servlet.FilterConfig;
  10. import javax.servlet.ServletException;
  11. import javax.servlet.ServletRequest;
  12. import javax.servlet.ServletResponse;
  13. import javax.servlet.http.HttpServletRequest;
  14. import javax.servlet.http.HttpServletResponse;
  15. import javax.servlet.http.HttpSession;
  16. import org.apache.commons.logging.Log;
  17. import org.apache.commons.logging.LogFactory;
  18. import com.work.core.QxglConstants;
  19. public class AuthFilter implements Filter {
  20.     private static Log log = LogFactory.getLog(AuthFilter.class);
  21.     public void init(FilterConfig filterConfig) throws ServletException {
  22.         if(log.isDebugEnabled()){
  23.             log.debug("初始化权限过滤器。");
  24.         }
  25.     }
  26.     public void doFilter(ServletRequest servletRequest,
  27.             ServletResponse servletResponse, FilterChain filterChain)
  28.             throws IOException, ServletException {
  29.         /**
  30.          * 1,doFilter方法的第一个参数为ServletRequest对象。此对象给过滤器提供了对进入的信息(包括
  31.          * 表单数据、cookie和HTTP请求头)的完全访问。第二个参数为ServletResponse,通常在简单的过
  32.          * 滤器中忽略此参数。最后一个参数为FilterChain,此参数用来调用servlet或JSP页。
  33.          */
  34.         HttpServletRequest request = (HttpServletRequest) servletRequest;
  35.         /**
  36.          * 如果处理HTTP请求,并且需要访问诸如getHeader或getCookies等在ServletRequest中
  37.          * 无法得到的方法,就要把此request对象构造成HttpServletRequest
  38.          */
  39.         HttpServletResponse response = (HttpServletResponse) servletResponse;
  40.         String currentURL = request.getRequestURI(); // 取得根目录所对应的绝对路径:
  41.         HttpSession session = request.getSession(false);
  42.         //如果jsp就验证(login.jsp除外)
  43.         if (currentURL.indexOf(QxglConstants.LOGIN_PAGE)==-1 && currentURL.indexOf(".jsp")>-1 ) { 
  44.             if(log.isDebugEnabled()){
  45.                 log.debug("对jsp文件进行权限验证。"+"请求的URL:"+currentURL);            
  46.             }
  47.             // 判断当前页是否是重定向以后的登录页面页面,如果是就不做session的判断,防止出现死循环
  48.             if(session == null || session.getAttribute(QxglConstants.AUTH_SUCCESS) == null ){
  49.                 response.sendRedirect(request.getContextPath()+QxglConstants.LOGIN_PAGE);
  50.                 return ;
  51.             }
  52.         }
  53.         // 加入filter链继续向下执行
  54.         filterChain.doFilter(request, response);
  55.         /**
  56.          *  调用FilterChain对象的doFilter方法。Filter接口的doFilter方法取一个FilterChain对象作 为它
  57.          * 的一个参数。在调用此对象的doFilter方法时,激活下一个相关的过滤器。如果没有另
  58.          * 一个过滤器与servlet或JSP页面关联,则servlet或JSP页面被激活。
  59.          */
  60.     }
  61.     public void destroy() {
  62.     }
  63. }

在web.xml中配置权限过滤器

 

  1.     <!-- 进行权限验证 -->
  2.     <filter>
  3.         <filter-name>AuthFilter</filter-name>
  4.         <filter-class>
  5.             com.work.core.filter.AuthFilter
  6.         </filter-class>
  7.     </filter>   
  8.     <filter-mapping>
  9.         <filter-name>AuthFilter</filter-name>
  10.         <url-pattern>/*</url-pattern>
  11.     </filter-mapping>
上一篇:PHP Ajax实现页面无刷新发表评论


下一篇:“万里牛”实时数仓的演进之路