java基于模块的数据字典权限验证防止数据越权攻击

允许的数据保存在会话中,属性为"modulePerm",数据结构为Map结构,各个模块的数据相互独立,各个模块的key值不同,比如用户模块就是"sysUser"。

每个模块内,又可以设置多个需要校验的属性,每个属性设置不同的名称。

1. 添加权限数据

void addCheckData(String modueName, String keyName, HashSet hset) {
		// 权限数据
		HashMap permMap = new HashMap<String, HashSet>();

		permMap.put(keyName, hset);

		// 分模块验证数据
		HashMap moduleMap = new HashMap<String, HashMap>();

		// 设置模块
		moduleMap.put(modueName, permMap);

		HttpSession session = ServletUtils.getSession();

		session.setAttribute("modulePerm", moduleMap);

	}

2. 验证数据方法

void verifyCheckData(String modueName, String keyName, ArrayList<String> arrayValue) {
		HttpSession session = ServletUtils.getSession();
		HashMap moduleMap = (HashMap) session.getAttribute("modulePerm");

		// 获取模块需要验证的内容
		HashMap<String, HashSet<String>> map = (HashMap<String, HashSet<String>>) moduleMap.get(modueName);

		if (map != null) {
			for (Map.Entry<String, HashSet<String>> entry : map.entrySet()) {
				String key = entry.getKey();
				HashSet<String> valSet = entry.getValue();

				// 指定了key,只验证指定key,其他key跳过当前验证
				// 空值表示验证所有规则
				if (StringUtils.isNotEmpty(keyName) && !key.equals(keyName)) {
					continue;
				}				
				
				// 这里的id应该在允许的map里面
				for (String str : arrayValue) {

					if (!valSet.contains(str)) {
						// 非法参数
						throw new BusinessException("非法参数");
					}
				}
			}

		}
		else
		{
			// 非法参数
			throw new BusinessException("非法参数");
		}
	}

3. 添加数据

查询权限范围内的数据的同时,将数据保存到会话中。

public class SysUserController extends BaseController {
		
	private String MODULE_NAME = "sysUser";
	private String CHECK_KEY_1 = "roleIds";
	
	public String add(ModelMap mmap) {
		List<SysRole> listRole = roleService.selectRoleAll();

		HashSet hset = new HashSet<String>();

		for (SysRole role : listRole) {
			Long roleId = role.getRoleId();

			hset.add(roleId.toString());
		}

		addCheckData(MODULE_NAME, CHECK_KEY_1, hset);

		mmap.put("roles", listRole);
		mmap.put("posts", postService.selectPostAll());
		return prefix + "/add";
	}	
	
}

4. 执行验证

在执行数据保存的时候,进行参数验证。

public class SysUserController extends BaseController {
		
	private String MODULE_NAME = "sysUser";
	private String CHECK_KEY_1 = "roleIds";
		
	
	public AjaxResult addSave(SysUser user) throws Exception {

		ArrayList arrayList = new ArrayList<String>();
		
		for(Long id : user.getRoleIds())
		{
			arrayList.add(id.toString());
		}
		
		verifyCheckData(MODULE_NAME, CHECK_KEY_1, arrayList);
	}	
}

比如在添加用户操作中,返回的页面之前,需要读取允许添加的用户角色列表,可以将该数据保存到会话中,当保存添加的用户时,就可以根据之前保存的数据校验用户角色是否在允许的范围内,如果不在允许范围内,则可以说明被篡改过,此时不应执行添加用户。

除了添加以外,对于修改用户和删除用户,也可以采用类似思路进行处理。

在实际的项目应用中,可以把添加数据和验证数据的方法添加到父类,这样子类就可以直接调用了,不用在每个子类中添加这两个方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值