背景:
权限控制其实我们可以在程序中直接做,如下:
- @Controller
- @RequestMapping("/appDetail.htm")
- public class AppDetailController {
- @RequestMapping(method = RequestMethod.GET)
- public String doGet(ModelMap modelMap, HttpServletRequest httpServletRequest) {
- //1. 开发者有效性判断
- Developer developer = developerManageServiceClient
- .getByCardNo(cardNo);
- if (null == developer){
- return ERROR_VM;
- }
- if (DeveloperStatus.VALID != developer.getStatus() && DeveloperStatus.FREEZE != developer.getStatus()) {
- return ERROR_VM;
- }
- //2. 业务操作,此处省略
- }
- }
- @Controller
- @RequestMapping("/appBaseInfoEdit.htm")
- public class AppBaseInfoEditController {
- @RequestMapping(method = RequestMethod.POST)
- public String modify(ModelMap modelMap, HttpServletRequest httpServletRequest, AppBaseInfoForm appBaseInfoForm) {
- //1. 开发者有效性判断
- Developer developer = developerManageServiceClient
- .getByCardNo(cardNo);
- if (null == developer){
- return ERROR_VM;
- }
- if (DeveloperStatus.VALID != developer.getStatus()) {
- return ERROR_VM;
- }
- //2. 业务操作,此处省略
- }
- }
但是我们会嫌这样的重复代码太多,所以才会有如下做法。
1. 在controller上使用自定义注释,将角色传入
@Controller
@Permission(permissionTypes = { RoleEnum.ADMIN, RoleEnum.LEADER })
public class FeedbackController extends BaseController {
@Autowired
private FeedbackService feedbackService;
@ResponseBody
@RequestMapping(value = "/event", method = RequestMethod.GET)
public ResultVO find(HttpServletRequest request, Long userId) {
System.out.println("进入Controller啦");
System.out.println("我是方法");
ResultVO result = new ResultVO();
result.setMessage("进来Controller啦");
result.setData(feedbackService.find(userId));
return result;
}
}
其中@Permission(permissionTypes = { PermissionEnum.ADMIN, PermissionEnum.LEADER }),是我们的自定义注释,上面可以赋值角色。
2. 编写我们的自定义注释类
@Documented
@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Permission {
/** 检查项枚举 */
RoleEnum[] permissionTypes() default {};
}
3. 编写拦截器
/**
* 权限拦截器
* @author Carson
*
*/
public class PermissionCheckInterceptor extends HandlerInterceptorAdapter {
/** 权限检查服务 */
@Autowired
private PermissionCheckProcessor permissionCheckProcessor;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
if (handler.getClass().isAssignableFrom(HandlerMethod.class)) {
HandlerMethod method = (HandlerMethod) handler;
// 先从方法上那注释
Permission permission = method.getMethodAnnotation(Permission.class);
// 如果方法中拿不到,就在类中找
if (permission == null) {
permission = AnnotationUtils.findAnnotation(method.getBeanType(), Permission.class);
}
return permissionCheckProcessor.process(permission, request,response);
} else {
return true;
}
}
}
4. 编写权限检查器,所有的权限检查都在这里做,可以避免重复代码
@Repository
public class PermissionCheckProcessor {
@Autowired
private UserDao userDao;
public boolean process(Permission permission, HttpServletRequest request, HttpServletResponse response) {
try {
Long userId = Long.parseLong(request.getParameter("userId"));
HttpSession session = request.getSession(false);
if(null != session){
//查询用户
User user = userDao.get(userId);
for (RoleEnum permissionEnum : permission.permissionTypes()) {
if (permissionEnum.toIntValue() == user.getRoleId()) {
return true;
}
}
}
// sendRedirect(response, ISV_APPLY_URL);
return false;
} catch (Exception e) {
// sendRedirect(response, ISV_APPLY_URL);
return false;
}
}
// private void sendRedirect(HttpServletResponse response, String redirectURI) {
// URIBroker uriBroker = uriBrokerManager.getUriBroker(redirectURI);
// String url = uriBroker.render();
// try {
// response.sendRedirect(url);
// } catch (IOException e) {
// logger.error("转向页面:" + url + "跳转出错:", e);
// }
// }
}
5. 角色枚举,这个只是我自己定义的角色
public enum RoleEnum {
ADMIN(1),
LEADER(2),
SUPPORT(3),
VOLUNTEER(4),
SECURITY_ADMIN(5),
SUPER_ADMIN(6)
;
private int key;
private RoleEnum(int key) {
this.key = key;
}
public int toIntValue() {
return this.key;
}
public static RoleEnum toKey(int key) {
if (ADMIN.key == key) {
return ADMIN;
} else if (LEADER.key == key) {
return LEADER;
} else if (SUPPORT.key == key) {
return SUPPORT;
} else if (VOLUNTEER.key == key) {
return VOLUNTEER;
} else if (SECURITY_ADMIN.key == key) {
return SECURITY_ADMIN;
} else if (SUPER_ADMIN.key == key) {
return SUPER_ADMIN;
} else {
throw new InvalidArgumentException("Unknown RoleKey[" + key + "].");
}
}
}
6. 拦截器定义,其中可以定义权限控制拦截器只拦截哪些请求
<!-- 拦截器 --> <mvc:interceptors> <!-- 所有请求都拦截 --> <bean id="testInterceptor" class="com.youyu4.interceptor.TestInterceptor"></bean> <!-- 只有特定请求才拦截 --> <mvc:interceptor> <mvc:mapping path="/event" /> <bean id="permissionCheckInterceptor" class="com.youyu4.interceptor.PermissionCheckInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>