每天一剂Rails良药之Role-Based Authorization

本文介绍了一种基于角色的权限管理系统实现方式,包括数据库表结构的设计、模型关联定义及控制器中进行权限验证的方法。此外还提供了跳过特定权限检查的方式。
我们的系统往往并不只是靠登录这么简单来控制权限,今天我们来看看基于角色的授权
假设我们的系统已经建立了昨天的users表

1,migration
[code]
class AddRolesAndRightsTables < ActiveRecord::Migration
def self.up
create_table :users_roles, :id => false do |t|
t.column :user_id, :integer
t.column :role_id, :integer
end

create_table :roles, :do |t|
t.column :name, :string
end

create_table :roles_rights, :id => false do |t|
t.column :role_id, :integer
t.column :right_id, :integer
end

create_table :rights do |t|
t.column :name, :string
t.column :controller, :string
t.column :action, :string
end
end

def self.down
drop_table :users_roles
drop_table :roles
drop_table :rights
drop_table :rights_roles
end
end
[/code]

2,model
[code]
class User < ActiveRecord::Base
has_and_belongs_to_many :roles
end

class Role < ActiveRecord::Base
has_and_belongs_to_many :users
has_and_belongs_to_many :rights
end

class Right < ActiveRecord::Base
has_and_belongs_to_many :roles
end
[/code]

3,application.rb
[code]
class ApplicationController < ActionController::Base
layout 'standard'
before_filter :check_authentication,
:check_authorization,
:except => [:signin_form, :signin]
def check_authentication
unless session[:user]
session[:intended_action] = action_name
redirect_to :controller => :admin, :action => signin_form
return false
end
end

def check_authorization
user = User.find(session[:user])
unless user.roles.detect{|role|
role.rights.detect{|right|
right.action == action_name && right.controller == controller_name
}
}
flash[:notice] = "You are not authorized to view the page you requested"
request.env["HTTP_REFERER"] ? (redirect_to :back) : (redirect_to home_url)
return false
end
end
end
end
[/code]

4,layout
[code]
<% if flash[:notice] %>
<div class="errors">
<% flash[:notice] %>
</div>
<% end %>
[/code]

如果我们的某一个controller或者action不想要check_authentication和check_authorization这两个filter,我们可以skip掉:
[code]
class HomeController < ApplicationController
skip_before_filter :check_authentication, :check_authorization
def index
render :text => "A page that doesn't require a signin or any rights"
end
end
[/code]
但这只能精确到controller和action级别的权限控制
如果我们想控制对models实例的访问权限,可以参考Bruce Perens的[url=http://perens.com/FreeSoftware/ModelSecurity]ModelSecurity[/url]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值