背景:
权限控制其实我们可以在程序中直接做,如下:
- @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>