一步一步做项目(21)访问控制

一步一步做项目(21)访问控制


在前面 一步一步做项目(18)拦截用户日志的基础上进行,由于前面已经建立了一些内容,这里可以直接使用。

拦截器

同样利用拦截器原理,从MethodFilterInterceptor继承,创建用户访问控制拦截器,由于系统比较简单,就只是提供键值对进行了权限配置,配置信息存储在Messages.properties文件中,如果要进行复杂的授权操作,可以通过数据库来进行存取,代码如下:

package cn.lut.curiezhang.interceptor;

import java.util.ArrayList;
import java.util.Map;
import java.util.ResourceBundle;

import javax.servlet.http.HttpServletRequest;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

import cn.lut.curiezhang.action.LoginAction;
import cn.lut.curiezhang.model.Users;   
/**
 * 登录拦截器
 * @author curiezhang  
 */   
@SuppressWarnings("serial")
public class AccessInterceptor extends MethodFilterInterceptor {   
	public static final String USER_SESSION = ResourceBundle.getBundle("Messages").getString("Application.sessionName");
	public static final String ADMIN_ACCESS_STUDENT = ResourceBundle.getBundle("Messages").getString("Admin.access.STUDENT");
	public static final String ADMIN_ACCESS_COLLEGE = ResourceBundle.getBundle("Messages").getString("Admin.access.COLLEGE");
	public static final String ADMIN_ACCESS_SITE = ResourceBundle.getBundle("Messages").getString("Admin.access.SITE");
	public static final String ADMIN_ACCESS_ADMIN = ADMIN_ACCESS_COLLEGE + "," + ADMIN_ACCESS_SITE + "," + 
	                                                ResourceBundle.getBundle("Messages").getString("Admin.access.ADMIN");
	private static final Logger log = LogManager.getLogger(AccessInterceptor.class);
	@Override
	protected String doIntercept(ActionInvocation actionInvocation) throws Exception {
		log.debug("cmis:访问控制 > 开始拦截");
		HttpServletRequest request = ServletActionContext.getRequest();
        ActionContext actionContext = actionInvocation.getInvocationContext();
        Map<String, Object> session = actionContext.getSession();

        //except login action
        Object action = actionInvocation.getAction();
        if (action instanceof LoginAction) {
           return actionInvocation.invoke();
        }
        //check session
        Users user = (Users)session.get(USER_SESSION);
        String visitUrl = request.getRequestURI();
    	String[] split;
		split = visitUrl.split("/");
        if(null == user) {
        	log.debug("cmis:访问控制 > 请登录");
        	String key;
    		key = split[2];
    		log.debug("cmis:访问控制 > key={}", key);
    		if("admin".equals(key)) {
    			return "loginAdmin";
    		} else {
    			return "login";
    		}
        } else {
        	String key;
        	switch (user.getStatus().getIndex()) {
	    		case 0:
	        		log.debug("cmis:访问控制 0 > status={}", user.getStatus().getIndex());
	        		split = visitUrl.split("/");
	        		key = split[2];
	        		log.debug("cmis:访问控制0 > key={}", key);
	        		String[] front = {"applyForTheCollegeId", "userId", "examineeId", "studentId", "assignExaminationRoomId"};
	        		ArrayList<String> frontValue = new ArrayList<String>();
	        		for(String str : front) {
	        			if(request.getParameter(str) != null) {
	        				log.debug("cmis:访问控制0 > str={},value={}", str, request.getParameter(str));
	        				frontValue.add(request.getParameter(str));
	        			}
	        		}
	        		// 如果访问其他用户,则不能访问
	        		if (!frontValue.isEmpty()) {
	        			for(String str : frontValue) {
	        				if(!str.contains(user.getUserId()))
	        					return "noAccess";
	        			}
	        		}
	        		// 如果访问其他资源,则没有权限
	        		if(!ADMIN_ACCESS_STUDENT.contains(key)) {
	        			return "noPermission";
	        		}
					break;
        		case 1:
	        		log.debug("cmis:访问控制 1 > status={}", user.getStatus().getIndex());
	        		visitUrl = request.getRequestURI();
	        		split = visitUrl.split("/");
	        		key = split[3];
	        		log.debug("cmis:访问控制1 > key={}", key);
	        		String[] front1 = {"collegeId", "examinationApplyId", "enrollmentId", "schoolAdmissionBrochureId", "userId"};
	        		ArrayList<String> front1Value = new ArrayList<String>();
	        		for(String str : front1) {
	        			if(request.getParameter(str) != null) {
	        				log.debug("cmis:访问控制1 > str={},value={}", str, request.getParameter(str));
	        				front1Value.add(request.getParameter(str));
	        			}
	        		}
	        		if (!front1Value.isEmpty()) {
	        			for(String str : front1Value) {
	        				if(!str.contains(user.getUserId()))
	        					return "noAccess";
	        			}
	        		}
	        		if(!ADMIN_ACCESS_COLLEGE.contains(key)) {
	        			return "noPermission";
	        		}
					break;
        		case 2:
	        		log.debug("cmis:访问控制2 > status={}", user.getStatus().getIndex());
	        		visitUrl = request.getRequestURI();
	        		split = visitUrl.split("/");
	        		key = split[3];
	        		log.debug("cmis:访问控制2 > key={}", key);
	        		String[] front2 = {"examinationPointId", "userId", "agendaId", "examinationRoomId", "examinationArrangementId", "assignExaminationRoomId"};
	        		ArrayList<String> front2Value = new ArrayList<String>();
	        		for(String str : front2) {
	        			if(request.getParameter(str) != null) {
	        				log.debug("cmis:访问控制2 > str={},value={}", str, request.getParameter(str));
	        				front2Value.add(request.getParameter(str));
	        			}
	        		}
	        		// 如果访问其他用户,则不能访问
	        		if (!front2Value.isEmpty()) {
	        			for(String str : front2Value) {
	        				if(!str.contains(user.getUserId()))
	        					return "noAccess";
	        			}
	        		}
	        		if(!ADMIN_ACCESS_SITE.contains(key)) {
	        			return "noPermission";
	        		}
					break;
        		case 3:
	        		log.debug("cmis:访问控制3 > status={}", user.getStatus().getIndex());
	        		visitUrl = request.getRequestURI();
	        		split = visitUrl.split("/");
	        		key = split[3];
	        		log.debug("cmis:访问控制3 > key={}", key);
	        		if(!ADMIN_ACCESS_ADMIN.contains(key)) {
	        			return "noPermission";
	        		}
					break;
				default:
					return "noPermission";
			}
        }
        return actionInvocation.invoke();//go on
	}   
}

