问题:只有token身份验证不安全,获取token后可以进行任何操作。
解决:对重要请求增加权限过滤(增删改),非重要请求(查询)不做处理。
创建新表存储重要请求地址(托管菜单表),过滤重要请求(增删改),拦截请求后判断托管表中是否存在该url如果不存在则通过验证,如果存在则判断(角色/菜单关系表)该角色是否有本请求的权限,如果有则通过验证,没有则验证失败。这样完成对重要请求地址的过滤。
gateway网关
过滤器
if (!JwtUtils.checkJWT(token)) {
setFailedRequest(AjaxResult.error401(), 200);
log.info("access token invalid!");
return null;
}
//权限验证
if(!rightCache.checkRight(token, requestURI)) {
setFailedRequest(AjaxResult.error403(), 200);
return null;
}
权限验证
/**
* 权限验证
* @author ******
*
*/
@Component
public class RightCache {
@Autowired
private StringRedisTemplate stringRedisTemplate;
/**
* 权限验证
* @param token
* @param url
* @return
*/
public Boolean checkRight(String token, String url) {
boolean flag = false;
JSONObject jsonObject = getObjectByUrl(url);
if(MyUtil.isEmpty(jsonObject)) {
flag = true;
}else {
String id = jsonObject.get("id").toString();
if(roleCheck(token,id)) {
flag = true;
}
}
return flag;
}
/**
* 根据url获取托管菜单对象
* @param urlkey
* @return
*/
public JSONObject getObjectByUrl(String urlkey) {
JSONObject jsonObject = null;
if (MyUtil.isNotEmpty(urlkey)) {
String key = MyCons.CacheKeyOrPrefix.FunctionMenu.getValue() + ":" + urlkey;
String str = stringRedisTemplate.opsForValue().get(key);
if(MyUtil.isNotEmpty(str)){
jsonObject = JSON.parseObject(str);
}
}
return jsonObject;
}
/**
* 根据token中角色id判断
* 是否存在访问权限
* @param token
* @param functionMenuId
* @return
*/
public Boolean roleCheck(String token,String functionMenuId) {
boolean flag = false;
try {
UserToken userToken = JwtUtils.getInfoFromToken(token);
String roleIds = userToken.getRoleIds();
List<String> listRole = Arrays.asList(roleIds.split(","));
for(String roleId : listRole) {
String key = MyCons.CacheKeyOrPrefix.RoleModule.getValue() + ":" + roleId;
Object object = stringRedisTemplate.opsForHash().get(key, functionMenuId);
if(MyUtil.isNotEmpty(object)) {
flag = true;
break;
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return flag;
}
}
登录时将role加入token
String roleIds = getRoleIds(userDO.getId());
UserToken userToken = new UserToken(userDO.getId(), userDO.getOrg_id(), userDO.getAccount(),
userDO.getName(), IdHelper.getId(),roleIds);
String token="";
try {
token = JwtUtils.generateToken(userToken, tokenExpire);
} catch (Exception e) {
e.printStackTrace();
}
前台(验证规则一致,静态元素(按钮)实现无权限不显示)
/**
* 权限一次加载
*/
permission ={};
top.permissionMap = top.permissionMap || {};
//执行AJAX请求
permission.loadPermissionData = function() {
}
/**
* 权限判断
*/
permission.check = function(url){
var flag = true;
if(top.permissionMap.hasOwnProperty(url)){
flag = top.permissionMap[url] == 0 ? false : true;
}
return flag;
}
/**
* dom是否显示
*/
permission.isShow = function(domId,flag){
var vm = new Vue({
el:domId,
data:{
isShow:flag,
}
});
}
/**
* 根据权限显示
*/
permission.isShowByRight = function(url,domId){
permission.isShow(domId,permission.check(url));
}