安装地址:git clone git://github.com/stffn/declarative_authorization.git vendor/plugins/declarative_authorization
这里不在svn上面,需要安装git(自己google)
1.在user模型是上加roles字段,该字段存储权限
2.打开application_controller,添加
before_filter :set_current_user
protected
def set_current_user
Authorization.current_user = current_user
end
这个全局的前置过滤器,会把restful authentication的current_user代入到declarative authorization的同名方法current_user中。注意,这两个current_user都是Session对象,里面装载着我们的User对象,这就保证了我们多个页面中可以保存用户的信息。如果restful authentication的current_user为空,declarative authorization就会创建一个匿名的User对象,把它放进declarative authorization的current_user中。它拥有一个role_symbols属性(这就是为什么我们自定义的User模型要添加一个role_symbols方法),值为guest。而guest实质是declarative authorization为我们预设的默认角色,当请求和任何用户都没有关联或当一个用户没有任何角色时被调用。这样就实现了User与Role的关联了。
3.打开users_controller,开启控制器级别的访问控制。
class UsersController < ApplicationController
filter_access_to :all
filter_access_to [:show, :edit, :update], :attribute_check => true
#………………
end
这里涉及到两个名词:
粗粒度与细粒度。
粗粒度:表示类别级,只检查对象的类别(Class),而不追究其某一个特定的实例。
细粒度:表示实例级,即需要考虑具体对象的实例(Instance)。比如,只有本人才能查看与编辑自己的用户资料。这个我们通过比较ID或某个特定的属性可以实现,因此:arrtibute_check => true(开启属性检查)就是为这准备的。
更绝的是我们还可以开启模型级别的访问控制,系统就会根据你的权限重写查询指令,防止数据被非法操纵。
4.为了实现授权规则与业务逻辑相分离,declarative authorization指定把所有的授权规则都定义到一个配置文件中,并为我们提供专门的DSL来编写授权规则。首先,我们得把\vendor\plugins\declarative_authorization目录下的样本authorization_rules.dist.rb复制到config目录下,并更名为authorization_rules.rb。打开authorization_rules.rb
authorization do
role :guest(guest角色,默认) do
has_permission_on :users(作用于模型), :to => [:read_index,:create](允许执行的action)
end
role :wikier(角色名称) do
includes :guest
has_permission_on :users, :to => [:read_show,:update] do
if_attribute :id => is {user.id}
end
end
role :providence_breaker do
has_permission_on :users, :to => :manage
end
end
privileges do
privilege :manage, :includes => [:create, :read, :update, :delete]
privilege :read, :includes => [:index, :show]
privilege :read_index, :includes => :index
privilege :read_show, :includes => :show
privilege :create, :includes => :new
privilege :update, :includes => :edit
privilege :delete, :includes => :destroy
end
5. 在控制器加上这个方面,权限不通过时跳到知道页面
protected
def permission_denied
respond_to do |format|
format.html { redirect_to '/403' }
format.xml { head :unauthorized }
format.js { head :unauthorized }
end
end
最后,User模块通常是应用程序最重要的地方,编辑删除等操作一般只能由管理员来执行,用户就算能抵及这种敏感的地带,也一般是一个被阉割了的编辑界面。例如User模型中的login与password用来让用户登录程序,一般是不让修改,所以我们在表单中disabled了这个域,密码更是用了SHA1 加密,不可反向破译,干脆不提供修改。为了保护User模型大部分字段的安全,我们还用了“白名单”;这个restful_authentication插件已经为了我们做了,但roles字段是我们后来添加的,我们得动手修改一下。在User模型的 attr_accessible方法的最后添加上roles便是,即:
attr_accessible :login, :email, :name, :password, :password_confirmation,:roles
再在模型中添加以下代码(超重要)
def role_symbols
@role_symbols ||= (roles || []).map {|r| r.to_sym}
end