简单的struts权限拦截器

自己做一个简单的东东,使用ssh,说实话strut2的拦截器感觉还是比较灵活,由于系统比较简单,权限验证就全部由一个拦截器完成
public class AuthorizeInterceptor implements Interceptor {
	private static final long serialVersionUID = 1L;
	private static final Log log = LogFactory.getLog(AuthorizeInterceptor.class);
	public static final String USR_KEY = "nbrc.user";
	public static final String LOGIN_URL = "login";
	@Override
	public String intercept(ActionInvocation inv) throws Exception {
		log.info("AuthorizeInterceptor进入拦截器");
		Object action = inv.getAction();
		if(action instanceof AuthorizeAction){ 
                //需要验证的action全部实现AuthorizeAction接口
			log.info("需要验证的action");
			User u = (User) inv.getInvocationContext().getSession().get(USR_KEY);
			if(u==null){
				log.info("用户信息不存在");
				return LOGIN_URL;
			}else{
				AuthorizeAction author = (AuthorizeAction) action;
				author.setUser(u);
                                //把用户信息放入action上下文
				if(author.validateUser()){
                                //action的validateUser方法判断用户是否有权限
					log.info("验证用户通过");
					return inv.invoke();
				}else{
					log.info("验证不通过,用户没有权限");
					return LOGIN_URL;
				}
			}
		}else{								
			log.info("不需要用户验证的action");
			return inv.invoke();
		}
	}
	@Override
	public void destroy() {		
	}

	@Override
	public void init() {		
	}
}

后来发现,这样做有一个不好的地方,就是验证是action级别的,而不是方法级别的,粒度太大了,我自己的代码又比较乱,最近在看annotation相关的资料,心中一动,就想把验证的改成用annotation来实现,只需要在方法上标注可以调用该方法的角色,就可以了,拦截器的代码如下:
public class AuthorizeInterceptor implements Interceptor {
	private static final long serialVersionUID = 1L;
	private static final Log log = LogFactory.getLog(AuthorizeInterceptor.class);
	public static final String USR_KEY = "nbrc.user";
	public static final String USR_LOG_CNT="nbrc.logincount";
	public static final String USR_LAST_LOG="nbrc.lastlogin";
	public static final String LOGIN_URL = "login";
	@Override
	public String intercept(ActionInvocation inv) throws Exception {
		log.info("AuthorizeInterceptor进入拦截器");
		Object action = inv.getAction();
		User u = (User) inv.getInvocationContext().getSession().get(USR_KEY);
		String method  = inv.getProxy().getConfig().getMethodName();
		Method m = action.getClass().getMethod(method);		
		String[] roles = null;
		if(m.isAnnotationPresent(AllowRoles.class)){
			AllowRoles ar = m.getAnnotation(AllowRoles.class);
			 roles = ar.roleNames();
			 if(isAllowed(roles,u)){
				 log.info("验证用户通过");
				 return inv.invoke();				 
			 }else{
				 log.info("验证不通过,用户没有权限");
				return LOGIN_URL;
			 }
		}else{
			 log.info("没有Annotation,直接运行");
			return inv.invoke();
		}
	}
	private boolean isAllowed(String[] roles, User usr) {
		if(roles[0].equals("*") && usr!=null){
			log.info("允许用户的权限:*");
			return true;
		}
		if(usr!=null){
			String priv = usr.getPriv();
			for(String r : roles){
				if(r.equals(priv)){
					log.info("允许用户的权限:"  + r);
					return true;
				}
			}
		}
		return false;
	}
	@Override
	public void destroy() {		
	}

	@Override
	public void init() {		
	}
}


annotation的定义如下:
@Retention(RetentionPolicy.RUNTIME)
public @interface AllowRoles {
	public String[] roleNames();
}

匿名可访问的方法可以不用标注,如果是"*",表示需要登录的用户才能访问
	@AllowRoles(roleNames="dangwei")
	public String execute(){
		//TODO:method here
	}
	

你可能感兴趣的:(struts,ssh)