这里面用到了一些属性值,需要在Messages.properties文件中进行声明,如下所示:

Application.sessionName=userSession
Admin.access.STUDENT=publicNotice
Admin.access.COLLEGE=publicNotice
Admin.access.SITE=publicNotice
Admin.access.ADMIN=index,users,userLog,publicNotice,examinee,discipline,countyDistrict
Admin.access.error=\u6743\u9650\u9519\u8BEF
Admin.access.noPermission=\u6CA1\u6709\u8BBF\u95EE\u6743\u9650\uFF0C\u8BF7\u767B\u5F55\u540E\u518D\u8BD5\u6216\u8054\u7CFB\u7BA1\u7406\u5458\uFF01
Admin.access.noAccess=\u6CA1\u6709\u8BBF\u95EE\u6743\u9650\uFF0C\u8BF7\u66F4\u6362\u7528\u6237\u767B\u5F55\u540E\u518D\u8BD5\u6216\u8054\u7CFB\u7BA1\u7406\u5458\uFF01

配置

创建了AccessInterceptor拦截器类,就要进行配置,在中间添加配置,之后,在action中引用配置,让自定义拦截器起作用,配置如下:

    <interceptors>   
      <interceptor name="auth" class="cn.lut.curiezhang.interceptor.AccessInterceptor" />   
      <interceptor-stack name="authStack">
        <interceptor-ref name="auth"/>
      </interceptor-stack>   
      <interceptor name="log" class="cn.lut.curiezhang.interceptor.UserLogInterceptor" />
      <interceptor-stack name="logStack">
        <interceptor-ref name="log">
        </interceptor-ref> 
      </interceptor-stack> 
    </interceptors>
    <global-results>
      <!-- 定义名为exception的全局result -->
      <result name="loginAdmin" type="redirect">/login/login.jsp</result>
      <result name="noAccess" type="redirect">/admin/error/noAccess.jsp</result>
      <result name="noPermission" type="redirect">/admin/error/noPermission.jsp</result>
    </global-results>

前面的interceptor是用户权限拦截器,后面的interceptor是用户日志拦截器,引用配置方法如下:

    <action name="index" class="cn.lut.curiezhang.action.AdminAction" method="index">
      <result name="success">index.jsp</result>
      <interceptor-ref name="logStack"/>
      <interceptor-ref name="authStack"/>
      <interceptor-ref name="basicStack"/>
    </action>

注意,这里interceptor-ref指定的logStack,就是前面配置的日志拦截器栈信息,这里interceptor-ref指定的authStack,就是前面配置的访问控制拦截器栈信息,这样,只要访问该链接,就会记录访问日志,然后,验证是否具有权限,因此,对应的配置文件,都需要进行相应的处理,以便让权限验证起作用。
从这里可以看出,要想产生一个易于修改的应用,还是比较困难的,而且,越到后面添加类似的功能,需要修改的就越多,就越不容易。当然,这样的修改比较机械,还是简单的。

运行

所有的配置修改好了以后,只要使用action访问的地址,就都会被访问控制拦截器拦截,例如在地址栏输入:http://localhost:8089/cmis/admin/index,如果没有登录,就会要求用户登录,弹出登录页面,运行截图如下:
登录
用户登录后,即可进行相应的操作,如下图所示:
登录后当然,这里只是一个简单的演示,但基本原理是一样的,其他的未登录的访问,都会要求用户进行登录,如果访问了其他没有权限的资源,会进入没有权限页面,当然,这个页面需要读者自己补全,这里不再赘述。

发布了42 篇原创文章 · 获赞 15 · 访问量 5859

猜你喜欢

转载自blog.csdn.net/ZhangCurie/article/details/102948515