菜单权限管理

本文介绍了在数据库中实现菜单权限管理的方法,通过用户表记录账号权限,菜单表存储菜单信息。为避免每个接口单独处理权限,使用了拦截器来判断用户是否具有访问特定菜单的权限,防止非法跳转。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在数据库中拥有菜单表与用户权限表的情况下,页面上登录账号进去只能看到用户权限表中所存在的菜单,但由于不想每个接口都写权限审查,所以写了一个基于拦截器的权限判断来审查,防止用户在不经过页面操作而是直接通过url跳转到不在自己权限内的菜单中。

数据表:user表(若分角色组的需要另外一个角色表,这里是按账号区分的,所以直接把权限字段rights写在user表中)

               menu表(菜单表,我这里设计的字段有menu_id,menu_name,menu_url,parent_id,menu_order,menu_icon,                                   menu_type,menu_state)

拦截器代码:

	<!-- 权限访问拦截  -->
	<mvc:interceptors>
		<mvc:interceptor>
			<mvc:mapping path="/**/*.do"/>
			<bean class="com.mxr.interceptor.JurisdictionInterceptor"/>
		</mvc:interceptor>
	</mvc:interceptors>

拦截所有.do的url访问路径。

com.mxr.interceptor.JurisdictionInterceptor类:

public class JurisdictionInterceptor implements HandlerInterceptor {
    private static final Logger logger = LoggerFactory.getLogger(JurisdictionInterceptor.class);


    @Resource(name = "chaMenuService")
    private ChaMenuService menuService;

    @Resource(name = "chaUserService")
    private ChaUserService chaUserService;
/*
 *拦截所有.do的访问接口,判断该账号是否拥有权限,若不拥有则无法访问
 */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取访问的url
        String url=request.getRequestURI();
        //Const.SHIRO_PREFIX_UN为项目中的“username”
        String username=SecurityUtils.getSubject().getPrincipals().asList().get(1).toString().replace(Const.SHIRO_PREFIX_UN, "");
        //通过username(唯一)到用户表中获取userId
        int userId=chaUserService.getByUsername(username).getUserId();
        //通过userId获取权限rights在菜单树中所对应的各个url
        List<ChaMenu> chaMenuList = menuService.listTreeMenuByRole(userId);
        int flag=0;
        //遍历菜单树,若访问的url存在于菜单树url中则flag=1
        for(int i=0;i<chaMenuList.size();i++){
            for(int j=0;j<chaMenuList.get(i).getSubMenu().size();j++) {
                String menuUrl=chaMenuList.get(i).getSubMenu().get(j).getMenuUrl();
                if(menuUrl.equals(url)){
                    flag=1;
                }
            }
        }
        if(flag==1){
            return true;
        }
        //设置编码格式
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter pw = response.getWriter();
        pw.write("拦截器拦截,无权限操作");
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        if(ex != null)
            logger.error("异常", ex);

    }
}
获取用户id下的权限菜单(有缓存)
@Override
	public List<ChaMenu> listTreeMenuByRole(int userId) throws Exception {
		ChaUser role = chaUserService.getByUserId(userId);
		if (role == null)
			return new ArrayList<>();
		String menuRights = role.getRights();
		List<ChaMenu> allMenuList = listAll();
		List<ChaMenu> menuList = listTreeMenu(allMenuList, 0, menuRights, true);
		return menuList;
	}



	/**
	 * 获取所有菜单记录(外部调有缓存,内部则无)
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public List<ChaMenu> listAll() throws Exception {
		return (List<ChaMenu>) dao.findForList(MAPPER.concat("listAll"), null);
	}


	@Override
	public List<ChaMenu> listTreeMenu(List<ChaMenu> allMenuList, Integer parentMenuId, String rights, boolean isExcept) {
		if(allMenuList == null || allMenuList.size() == 0)
			return new ArrayList<>();
		List<ChaMenu> list = new ArrayList<>();
		for(ChaMenu menu: allMenuList) {
			if(menu.getMenuState() == Status.ENABLED.getId())
				continue;
			if(menu.getParentId() != parentMenuId)
				continue;
			rights = rights == null ? "" : rights;
			boolean hasRights = rights.equals(Const.ALL_RIGHTS) || RightsHelper.testRights(rights, menu.getMenuId());
			menu.setHasMenu(hasRights);
			if(isExcept && !menu.isHasMenu())
				continue;
			menu.setSubMenu(listTreeMenu(allMenuList, menu.getMenuId(), rights, isExcept));
			if(menu.getSubMenu() != null && menu.getSubMenu().size() > 0)
				menu.setTarget("treeFrame");
			list.add(menu);
		}
		return list;
	}

	/**
	 * 测试是否具有指定编码的权限
	 * @param sum
	 * @param targetRights
	 * @return
	 */
	public static boolean testRights(String sum,int targetRights){
		if(Tools.isEmpty(sum))
			return false;
		return testRights(new BigInteger(sum),targetRights);
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值