当前位置: 主页 > 数据库

数据库权限管理设计-权限设计 数据权限

发布时间:2023-02-13 11:17   浏览次数:次   作者:佚名

更多精彩第一时间直达

数据库权限管理设计_大数据名录库管理_权限设计 数据权限

前言 随着移动互联网的发展,前端开发的领域越来越广。 前端已经告别了切图时代,迎来了前端大型化、工程化时代。 近年来,随着react、angular、vue等前端框架的兴起,前后端分离的架构迅速流行起来。 但与此同时,权限控制也带来了问题。 前后端分离后,虽然前端也会进行权限控制,但是比较简单。 而且,只有前端的权限控制并不是真正的权限控制。 用户可以完全绕过前端控制,直接向后端发起请求。 权限设计 目前最流行的权限设计模型是RBAC模型,基于角色的访问控制(Role-Based Access Control)

权限设计 数据权限_大数据名录库管理_数据库权限管理设计

市面上流行的Apache Shrio、Spring Security都是基于这种模型设计的。 权限系统可以说是整个系统中最基础的,但也可以说是非常复杂的。 在实际项目中,会遇到多系统、多用户类型、多使用场景数据库权限管理设计,需要具体问题具体分析,但最核心的RBAC模型是不变的,我们可以对其进行扩展以满足需求。 下面是一个简单的用户、角色、操作、组织数据库表设计,基本满足大部分业务场景。

大数据名录库管理_数据库权限管理设计_权限设计 数据权限

数据库权限管理设计_大数据名录库管理_权限设计 数据权限

如果前端控制用户登录成功,会生成一个Token,里面会包含一些基本的用户信息,不推荐角色权限信息。 这个Token会附加到用户发送给后端的请求中。 前端一般由菜单和按钮控制。 用户登录认证成功后,根据用户ID实时获取并渲染菜单信息。 对于按钮控件,情况就比较复杂了。 如果要求不是很高,可以一次性查询,放入本地缓存,本地认证。 这是一个更简单的实现:

hasRole: function(roles){
var roleNames = this.userInfo.roleNames;
if(roleNames!=""){
var role = roles.split(",");
var array = roleNames.split(",");
for(var i=0;i if(array.indexOf(role[i])>-1){
return true;
}
}
}
return false;
}

权限设计 数据权限_数据库权限管理设计_大数据名录库管理

按钮控制:

"primary" v-if="hasRole('admin')" icon="ios-cloud-download" @click="exportCashReports">导出</i-button>

后台控制虽然前端控制了前端,但是远远不够。 特殊用户可以完全避开前端控制,直接向后端发起请求。 这时候如果后端不对请求进行安全校验,很容易暴露敏感数据。 出去。 在单体架构时代,如果我使用一个安全框架,我只需要一个注解或者一个拦截配置。 例如:

大数据名录库管理_数据库权限管理设计_权限设计 数据权限

@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean (SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setLoginUrl("/login.html");
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
Map<String, Filter> filtersMap = new LinkedHashMap<>();
filtersMap.put("kickout", kickoutSessionControlFilter());
shiroFilterFactoryBean.setFilters(filtersMap);
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
/**
* 静态文件
*/

filterChainDefinitionMap.put("/css/**","anon");
filterChainDefinitionMap.put("/images/**","anon");
filterChainDefinitionMap.put("/js/**","anon");
filterChainDefinitionMap.put("/file/**","anon");
/**
* 登录
*/

filterChainDefinitionMap.put("/login.html","anon");
filterChainDefinitionMap.put("/sys/logout","anon");
filterChainDefinitionMap.put("/sys/login","anon");
/**
* 管理后台
*/

filterChainDefinitionMap.put("/sys/**", "roles[admin]");
filterChainDefinitionMap.put("/**", "kickout,authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}

或这个:

 
/**
* 角色列表
*/

@PostMapping("/list")
@RequiresRoles(value="admin")
public Result list(SysRole role){
return sysRoleService.list(role);
}

数据库权限管理设计_大数据名录库管理_权限设计 数据权限

前后端分离后,后端不保存任何用户信息,只能通过前端传输的token进行验证。 这里参考Shrio的实现思路,写个注解实现权限校验。


/**
* 权限注解
*/

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresRoles {

/**
* A single String role name or multiple comma-delimitted role names required in order for the method
* invocation to be allowed.
*/

String[] value();

/**
* The logical operation for the permission check in case multiple roles are specified. AND is the default
* @since 1.1.0
*/

Logical logical() default Logical.OR;
}

然后写一个拦截器来拦截请求,这里是认证代码的一部分:

权限设计 数据权限_大数据名录库管理_数据库权限管理设计

/**
* @Description
* @Author 小柒2012
* @Date 2020/6/12
*/

@Component
public class AuthUtils {

@Autowired
private RedisUtils redisUtils;

public boolean check(Object handler,String userId){
HandlerMethod handlerMethod = (HandlerMethod) handler;
Annotation permAnnotation= handlerMethod.getMethod().getAnnotation(RequiresPermissions.class);
if(permAnnotation!=null) {
String[] role = handlerMethod.getMethod().getAnnotation(RequiresPermissions.class).value();
List roleList = Arrays.asList(role);
/**
* 获取用户实际权限
*/

List list = redisUtils.lGet("perms:"+userId,0,-1);
List permissions = roleList.stream().filter(item -> list.contains(item)).collect(toList());
if (permissions.size() == 0) {
return false;
}
}else{
Annotation roleAnnotation= handlerMethod.getMethod().getAnnotation(RequiresRoles.class);
if(roleAnnotation!=null){
String[] role = handlerMethod.getMethod().getAnnotation(RequiresRoles.class).value();
List roleList = Arrays.asList(role);
/**
* 获取用户实际角色
*/

List list = redisUtils.lGet("roles:"+userId,0,-1);
List roles = roleList.stream().filter(item -> list.contains(item)).collect(toList());
if (roles.size() == 0) {
return false;
}
}
}
return true;
}
}

上面提到,用户登录成功后,用户的角色信息会被保存到缓存中。 在生产环境中数据库权限管理设计,可以根据业务需求的实时性选择读取数据库和读取缓存。 总结 前后端开发不是灵丹妙药,微服务也不是。 不要盲目选机型跟风,不要学习大厂的经验,更不要谈技术债。 适合您团队的是最好的。 当然,如果项目不高,出去了怎么吹牛,怎么扩大团队规模,怎么升职加薪,所以我之前说的都是废话,要点还是被进球了! ! ! 最后还是要推荐魅子图的微服务版,权限设计参考这个。

大数据名录库管理_权限设计 数据权限_数据库权限管理设计

权限设计 数据权限_数据库权限管理设计_大数据名录库管理

▲有温度的公众号,期待与你共同进步