在做各种系统开发时,我们经常会碰到权限控制,而权限控制往往是很复杂的,一般都会涉及到两个层面:第一,操作层面;第二,业务层面。所谓操作层面是指用户是否拥有某个操作权限,比如浏览、添加、删除、修改等。所谓业务层面是指,两个用户都拥有比如说浏览这一操作权限,但是他们浏览的内容有所区别。
而struts2采用拦截器做权限控制主要是针对操作层面的权限控制。它的实现方式是:将所有的操作存放的到数据库中,并跟用户关联,自定义一个拦截器,该拦截器拦截所有的操作,检查该用户是否拥有该操作权限,如果拥有则放行,如果没有则跳转到提示页面。
主要包含以下工作:
1、在struts.xml配置文件中配置一个自定义的拦截器,该拦截器属于某个包,所有需要进行控制的action都要继承该包,例如:
<package name="authority" extends="struts-default">
<interceptors>
<interceptor name="authority"
class="com.goldpac.framework.filter.AuthorityInterceptor" />
<!-- 定义含“权限检查拦截器”的拦截器栈,注意缺省的拦截器栈“defaultStack”要放在前面 -->
<interceptor-stack name="authorityStack">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="authority"></interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="authorityStack"></default-interceptor-ref>
<global-results>
<!-- 无权限进行操作 -->
<result name="authorityDeny">/WEB-INF/page/authorityMsg.jsp</result>
</global-results>
</package>
action配置文件中,要进行权限控制的action所在的包要继承上面定义的拦截器包:
<package name="system" namespace="/system" extends="authority">
<!-- 这里是要进行权限控制的action -->
</package>
2、自定义拦截器的实现类
import java.util.List;
import com.goldpac.framework.core.ServiceProvider;
import com.goldpac.framework.utils.AuthorityUtils;
import com.goldpac.pms.system.entity.Operate;
import com.goldpac.pms.system.entity.Users;
import com.goldpac.pms.system.service.IOperateService;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
/**
* 所有action的拦截器,进行权限控制
* */
public class AuthorityInterceptor extends AbstractInterceptor {
private static final long serialVersionUID = 1L;
// private IUserService userService = (IUserService) ServiceProvider
// .getService(IUserService.SERVICENAME);
private IOperateService opService = (IOperateService) ServiceProvider
.getService(IOperateService.SERVICENAME);
@SuppressWarnings("unchecked")
public String intercept(ActionInvocation invocation) throws Exception {
ActionContext invoContext = invocation.getInvocationContext();
String actionUrl = invoContext.getName(); //当前action的名称
System.out.println("当前操作的URL:" + actionUrl);
//查看数据库中是否有该操作,如果没有则加入数据库--这一步主要是为了往数据库中添加需要权限控制的操作,从而减少了手动添加的工作量
if(!opService.isExist(actionUrl)){
opService.save(actionUrl);
}
//有些action不需要控制,但又继承了拦截器包,所以这里直接放行
if("userAction_isLogin".equals(actionUrl)){
return invocation.invoke();
}
// 取出存放在session中的不需要权限控制的一些操作
List<Operate> commonOpList = (List<Operate>) invoContext.getSession()
.get("commonOpList");
// 验证当前请求是否属于不需要权限控制的操作
if (commonOpList != null
&& AuthorityUtils.isCommonAuthority(commonOpList, actionUrl)) {
System.out.println("不需要控制,直接跳转!");
return invocation.invoke();// 如果不需要权限控制,则直接跳转到相应的操作action
} else {
// 进行权限验证,取出该session中该用户所拥有的权限,进行验证
Users user = (Users) invoContext.getSession().get("user");
// 进行权限验证
if (user != null
&& AuthorityUtils.isHasAuthority(user.getOperates(),
actionUrl)) {
System.out.println("需要权限控制,已拥有该权限!");
return invocation.invoke();
} else {
System.out.println("需要权限控制,没有该权限!");
return "authorityDeny";
}
}
}
}