`
youyu4
  • 浏览: 425800 次
社区版块
存档分类
最新评论

基于拦截器和注解实现页面的访问权限控制

 
阅读更多

背景:

权限控制其实我们可以在程序中直接做,如下:

Java代码  收藏代码
  1. @Controller  
  2. @RequestMapping("/appDetail.htm")  
  3. public class AppDetailController {  
  4.     @RequestMapping(method = RequestMethod.GET)  
  5.     public String doGet(ModelMap modelMap, HttpServletRequest httpServletRequest) {  
  6.         //1. 开发者有效性判断  
  7.         Developer developer = developerManageServiceClient  
  8.             .getByCardNo(cardNo);  
  9.         if (null == developer){  
  10.             return ERROR_VM;  
  11.         }  
  12.         if (DeveloperStatus.VALID != developer.getStatus()  &&  DeveloperStatus.FREEZE != developer.getStatus()) {  
  13.             return ERROR_VM;  
  14.         }  
  15.         //2. 业务操作,此处省略  
  16.     }  
  17. }  
  18.   
  19. @Controller  
  20. @RequestMapping("/appBaseInfoEdit.htm")  
  21. public class AppBaseInfoEditController {  
  22.     @RequestMapping(method = RequestMethod.POST)  
  23.     public String modify(ModelMap modelMap, HttpServletRequest httpServletRequest,  AppBaseInfoForm appBaseInfoForm) {  
  24.         //1. 开发者有效性判断  
  25.         Developer developer = developerManageServiceClient  
  26.             .getByCardNo(cardNo);  
  27.         if (null == developer){  
  28.             return ERROR_VM;  
  29.         }  
  30.         if (DeveloperStatus.VALID !=  developer.getStatus()) {  
  31.             return ERROR_VM;  
  32.         }  
  33.         //2. 业务操作,此处省略  
  34.     }  
  35. }  

 

但是我们会嫌这样的重复代码太多,所以才会有如下做法。

 

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>

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics