允许的数据保存在会话中,属性为"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);
}
}
比如在添加用户操作中,返回的页面之前,需要读取允许添加的用户角色列表,可以将该数据保存到会话中,当保存添加的用户时,就可以根据之前保存的数据校验用户角色是否在允许的范围内,如果不在允许范围内,则可以说明被篡改过,此时不应执行添加用户。
除了添加以外,对于修改用户和删除用户,也可以采用类似思路进行处理。
在实际的项目应用中,可以把添加数据和验证数据的方法添加到父类,这样子类就可以直接调用了,不用在每个子类中添加这两个方法。
|