您的位置:首页 > 编程语言 > Java开发

基于角色和资源的用户权限控制(用SpringMVC实现)

2017-04-01 09:15 676 查看
大龄菜鸟 2017-03-03 19:25

介绍

用户权限控制几乎是每个网站都会涉及到的问题,这不仅是涉及到安全,而且还涉及到用户的体验,例如,某个用户可能只需要用到少数几个模块,那么,我们就不应该将无关的模块显示给他。对于很多的小型网站,可能只需要一个管理员账号和密码就可以了,但对于稍微大一点的网站,都会有一套比较严格的用户权限管理机制。在实现方式方面,常见的有以下几种(只是按经验划分,不一定准确):

1、基于层级:将使用者分成多个层级,层级越高拥有的权限越大。例如在一个论坛系统,可以分为超级管理员、普通管理员、版主等,上级会拥有下级的所有权限。

2、基于角色:如果系统的各个模块所使用的用户是相对固定的,那么使用这种方式是不错的选择。例如,一个超市管理软件可以分为收银员、开票员、仓管员等,然后分别有不同的应用模块,用户之间的地位是平等的。

3、基于资源:按一定的粒度将各个模块或操作定义为相应的资源,然后再将资源授权给用户使用。例如,可以将文章 的添加、删除、修改、查看定义为资源,不同的人可以进行不同的操作。

4、基于流程:资源的使用环环相扣,通过前后环节的消息推送来实现控制。例如,在一个公文系统,要发布一份公文,首先要有基层科员起草,然后推送给科长审批,再推送给办公室校对,最后推送给局长签发,如果公文不在当前用户的环节,即使是局长也无权修改。



基于角色和资源的用户权限控制(用SpringMVC实现)

建立数据表

通常,我们会混合使用上述的几种方式。其中,基于角色和资源是目前较为常见的一种实现,一般会有以下几张表:

用户表(users):id、用户名、密码、状态(是否可用,下同)

角色表(roles):id、角色名、角色状态

权限表(permissions):id、权限名、权限状态

除了这三张表外,还要两张表来将三者关联起来:

用户角色关联表(users_roles):用户id、角色id(复合主键)

角色权限关联表(roles_permissions):角色id、权限id(复合主键)

然后,我们在相应的action中通过annotation,或者在XML中定义相应的permission即可。

如果你不想自己实现,可以直接用Spring Security、Shiro等第三方安全框架,只要参照其规范建立几张表,进行一下配置即可。如果要自己实现也不难,下面我们就通过过滤器来实现。

在Web环境中,“资源”大部分情况就是指用户是否有权限访问某个URL。为了实现更加灵活的配置,我们在上述提到的几张表基础上,再增加两张表:

资源表(resources):id、URL、描述

权限资源关联表(permissions_resources):权限id、资源id(复合主键)



相关数据表

大体思路

(1)系统启动的时候,建立一个Map<String,Set> resourceMap,键名为resource(即URL),键值为跟该resource关联的所有permission。由于一个资源可能对应多个permission(如文章查看权限可以授予一般用户,同时也授予文章管理员),因此这里需要用到一个集合。

(2)当用户登录的时候,获取该用户所对应的角色,再根据角色获取其拥有的permission集合

(3)当用户访问受限资源的时候,通过URL从resourceMap中获取所需的permission集合,再跟该用户拥有的permission集合比对,用户有相应的permission则通过,否则不通过。

实现代码

(仅供参考,不一定完善)

1、启动的时候建立resourceMap



2、用户登录的时候加载用户的权限并放到Session



3、创建拦截器,对相关资源进行控制



4、Spring配置文件很简单



如果你系统本身不复杂的话,其实也可以省掉resource表,直接使用URL作为permission,然后role跟permission对应就可以了。这种实现方式的好处是可以对资源进行很精确的配置,除了上述方式,还可以采用粗粒度的配置(如将文章管理作为一项资源uc/articles,包括增删改查),或者更加细粒度的配置(如针对URL的请求方法POST、GET、PUT、DELETE),不过也有一个问题,就是当系统的资源很多的时候,在进行用户权限比对的时候会有较大的消耗。这时候,可以考虑对资源和用户进行分组,先进行分组匹配,再查找相关资源。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: