2008-07-15
使用Rails做一个RBAC的权限管理系统(不使用插件)
关键字: rbac 权限管理
前几天,稍微分析了一下RBAC形式的权限管理系统的实现原理,然后我使用Rails做了一个。
先来说一下表间的关系:
users <--> roles roles <--> permissions
很简单,用户和角色是多对多关系,角色和权限也是多对多关系,那么关于权限管理这一块就一共有5张表。
具体的表结构:
还是直接看数据库定义文件吧!
在User这个Model中有以下两个关键的方法:
现在,大致的意思,相信应该说清楚了吧,我对于用户权限的验证就是根据url,准确地说,应该是根据controller名称和action名称来验证的。
那么现在来看看此权限管理系统是如何工作的吧!
在用户登录时,我把用户的id存到session范围中,然后在需要进行权限保护的控制器中加入如下的过滤器:
比如我在后台管理对文章进行管理(Admin::PostController),代码如下:
以上是对于每次请求的权限控制,那么在页面上如何根据登录用户的权限显示相应的权限内容呢?
在后台管理的模块页面中,加入如下的判断语句即可。
以上就是我做这个权限管理系统的基本思想,代码量比较少,思路也蛮请楚的,比较适合小型的项目。
不过我分析了一下这个权限管理系统,它就基于控制器和控制器方法的名称来判断的,而且应该是对使用generate scaffold形式生成的控制器能比较好地起作用。那么这就决定了它有多方面的不足。
1- 如何保护后台管理中的静态页面。
2- 使用不方便,在对permissions进行管理时,要求管理员比较对所用的程序比较熟悉,了解那些controller和action才行(我正在考虑怎么样让程序自动获取后台中的所有控制器和相关方法,并且显示它们的作用)
3- 权限重复比较多。
4- 与系统结合得感觉还是比较紧,我正在考虑如何运行ruby的特性将其变成一个插件(我的目标)
我正在考虑如何改进这些问题,从而做了一个轻量级的好用的权限管理系统。
先来说一下表间的关系:
users <--> roles roles <--> permissions
很简单,用户和角色是多对多关系,角色和权限也是多对多关系,那么关于权限管理这一块就一共有5张表。
具体的表结构:
还是直接看数据库定义文件吧!
ActiveRecord::Schema.define(:version => 20080708074044) do
create_table "permissions", :force => true do |t|
t.string "name"
t.string "action"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "permissions_roles", :id => false, :force => true do |t|
t.integer "permission_id", :limit => 11
t.integer "role_id", :limit => 11
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "posts", :force => true do |t|
t.string "title"
t.text "body"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "roles", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "roles_users", :id => false, :force => true do |t|
t.integer "role_id", :limit => 11
t.integer "user_id", :limit => 11
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "users", :force => true do |t|
t.string "name"
t.string "password"
t.string "email"
t.datetime "created_at"
t.datetime "updated_at"
end
end
在User这个Model中有以下两个关键的方法:
#Get user's all permissions def permissions user_permissions = Array.new for role in self.roles user_permissions += role.permissions end user_permissions.uniq! user_permissions end #Get user's allowed requests uri def permission_urls user_urls = Array.new user_permissions = Array.new for role in self.roles user_permissions += role.permissions end for user_permission in user_permissions user_urls << user_permission.action end user_urls end
现在,大致的意思,相信应该说清楚了吧,我对于用户权限的验证就是根据url,准确地说,应该是根据controller名称和action名称来验证的。
那么现在来看看此权限管理系统是如何工作的吧!
在用户登录时,我把用户的id存到session范围中,然后在需要进行权限保护的控制器中加入如下的过滤器:
比如我在后台管理对文章进行管理(Admin::PostController),代码如下:
before_filter :authorize, :only => [:index, :show, :new, :edit, :destroy] def authorize unless User.find(session[:user_id]).permission_urls.include?( self.class.controller_path + "/" + self.action_name ) flash[:notice] = "You have not permission to do it!" redirect_to :controller => "admin/welcome" end end
以上是对于每次请求的权限控制,那么在页面上如何根据登录用户的权限显示相应的权限内容呢?
在后台管理的模块页面中,加入如下的判断语句即可。
<% if User.find(session[:user_id]).allowed_to?("admin/posts/index")%>
<li id="posts_item"><%= link_to "Post Manage", admin_posts_path %></li>
<% end %>
以上就是我做这个权限管理系统的基本思想,代码量比较少,思路也蛮请楚的,比较适合小型的项目。
不过我分析了一下这个权限管理系统,它就基于控制器和控制器方法的名称来判断的,而且应该是对使用generate scaffold形式生成的控制器能比较好地起作用。那么这就决定了它有多方面的不足。
1- 如何保护后台管理中的静态页面。
2- 使用不方便,在对permissions进行管理时,要求管理员比较对所用的程序比较熟悉,了解那些controller和action才行(我正在考虑怎么样让程序自动获取后台中的所有控制器和相关方法,并且显示它们的作用)
3- 权限重复比较多。
4- 与系统结合得感觉还是比较紧,我正在考虑如何运行ruby的特性将其变成一个插件(我的目标)
我正在考虑如何改进这些问题,从而做了一个轻量级的好用的权限管理系统。
- 17:45
- 浏览 (352)
- 评论 (13)
- 分类: Ruby and Rails
- 进入论坛
- 相关推荐
评论
kkito
2008-08-01
年初的时候我用了一个插件,感觉跟楼主这个差不多
activerbac
自己也思考了一下
至于那个控制粒度问题
你怎么控制粒度精确到对资源的操作?
如A建立的POSTS,B能看不能删,C是版主,能看有能删
我觉得也可以实现
应该除destory方法外还有一个destory_by_self方法
一般用户有destory_by_self的权限,而版主有destory权限
或者destory方法只能删除自己的文章,另一个admin_destory可以随便删
就能做到自己的能够删,不能删别人,版主都能删文章的功能
本来逻辑上就可以看成两码事
activerbac
自己也思考了一下
至于那个控制粒度问题
你怎么控制粒度精确到对资源的操作?
如A建立的POSTS,B能看不能删,C是版主,能看有能删
我觉得也可以实现
应该除destory方法外还有一个destory_by_self方法
一般用户有destory_by_self的权限,而版主有destory权限
或者destory方法只能删除自己的文章,另一个admin_destory可以随便删
就能做到自己的能够删,不能删别人,版主都能删文章的功能
本来逻辑上就可以看成两码事
lurena
2008-08-01
这个基本没有实用性, 实现的权限管理要比这复杂得多.
做教科书还可以.
做教科书还可以.
rainchen
2008-08-01
qichunren 写道
引用
你怎么控制粒度精确到对资源的操作?
如A建立的POSTS,B能看不能删,C是版主,能看有能删
如A建立的POSTS,B能看不能删,C是版主,能看有能删
不知道你说的是不是:
你是说对于某个特定的用户创建的资源的权限控制吗?我做的这个不能达到这个要求.
如果只有让B能看不能删posts,让C能看又能删posts,那可以通过我的这个控制.
不知道对于你说的针对某个特定的资源(在我我先暂且理解为table中的一条记录)是如何控制每个用户对其的权限控制,有什么好的方法没有??
我选用 RoleRequirement 这个插件,因为他支持eval一些自定义方法来进行细粒度的判断
class Admin::Listings < ApplicationController require_role "contractor" require_role "admin", :for => :destroy # don't allow contractors to destroy # leverage ruby to prevent contractors from updating listings they don't have access to. require_role "admin", :for => :update, :unless => "current_user.authorized_for_listing?(params[:id]) " ... end "
经过修改,扩展出这种形式的调用:
@user.can_{action}_{controller}?
@user.can_{action}_{controller}?(@target)
以便在View能做更细致的布局
详细可参考以前写的测试例子:
http://www.javaeye.com/post/409317
goodforlife
2008-07-31
我大致上看了一下你的思想,感觉做一般的小系统还过得去.
我想看看你的源码啊.
我想看看你的源码啊.
reeze
2008-07-31
现在也很头疼这个问题。。要这针对某个资源进行访问控制。普通的基于权限的方式不是记恨有效。比如一个群组,可以设置访问权限,然后管理员 ,组成员,非组员的控制很不DRY,也很分散。。不知道有没有比较灵活的解决办法~
universac
2008-07-29
rainchen 写道
你怎么控制粒度精确到对资源的操作?
如A建立的POSTS,B能看不能删,C是版主,能看有能删
如A建立的POSTS,B能看不能删,C是版主,能看有能删
我现在头疼的也是这个,不光光基于角色,想把对资源的访问也统一控制,一直没有办法,现在都是分散在各个地方。不知道有谁有这方面的经验
qichunren
2008-07-29
引用
你怎么控制粒度精确到对资源的操作?
如A建立的POSTS,B能看不能删,C是版主,能看有能删
如A建立的POSTS,B能看不能删,C是版主,能看有能删
不知道你说的是不是:
你是说对于某个特定的用户创建的资源的权限控制吗?我做的这个不能达到这个要求.
如果只有让B能看不能删posts,让C能看又能删posts,那可以通过我的这个控制.
不知道对于你说的针对某个特定的资源(在我我先暂且理解为table中的一条记录)是如何控制每个用户对其的权限控制,有什么好的方法没有??
rainchen
2008-07-17
你怎么控制粒度精确到对资源的操作?
如A建立的POSTS,B能看不能删,C是版主,能看有能删
如A建立的POSTS,B能看不能删,C是版主,能看有能删
phoenix520
2008-07-17
qichunren 写道
phoenix520 写道
这个是用户角色资源的3层结构?我们现在使用的是用户角色权限资源的4层结构,但很多时候觉得多了那么一层,哪种结构更加合理一点呢?
说来听听呢!具体的是什么样子的呢?有什么优点?
例如人力资源部这个角色可以看到人力资源部的相关资源,财务部的角色可以看到财务部的相关资源,总经理工作部这个角色可以同时看到所有部门的资源,如果用3层结构,角色直接关联资源,那么关联总经理工作部资源的时候就会把人资部和财务部的资源再关联给总经部,会产生一些重复工作,当然也可以给总经部用户授予人资部和财务部的两个角色,不过这样并不是很直观,如果采用4层结构,财务部角色对应财务部权限,再对应财务部资源,总经部角色对应财务部权限加人资部权限,再对应相关资源,这样子可能会减少些赋权的工作量。
qichunren
2008-07-16
phoenix520 写道
这个是用户角色资源的3层结构?我们现在使用的是用户角色权限资源的4层结构,但很多时候觉得多了那么一层,哪种结构更加合理一点呢?
说来听听呢!具体的是什么样子的呢?有什么优点?
superxielei
2008-07-16
我现在使用的是三层的,并没有权限这一层,这个应该是不同的项目有不同的需求吧。
应该是四层的更完善一点,但应该是可以配置的。
应该是四层的更完善一点,但应该是可以配置的。
phoenix520
2008-07-16
这个是用户角色资源的3层结构?我们现在使用的是用户角色权限资源的4层结构,但很多时候觉得多了那么一层,哪种结构更加合理一点呢?
superxielei
2008-07-16
说错了。还是删了吧!!
发表评论
提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则
- 浏览: 9306 次
- 性别:

