- packagecom.work.qxgl.login;
- importjava.util.List;
- importjava.util.Map;
- importjavax.servlet.http.HttpServletRequest;
- importorg.apache.commons.logging.Log;
- importorg.apache.commons.logging.LogFactory;
- importorg.apache.struts2.StrutsConstants;
- importorg.apache.struts2.config.DefaultSettings;
- importcom.opensymphony.xwork2.Action;
- importcom.opensymphony.xwork2.ActionInvocation;
- importcom.opensymphony.xwork2.interceptor.AbstractInterceptor;
- importcom.work.core.QxglConstants;
- importcom.work.core.spring.MyBeanUtil;
- importcom.work.qxgl.model.QxglRole;
- importcom.work.qxgl.usermodel.UserModelServiceDao;
- publicclassAuthorizationInterceptorextendsAbstractInterceptor{
- /**
- *
- */
- privatestaticfinallongserialVersionUID=4949812834762901805L;
- privatestaticLoglog=LogFactory.getLog(AuthorizationInterceptor.class);
- @Override
- publicStringintercept(ActionInvocationinvocation)throwsException{
- //取得请求的Action名
- Stringname=invocation.getInvocationContext().getName();//action
- //的名称,在xml中配置的
- Stringnamespace=invocation.getProxy().getNamespace();//获取到namespace,还能够获取到要执行的方法,class等
- if((namespace!=null)&&(namespace.trim().length()>0)){
- if("/".equals(namespace.trim())){
- //说明是根路径,不需要再增加反斜杠了。
- }else{
- namespace+="/";
- }
- }
- StringURL=namespace+invocation.getProxy().getActionName();
- URL+=".action";
- log.debug("actionname="+name+"||fullActionName="+URL);
- if(name.equals("login")||name.equals("loginAccess")){
- //如果用户想登录,则使之通过
- returninvocation.invoke();
- }
- Mapsession=invocation.getInvocationContext().getSession();
- //TODO在这里判断用户是否已经登陆,更改此方法,和OnLineUserManager联系起来,
- //OnLineUserManager是线程安全的,效率上可能会比较低!所以暂时还不更改!。
- Stringsuccess=(String)session.get(QxglConstants.AUTH_SUCCESS);
- log.debug("success="+success);
- //如果没有登陆,那么就退出系统
- if(success==null||!"true".equals(success)){
- log.debug("pleaselogin");
- returnAction.LOGIN;
- }
- Stringuserid=(String)session.get("userid");
- if(userid==null||"".equals(userid)){
- log.error("用户id不能为空!");
- returnAction.LOGIN;
- }
- //如果是超级管理员,那么直接返回
- if("admin1111222233334444555566admin".equals(userid)){
- returninvocation.invoke();
- }
- UserModelServiceDaouserModelServiceDao=(UserModelServiceDao)MyBeanUtil
- .getBean("userModelServiceDao");
- //获取当前用户所拥有的角色
- List<QxglRole>userRoles=userModelServiceDao.getRoles(userid);
- if(userRoles==null||userRoles.size()<1){
- //没有任何角色
- log.warn("此用户"+userid+"没有任何角色,没有权限执行任何功能");
- return"noPermit";
- }
- List<QxglRole>urlRoles=userModelServiceDao.getRolesByUrl(URL);
- //如果此URL没有赋给任何角色,说明是合法用户就可以访问
- if(urlRoles==null||urlRoles.size()<1){
- log.debug("此资源未赋给任何角色,合法用户就可以访问");
- returninvocation.invoke();
- }
- //根据角色来判断用户是否有权限来使用当前的URL(action)
- booleanflag=false;//如果有权限访问设置为true;
- intuserLen=userRoles.size();
- inturlLen=urlRoles.size();
- QxglRoletempUserRole=null;
- QxglRoletempUrlRole=null;
- START:
- for(inti=0;i<userLen;i++){
- //首先初始化
- tempUserRole=null;
- tempUrlRole=null;
- tempUserRole=userRoles.get(i);
- for(intj=0;j<urlLen;j++){
- tempUrlRole=urlRoles.get(j);
- if(tempUserRole.getId().equals(tempUrlRole.getId())){
- flag=true;
- breakSTART;
- }
- }
- }
- if(flag){
- log.debug("successauth");
- returninvocation.invoke();
- }else{
- //用户如果在主页面中输入其他的任何链接,系统将自动执行logout动作,因为在/sysmenu/top.jsp中配置了onunload事件。
- log.warn("此用户"+userid+"没有权限执行此功能"+URL);
- return"noPermit";
- }
- }
- }
在struts2的配置文件中配置
- <packagename="qxglmain"extends="struts-default"namespace="/">
- <!--自定义拦截器-->
- <interceptors>
- <interceptorname="auth"
- class="com.work.qxgl.login.AuthorizationInterceptor"/>
- <interceptorname="ourLogger"
- class="com.work.core.interceptor.LoggingInterceptor"/>
- <interceptorname="ourTimer"
- class="com.work.core.interceptor.TimerInterceptor"/>
- <!--自定义拦截器堆栈-->
- <interceptor-stackname="qxglStack">
- <interceptor-refname="auth"/><!--权限控制 -->
- <!--用来查看每个action执行了多长时间,看执行效率,只所以重新编写,因为xwork的源代码的日志级别低为INFO,我们配置的日志级别为ERROR。所以看不到了-->
- <interceptor-refname="ourTimer"/>
- <interceptor-refname="ourLogger"/>
- <!--
- <interceptor-refname="logger"/>-->
- <!--引用默认的拦截器堆栈-->
- <interceptor-refname="defaultStack"/>
- </interceptor-stack>
- </interceptors>
- <!--重定义默认拦截器堆栈-->
- <default-interceptor-refname="qxglStack"/>
- <global-results>
- <resultname="login"type="redirectAction">login</result>
- <resultname="error">/qxgl/error.jsp</result>
- <resultname="noPermit">/qxgl/noPermit.jsp</result>
- <resultname="input"type="redirectAction">login</result>
- </global-results>
- <!--exception的配置必须在global-results后面-->
- <global-exception-mappings>
- <exception-mapping
- exception="java.lang.NullPointerException"result="error"/>
- <exception-mappingexception="java.lang.Exception"
- result="error"/>
- <exception-mapping
- exception="com.work.core.exception.StorageException"result="error"/>
- </global-exception-mappings>
- <actionname="qxglmain"
- class="com.work.qxgl.main.QxglMainAction">
- <result>/qxgl/menutree/qxglmain.jsp</result>
- </action>
- <actionname="sysmain"
- class="com.work.qxgl.main.QxglMainAction"method="sysmain">
- <result>/sysmenu/sysMain.jsp</result>
- </action>
- <actionname="login"class="com.work.qxgl.login.LoginAction"
- method="login">
- <result>/login.jsp</result>
- </action>
- <actionname="logout"class="com.work.qxgl.login.LogoutAction">
- <result>/login.jsp</result>
- </action>
- <actionname="loginAccess"class="com.work.qxgl.login.LoginAction">
- <resulttype="redirectAction">sysmain</result>
- <resultname="input">/login.jsp</result>
- </action>
- <actionname="listOnLineUsers"class="com.work.qxgl.login.OnLineUserAction">
- <result>/qxgl/onlineuser/onlineuser.jsp</result>
- </action>
- <actionname="kickUser"class="com.work.qxgl.login.OnLineUserAction"
- method="kickUser">
- <resulttype="chain">listOnLineUsers</result>
- </action>
- <actionname="listMenu"class="com.work.qxgl.main.QxglMainAction"
- method="listMenu">
- <result>/sysmenu/menu.jsp</result>
- </action>
- </package>
缺点:
struts2的拦截器只能够控制*.action,其他的jsp文件等会被忽略,所以通过struts2的拦截器实现权限控制有一定的缺陷。
我们可以通过编写一个filter来控制其他请求的权限
- packagecom.work.core.filter;
- /**
- *@authorwangmingjie
- *@date2008-8-25下午10:09:26
- */
- importjava.io.IOException;
- importjavax.servlet.Filter;
- importjavax.servlet.FilterChain;
- importjavax.servlet.FilterConfig;
- importjavax.servlet.ServletException;
- importjavax.servlet.ServletRequest;
- importjavax.servlet.ServletResponse;
- importjavax.servlet.http.HttpServletRequest;
- importjavax.servlet.http.HttpServletResponse;
- importjavax.servlet.http.HttpSession;
- importorg.apache.commons.logging.Log;
- importorg.apache.commons.logging.LogFactory;
- importcom.work.core.QxglConstants;
- publicclassAuthFilterimplementsFilter{
- privatestaticLoglog=LogFactory.getLog(AuthFilter.class);
- publicvoidinit(FilterConfigfilterConfig)throwsServletException{
- if(log.isDebugEnabled()){
- log.debug("初始化权限过滤器。");
- }
- }
- publicvoiddoFilter(ServletRequestservletRequest,
- ServletResponseservletResponse,FilterChainfilterChain)
- throwsIOException,ServletException{
- /**
- *1,doFilter方法的第一个参数为ServletRequest对象。此对象给过滤器提供了对进入的信息(包括
- *表单数据、cookie和HTTP请求头)的完全访问。第二个参数为ServletResponse,通常在简单的过
- *滤器中忽略此参数。最后一个参数为FilterChain,此参数用来调用servlet或JSP页。
- */
- HttpServletRequestrequest=(HttpServletRequest)servletRequest;
- /**
- *如果处理HTTP请求,并且需要访问诸如getHeader或getCookies等在ServletRequest中
- *无法得到的方法,就要把此request对象构造成HttpServletRequest
- */
- HttpServletResponseresponse=(HttpServletResponse)servletResponse;
- StringcurrentURL=request.getRequestURI();//取得根目录所对应的绝对路径:
- HttpSessionsession=request.getSession(false);
- //如果jsp就验证(login.jsp除外)
- if(currentURL.indexOf(QxglConstants.LOGIN_PAGE)==-1&¤tURL.indexOf(".jsp")>-1){
- if(log.isDebugEnabled()){
- log.debug("对jsp文件进行权限验证。"+"请求的URL:"+currentURL);
- }
- //判断当前页是否是重定向以后的登录页面页面,如果是就不做session的判断,防止出现死循环
- if(session==null||session.getAttribute(QxglConstants.AUTH_SUCCESS)==null){
- response.sendRedirect(request.getContextPath()+QxglConstants.LOGIN_PAGE);
- return;
- }
- }
- //加入filter链继续向下执行
- filterChain.doFilter(request,response);
- /**
- *调用FilterChain对象的doFilter方法。Filter接口的doFilter方法取一个FilterChain对象作为它
- *的一个参数。在调用此对象的doFilter方法时,激活下一个相关的过滤器。如果没有另
- *一个过滤器与servlet或JSP页面关联,则servlet或JSP页面被激活。
- */
- }
- publicvoiddestroy(){
- }
- }
在web.xml中配置权限过滤器
- <!--进行权限验证-->
- <filter>
- <filter-name>AuthFilter</filter-name>
- <filter-class>
- com.work.core.filter.AuthFilter
- </filter-class>
- </filter>
- <filter-mapping>
- <filter-name>AuthFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>