基于struts2拦截器的权限管理之拦截器实现
程序员文章站
2022-03-03 16:16:24
...
这里共定义了三种拦截器,用于日志记录·过滤未登录用户·验证访问权限·作业时间拦截器:
1.日志记录。
package com.xx.power.web.intercept;
import java.util.Date;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.ylsoft.invite.action.SaveException;
import com.ylsoft.power.domain.entity.AccessLog;
import com.ylsoft.power.domain.entity.User;
import com.ylsoft.power.domain.service.AccessLogService;
import com.ylsoft.power.openservice.AccessDenyException;
import com.ylsoft.power.openservice.LoginFailException;
import com.ylsoft.power.query.ajax.json.response.FailResponseBean;
import com.ylsoft.power.web.action.AbstractAction;
import com.ylsoft.power.web.action.ActionUtil;
public class AccessLogInterceptor extends AbstractInterceptor {
private static final long serialVersionUID = 3888019155867653546L;
private AccessLogService accessLogService;//日志服务,记录refer,用户信息,访问地址,处理耗时,访问者ip,客户端信息
public static final String ACTION_NAME = "ACTION_NAME";//访问地址在session中的位置
public void setAccessLogService(AccessLogService accessLogService) {
this.accessLogService = accessLogService;
}
/**
* 拦截处理
*/
public String intercept(ActionInvocation ai) throws Exception {
System.out.println("begin request");
String result = null;
Exception ex = null;
Long escape = System.currentTimeMillis();
HttpServletRequest request = null;
try {//捕捉所有异常,并进行异常记录
logSetUp(ai);
request = (HttpServletRequest) ai.getInvocationContext().get(ServletActionContext.HTTP_REQUEST);
HttpSession session = request.getSession();
String url = request.getRequestURI();
String actionName = this.getActionNameUrl(url);
session.setAttribute(ACTION_NAME, actionName);//放置用户访问地址
result = ai.invoke();
escape = System.currentTimeMillis() - escape;
} catch (LoginFailException e) {
ActionSupport action = (ActionSupport) (ai.getAction());
action.addActionError(e.getMessage());
e.printStackTrace();
ex = e;
escape = System.currentTimeMillis() - escape;
} catch (Exception e) {
ex = e;
escape = System.currentTimeMillis() - escape;
e.printStackTrace();
} finally {
AccessLog accessLog = logSetUp(ai);
accessLog.setElapsedTime(escape);//设置耗时
if (ex != null) {
accessLog.setDescript(StringUtils.substring(ex.getMessage(), 0,100));
accessLog.setThrowEx(true);
} else {
accessLog.setThrowEx(false);
}
accessLogService.persistLog(accessLog);
HttpServletResponse response = (HttpServletResponse) ai.getInvocationContext().get(
ServletActionContext.HTTP_RESPONSE);
String ajax = request.getHeader("x-requested-with");// 判断时同步请求还是异步请求
// 为空代表同步的请求
ActionSupport action = (ActionSupport) (ai.getAction());
if (ex!=null) {
if (StringUtils.isNotBlank(ajax)) {
if (request.getParameter("r") != null) {
ActionUtil.flushJsonMsg(response, new FailResponseBean("操作失败!"));
return null;
}else if (ex != null&&ex instanceof LoginFailException) {
ActionUtil.flushJsonMsg(response, new FailResponseBean("xx"));
return null;
}
}else if(ex instanceof AccessDenyException){
return "501";
}else if (ex != null&&ex instanceof LoginFailException) {
ActionUtil.flushMsg(response, "<script>window.top.location='"+request.getContextPath()+"/login!loginUI.action';</script>");
return null;
}
if (ex instanceof SaveException) {
SaveException saveException=(SaveException) ex;
action.addActionError(saveException.getMessage());
return saveException.getResult();
}
}
//TODO 实现退回
System.out.println("begin response");
if (result==null) {
if (ex!=null) {
action.addActionError(ex.getMessage());
}else {
action.addActionError("服务器错误!");
}
result="500";
}
}
return result;
}
/**
* 装配访问日志对象
* @param ai
* @return
*/
private AccessLog logSetUp(ActionInvocation ai) {
AccessLog accessLog = new AccessLog();
HttpServletRequest request = (HttpServletRequest) ai.getInvocationContext().get(
ServletActionContext.HTTP_REQUEST);
Map<String, Object> session =(Map<String, Object>) ai.getInvocationContext().get(ServletActionContext.SESSION);
User user = (User) session.get(AbstractAction.LOGIN_USER_SESSION_KEY);
String user_agent = request.getHeader("User-Agent");
String userIp = request.getRemoteAddr();
String url = request.getRequestURI();
String reffer=request.getHeader("refer");
accessLog.setReffer(StringUtils.substring(reffer, 0,90));
accessLog.setUrl(this.getActionNameUrl(url));
accessLog.setUser(user);
if (user!=null) {
accessLog.setUserId(user.getUserId());
}
accessLog.setUserIp(userIp);
accessLog.setUserOs(user_agent != null ? user_agent.substring(0, user_agent.length() > 70 ? 70 : user_agent
.length() - 1) : null);
accessLog.setUsrBrowser(user_agent != null ? user_agent.substring(0, user_agent.length() > 70 ? 70 : user_agent
.length() - 1) : null);
accessLog.setLogDate(new Date());
accessLog.setAction(null);
return accessLog;
}
/**
* 得到用户访问地址xx!x.action形式
* @param url
* @return
*/
private String getActionNameUrl(String url) {
String actionName = "";
String[] str = url.split("/");
if (str.length > 0) {
actionName = str[str.length - 1];
}
if (actionName.indexOf("?") > 0) {
actionName = actionName.substring(0, actionName.indexOf("?"));
}
return actionName;
}
}
2.过滤未登录用户
/**
* 验证是不是已登录用户
*/
package com.xx.power.web.intercept;
import java.util.Map;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.ylsoft.power.domain.entity.Action;
import com.ylsoft.power.domain.entity.Catalog;
import com.ylsoft.power.domain.entity.User;
import com.ylsoft.power.domain.service.ActionService;
import com.ylsoft.power.openservice.LoginFailException;
import com.ylsoft.power.web.action.AbstractAction;
public class ValidSessionInterceptor extends AbstractInterceptor{
private static final long serialVersionUID = 6751070416682198400L;
private ActionService actionService;//操作或动作指令服务
/**
* 拦截并处理
*/
public String intercept(ActionInvocation ai) throws Exception {
System.out.println("begin request");
String result="";
try {
Map session=ai.getInvocationContext().getContext().getSession();
if (session.get(AbstractAction.LOGIN_USER_SESSION_KEY)==null) {
throw new LoginFailException(null,"请登录!");//抛出全局异常
}else {
//查看用户访问地址
Action action=actionService.top0InUrl((String)session.get(AccessLogInterceptor.ACTION_NAME));
String listViewType=null;//过滤类型
Catalog catalog=null; //访问对应的具体页面
if (action!=null) {
listViewType=action.getListViewType();
catalog=action.getCatalog();
}
/**
* 通过threadlocal变量进行动态的参数传递,可以在用户当前请求线程中访问和设置
*/
ThreadLocalOperater.setAccessMessage(new AccessMessage((User)session.get(AbstractAction.LOGIN_USER_SESSION_KEY),listViewType,catalog));
result=ai.invoke();
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("begin response");
return result;
}
public void init() {
super.init();
System.out.println("验证会话拦截器 init...");
}
public void destroy() {
super.destroy();
System.out.println("验证会话拦截器 destroy...");
}
public void setActionService(ActionService actionService) {
this.actionService = actionService;
}
}
3.·验证访问权限
/**
* 身份验证
*/
package com.ylsoft.power.web.intercept;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.ylsoft.power.domain.entity.Catalog;
import com.ylsoft.power.domain.entity.User;
import com.ylsoft.power.openservice.AccessService;
import com.ylsoft.power.openservice.PowerBean;
import com.ylsoft.power.web.action.AbstractAction;
public class AuthenticateInterceptor extends AbstractInterceptor{
private static final long serialVersionUID = 4422212767616230184L;
public static final String MENUNAME="IS-A-MENU";//是不是导航菜单
private AccessService accessService;//访问处理服务
public void setAccessService(AccessService accessService) {
this.accessService = accessService;
}
/**
* 拦截并处理
*/
public String intercept(ActionInvocation ai) throws Exception {
authenRole(ai);
return ai.invoke();
}
/**
* 核心方法 进行角色验证
* @param ai
* @return true
* @throws Exception
*/
private boolean authenRole(ActionInvocation ai) throws Exception{
System.out.println(ai);
HttpSession session=((HttpServletRequest)ai.getInvocationContext().get(ServletActionContext.HTTP_REQUEST)).getSession();
HttpServletRequest request = (HttpServletRequest) ai.getInvocationContext().get(
ServletActionContext.HTTP_REQUEST);
String type="";
if ("menu".equals(request.getParameter("t"))) {//规定 如果是菜单访问的参数会在后面加上一个标识
type=MENUNAME;
}
//访问的判断都在下面的方法里面
Catalog catalog=accessService.accessInUrl((String)session.getAttribute(AccessLogInterceptor.ACTION_NAME), (User)session.getAttribute(AbstractAction.LOGIN_USER_SESSION_KEY),type);
PowerBean powerBean=new PowerBean(catalog);//权限bean 里面包含了用户当前请求页面的按钮和输入框,也就是表单的元素
ai.getStack().set(PowerBean.name, powerBean);//放在值栈里用于标签读取
return true;
}
}
4.作业时间
这里是业务上一个内容,不在权限范围内。