- 来自: 与JE一起成长

- 详细资料
搜索本博客
我的相册
qq.png
共 4 张
共 4 张
最近加入圈子
链接
- 蕲春人
- 数据库模型分享
- JAVA项目网
- 关于ror的博客
- http://groovie.org/
- Ruby语言思想驱动
- dzone
- 喜道技术笔记
- 铁道播客
- Agile Web Development
- ror开源一看
- 中国onrails社区
- Rails2中文站
- rails and ruby
- Err the Blog
- http://zilkey.com/
- Rails2 API
- Typo Blog
- Rails2.1 API
- 海阳的新博客
- Ruby中文门门
- Rails视频
- Rails Engin
- Railslodge
- http://davidsmalley.com/
- http://www.railsenvy.com/
- http://www.railway.at/
- LetRails
- 外国模块网
- Devint ART
- Smashing Magazine
- Csscreme
- topcsstemplates
- CSS库
- Urban Puddle
- SEO on Rails
- RailsExpress.blog
- BenCurtis.com
- 免费CSS模板
- dianeyu
- 剌洪利的博客
- CSS Zen Garden CSS Demo
- Ajax Daddy
- English Chat
最新评论
-
互联网创业是程序员腾达的 ...
hunter.wxhu 写道 又一个偏执狂,想象很美好,时机很现实, 成功的机会 ...
-- by qichunren -
互联网创业是程序员腾达的 ...
又一个偏执狂,想象很美好,时机很现实, 成功的机会很少啊 。技术只是成功的一个要 ...
-- by hunter.wxhu -
互联网创业是程序员腾达的 ...
想要互联网创业,作为程序员一个人想创业,我是不赞成的,这是因为我们思维的问题,除 ...
-- by jhj823900 -
互联网创业是程序员腾达的 ...
bayers 写道 创业教程初级班秘籍之一: 因为发现了确定的可以赚到钱的可行 ...
-- by gigix -
互联网创业是程序员腾达的 ...
『创业家园』 [经验交流]创业实战初级班教程 zt http://cache.t ...
-- by bayers






评论排行榜