在实际web开发过程中通常会存在功能权限的控制,不如这个角色只允许拥有查询权限,这个角色拥有CRUD权限,当然按钮权限显示控制上可以用button.tld来控制,本文就不说明。
具体控制流程就是通过登录系统时候请求控制层将用户的所拥有功能权限查询出来存入session中,然后通过aop切面编程技术获取session里的功能权限与当前方法标签注解权限匹配,当存在则继续执行,若不存在,通过springmvc简单的异常重定向到自己的无权限页面。
1、配置注解方式
privilegeInfo.java
packagecom.tp.soft.common.util;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)public @interfacePrivilegeInfo {
String name()default "";
}
2、通过反射获取注解上的标签的封装类
PrivilegeInfoAnnotationParse.java
packagecom.tp.soft.common.util;importjava.lang.reflect.Method;public classPrivilegeInfoAnnotationParse {public static String parse(Class targetClass, String methodName) throwsNoSuchMethodException, SecurityException{
String privilegeName= "";
Method method=targetClass.getMethod(methodName);//判断方法上是否存在@PrivilegeInfo 注解
if(method.isAnnotationPresent(PrivilegeInfo.class)){//获取注解对象
PrivilegeInfo annotation = method.getAnnotation(PrivilegeInfo.class);//获取注解对象上的名字@PrivilegeInfo(name="admin")//即name为"admin"
privilegeName =annotation.name();
}returnprivilegeName;
}
}
3、创建控制层
LoginController.java
具体session创建在之前那一篇文章中有写到,通过拦截器创建的
packagecom.tp.soft.controller;importjava.util.ArrayList;importjava.util.List;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.servlet.ModelAndView;importcom.tp.soft.common.util.SysContext;importcom.tp.soft.entity.Privilege;importcom.tp.soft.entity.User;
@Controllerpublic classLoginController {
@RequestMapping(value= "/login")publicModelAndView login() {//这里创建一个对象当做登录成功
User user = newUser();
user.setLogin_name("taop");
user.setLogin_pwd("1");//登录查询
if (user != null) {//根据用户查询出所有权限,本来存入数据库,这边就生动生成taop的权限//不如只有添加权限
Privilege privilege = newPrivilege();
privilege.setName("query");
privilege.setDesc("查詢权限");
List privilegeList = new ArrayList();
privilegeList.add(privilege);
SysContext.getSession().setAttribute("privileges", privilegeList);
SysContext.getSession().setAttribute("user", user);return new ModelAndView("/pc/main");
}return null;
}
@RequestMapping(value="/toHasNoPower")publicModelAndView toHasNoPower(){return new ModelAndView("/pc/privilege/noPower");
}
}
UserController.java
packagecom.tp.soft.controller;importjava.util.ArrayList;importjava.util.HashMap;importjava.util.List;importjava.util.Map;importjavax.annotation.Resource;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.servlet.ModelAndView;importcom.tp.soft.common.util.PrivilegeInfo;importcom.tp.soft.common.util.SysContext;importcom.tp.soft.entity.Privilege;importcom.tp.soft.entity.User;importcom.tp.soft.service.login.LoginSvc;importcom.tp.soft.service.sys.UserSvc;
@Controllerpublic classUserController {
@ResourceprivateUserSvc userSvc;
@ResourceprivateLoginSvc loginSvc;
@RequestMapping(value="/toQueryUser")
@PrivilegeInfo(name="query")publicModelAndView toQueryUser(){
User user= userSvc.getUser(21);
Map map = new HashMap();
map.put("user", user);return new ModelAndView("/pc/userTest");
}
}
@PrivilegeInfo(name="query") 可以通过数组的形式 如name={"query", "add"}
创建异常类
AssessDeniedException.java
packagecom.tp.soft.common.exception;public class AssessDeniedException extendsRuntimeException{/****/
private static final long serialVersionUID = 5188167616201017971L;publicAssessDeniedException() {super();//TODO Auto-generated constructor stub
}publicAssessDeniedException(String message, Throwable cause,boolean enableSuppression, booleanwritableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);//TODO Auto-generated constructor stub
}publicAssessDeniedException(String message, Throwable cause) {super(message, cause);//TODO Auto-generated constructor stub
}publicAssessDeniedException(String message) {super(message);//TODO Auto-generated constructor stub
}publicAssessDeniedException(Throwable cause) {super(cause);//TODO Auto-generated constructor stub
}
}
创建权限对象
Privilege.java
public classPrivilege {private intpid;privateString name;privateString desc;
...省略set get
}
4、配置aop切面类
AdminAspect.java
packagecom.tp.soft.aop;importjava.util.List;importjavax.servlet.http.HttpSession;importorg.aspectj.lang.ProceedingJoinPoint;importorg.aspectj.lang.annotation.Around;importorg.aspectj.lang.annotation.Aspect;importorg.aspectj.lang.annotation.Pointcut;importcom.tp.soft.common.exception.AssessDeniedException;importcom.tp.soft.common.util.PrivilegeInfoAnnotationParse;importcom.tp.soft.common.util.SysContext;importcom.tp.soft.entity.Privilege;importcom.tp.soft.entity.User;
@Aspectpublic classAdminAspect {
@Pointcut("execution(* com.tp.soft.controller..*.*(..)) && !execution(* com.tp.soft.controller.LoginController.*(..))")public voidpointCutMethod(){
}
@Around("pointCutMethod()")public Object dealPrivilege(ProceedingJoinPoint jpj) throwsThrowable{//获取请求的类和方法名
Class extends Object> cls =jpj.getTarget().getClass();
String name=jpj.getSignature().getName();
System.out.println(cls);
System.out.println(name);//获取注解上的标签
String privilegeName =PrivilegeInfoAnnotationParse.parse(cls, name);
HttpSession session=SysContext.getSession();
User user= (User) session.getAttribute("user");
List privileges = (List) session.getAttribute("privileges");if(user == null){throw new AssessDeniedException("您无权操作!");
}//是否通过访问
boolean flag = false;if(privilegeName == "" || privilegeName == null){
flag= true;
}else{for(Privilege privilege : privileges) {if(privilegeName.equals(privilege.getName())){//用户访问权限(add) 是否包含当前方法的访问权限
flag = true;break;
}
}
}if(flag){returnjpj.proceed();
}else{//权限不足
System.out.println("权限不足");throw new AssessDeniedException("您无权操作!");
}
}
}
配置spring-mvc.xml 异常类重定向跳转
forward:/toHasNoPower
当无权限抛出异常时候即会重定向到toHashNoPower 然后modelandview 自己写的一个无权限的页面
至此全部结束
请求结果:当直接访问查询方法
当访问
再访问
当将权限设置成
继续访问