记录一下Struts2一种权限控制的方法——使用拦截器
之前在学springMVC的时候也做过权限控制,也是用拦截器实现的,这段时间正好用ssh开发一个学生签到系统,也碰到这个问题,找了下百度最终用拦截器+注解实现权限控制,实现过程如下:
1.编写用户类型静态类,用于存用户类型常量
package cn.jiesunshine.check_system.utils;
/***
* 用户类型类
* @author xiaojie119120
*
*/
public class UserType {
/***
* 学生
*/
public static final int STU = 0;
public static final String STU_STRING = "学生";
/***
* 老师
*/
public static final int TEA = 1;
public static final String TEA_STRING = "老师";
public static final int ADMIN = 2;
/***
* 管理员
*/
public static final String ADMIN_STRING = "管理员";
private int userType;
public UserType(int userType) {
this.userType = userType;
}
public int getUserType() {
return this.userType;
}
public void setUserType(int userType) {
this.userType = userType;
}
public String getUserTypeStr() {
switch (this.userType) {
case 0:
return "学生";
case 1:
return "老师";
case 2:
return "管理员";
}
return "学生";
}
}
2.编写权限注解类,用来标记需要控制权限的方法
package cn.jiesunshine.check_system.action;
import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import cn.jiesunshine.check_system.utils.UserType;
@Documented
@Inherited
@Target({ java.lang.annotation.ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
/***
* 注解类,userRole为用户等级,配置该注解的方法只有等于或高于userRole参数的用户才能访问
* @author xiaojie119120
*
*/
public @interface AuthPassport {
int userRole() default UserType.STU;
}
3.编写拦截器和拦截逻辑
package cn.jiesunshine.check_system.action;
import cn.jiesunshine.check_system.entity.User;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ActionProxy;
import com.opensymphony.xwork2.interceptor.Interceptor;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
public class AuthorityInterceptor implements Interceptor {
public void destroy() {
}
public void init() {
}
/***
* 拦截方法
*/
public String intercept(ActionInvocation invocation) throws Exception {
//通过代理类拿到拦截到的方法名和方法
String methodName = invocation.getProxy().getMethod();
Method currentMethod = invocation.getAction().getClass()
.getMethod(methodName, null);
//判断方法是否有权限注解
if (currentMethod.isAnnotationPresent(AuthPassport.class)) {
//拿到权限注解对象
AuthPassport authPassport = (AuthPassport) currentMethod
.getAnnotation(AuthPassport.class);
//去session里拿User
User user = (User) ServletActionContext.getRequest().getSession()
.getAttribute("user");
if (user == null) {
return "index";
}
//权限控制逻辑,当前用户权限高于等于注解权限就放行
if (user.getRole().intValue() >= authPassport.userRole()) {
return invocation.invoke();
}
//跳转到权限页面
return "no_authority";
}
//没有注解,直接放行
return invocation.invoke();
}
}
4.配置拦截器
<!-- 自定义拦截器 -->
<package name="base" extends="struts-default">
<global-results>
<result name="index">/WEB-INF/jsp/index.jsp</result>
<result name="no_authority">/WEB-INF/jsp/no_authority.jsp</result>
</global-results>
</package>
<package name="permissionInterceptor" extends="base">
<interceptors>
<!-- 注册自定义的权限控制拦截器 -->
<interceptor name="authorityInterceptor" class="cn.jiesunshine.check_system.action.AuthorityInterceptor"/>
<!-- 把自定义的权限控制拦截器和默认的拦截器栈加到新的自定义的拦截器栈 -->
<interceptor-stack name="myInterceptors">
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="authorityInterceptor"/>
</interceptor-stack>
</interceptors>
<!-- 指定新的自定义的拦截器栈为默认的拦截器栈,这样自定义的权限控制拦截器就可以发挥作用了 -->
<default-interceptor-ref name="myInterceptors"/>
</package>
解释一下以上配置代码:首先配置一个base包继承Struts默认包,再配置我们自定义的拦截器继承base,最后所有的包都继承我们自定义的拦截器包permissionInterceptor
5.使用拦截器
/***
* 添加课程页面
* @return
*/
@AuthPassport(userRole = UserType.STU)
public String addCoursePage() {
return "success";
}
直接在方法上加注解,来标记访问该方法至少需要多高的权限
最后,还有个小问题要说一下:这样配置的拦截器只能拦截http请求,不能拦截ajax,如果需要拦截ajax还得自行百度。