Rails2 的授权认证

用了Rails2 以后,所有的东西都要去寻求插件帮助了, 在网上找了篇文章,好像还是挺有用的。我在本地使用act_as_authenticated 插件和Role_requirement插件还是配置成功了的

 

关键词: authorization(授权认证) authentication(登录认证) role based authorization Role Requirement Role Based Access Control (RBAC)

相关链接:
http://anonymouse.org/cgi-bin/anon-www.cgi/http://www.bencurtis.com/archives/2007/06/user-roles-in-rails-applications/
http://wiki.rubyonrails.com/rails/pages/Authentication+and+Security+Plugins
http://code.google.com/p/rolerequirement/
http://active-rbac.rubyforge.org/
http://wiki.rubyonrails.org/rails/pages/ActiveRBAC
http://active-rbac.rubyforge.org/
http://rubyforge.org/projects/activeacl/
http://www.billkatz.com/authorization(Authorization Plugin 详解)
http://railsforum.com/viewtopic.php?pid=2329
http://agilewebdevelopment.com/plugins/search?search=role
http://blog.wolfman.com/articles/2006/05/20/role-based-authentication-admin-page
http://www.writertopia.com/developers/authorization (Authorization Plugin 使用说明 Version 1.0 (Sept 13, 2006))
http://technoweenie.stikipad.com/plugins/show/Acts+as+Authenticated

other tips:

(较长,略)


my tips:

ActiveRBAC :
太复杂,要建立9个表!

Authorization plugin:
可配合已有登录系统使用,但需要登录系统提供一个current_user 方法(取当前已登录的用户对象)作为接口(可在ApplicationController中自定义)
每个角色需要建立一个表?from http://www.billkatz.com/authorization
语法怪异,但功能比较丰富
支持:only,:except等选项。
支持无数据库调用hardwired模式(AUTHORIZATION_MIXIN='hardwired')
支持acts_as_authorizable as well as acts_as_authorized_user:
user.has_role? 'member', Group
支持单表继承来实现多态
先在controller中设置基本权限,然后在每个action里细分权限:
class MeetingController < ActionController::Base
    permit "registered", :except => :public

    def public
      # Anybody can access this action
    end
  
    def list
      # Any "registered" user can access this action.
      ...
    end
  
    def add_item
      # Only moderators of this meeting or a user who is an admin can add items.
      permit "moderator of :meeting or admin", :meeting => Meeting.find(params[:id]) do
        ...
      end
    end

    def edit
      # Editing is limited to the admin of this meeting or users who have a global admin role.
      @meeting = Meeting.find(params[:id])
      if permit? "(admin of :meeting) or admin"    # Note that no :meeting hash is provided, so @meeting is used.
        # Do editing
      end
    end

    protected
    # 非公开action的保护方法
    def remove_moderator
      # 只允许 对象所有者 或者 管理员
      permit "admin of :meeting or admin"
      ...# do remove process
      # 删除对象后 移除 对象权限的关联
      permit_set "not moderator of :meeting", :user => @removed_member
    end
end

The difference between permit and permit? is redirection. permit redirects by default. permit? can be used within expressions and does not redirect by default.


User engine :
配置复杂,而功能却简单,只做到controller/action级别的限制,但有不错的view helper方法,如 link_if_authorized(controller, action),authorized?(controller, action)


RoleRequirement :
http://code.google.com/p/rolerequirement/
需先安装acts_as_authenticated 插件,(会覆盖掉unknown action)
添加两个表:roles和users_roles (通过生成器生成,名字可配置),
可建立role 或roles 两种不同关联(has_one :role 或has_many :roles),roles可以配置为enum column
权限直接在controller里设置(应该可扩展出把权限保存到数据库了,读出时覆盖controller里的默认设置),
有has_role?('admin')的辅助方法,
核心方法(controller instance method)user_authorized_for?(user_object, params = {:controller=>"user", :action=>"edit"})
view的辅助方法有:url_options_authenticate?({:controller=>"user", :action=>"edit"})
可扩展出@user.authorized_for?("/user/edit") (再尝试扩展出动态方法:@user.can_{action}_{controller}? )
似乎可扩展出object级别的限制(Business Object Permissions ):require_role "admin", :only => :update, :unless => "current_user.authorized_for_listing?(params[:id]) "
用法类似before_filter,可添加only和except来指定排除:
#   * :only - Only require the role for the given actions
#   * :except - Require the role for everything but
#   * :if - a Proc or a string to evaluate.   If it evaluates to true, the role is required.
#   * :unless - The inverse of :if

class Admin::Listings < ApplicationController
   require_role "contractor"
   require_role "admin", :only => :destroy # don't allow contractors to destroy
end

步骤:
1.分别安装acts_as_authenticated rolerequirement
# rolerequirement的用法在README,在线的wiki没用
2.用acts_as_authenticated的generator生成user model和user controller:
#script/generate authenticated UserModelName UserControllerName
script/generate authenticated user users
(rolerequirement需要一个current_user方法做接口,如果上面生成的UserModelName不是"user",如是"person",则需要在ApplicationController里alias一个同名方法,如 alias :current_user :current_person)
# UsersController 会添加4个action: index login signup logout

#2.2 执行rake db:migrate
3.用rolerequirement的generator生成role model(留意生成完后有提示,会修改user model及ApplicationController的代码 http://code.google.com/p/rolerequirement/wiki/WhatTheGeneratorsDo):
#script/generate roles RoleModelName UserModelName
script/generate roles role user
#3.2 执行rake db:migrate
4.添加权限限制到controller中
class RolesController < ApplicationController
   scaffold :role
   require_role "admin"
end
5.在console里添加一个role到user
user = User.find(:first)
role = Role.find_or_create_by_name "admin"
user.roles << role unless user.roles.any?{ |r| r.name == role.name }
# 默认在User model里的has_role?方法总是返回true,如果user里有'admin' role


Active Acl:
基于 phpgacl的设计;使用polymorphic(因此需要安装has_many_polymorphs 插件) 做关联(一般都是用habtm)。封装了网状查询,只用一条SQL就能得到所有的权限数据;调用方法: current_user.has_permission?(User::LOGIN) and object level (3D, like admin.has_permission?(Forum::ADMIN, :on => team_forum)) ,设置太复杂

ACL System:
http://agilewebdevelopment.com/plugins/acl_system
可配合已有的登录系统使用,需要current_user 方法作为接口(若要改变则要hack源码),需要一个role model,且有个title属性(若要改变则要hack源码),并在user中设置habtm联系,代码也很简单。(评分挺高 Rating: 4/5 (42 votes))
没有user.has_role?('admin')这样的辅助方法
不支持直接判断controller和action,如 user.can_access?(controller, action)

需添加两个表:roles和roles_users(注意表名),权限直接在controller里设置,主要是access_control,但还要显式的与before_filter :login_required配合使用,比较麻烦:
class PostController < ApplicationController
   before_filter :login_required, :except => [:list, :index]
   access_control [:new, :create, :update, :edit] => '(admin | user | moderator)',
                  :delete => 'admin & (!moderator & !blacklist)'
end

class PostController < ApplicationController
   before_filter :login_required, :except => [:list, :index]
   access_control :DEFAULT => '!guest' ,
                  [:new, :create, :update, :edit] => '(admin | user | moderator)',
                  :delete => 'admin & (!moderator & !blacklist)'
end

在view中用法:
<% restrict_to "(admin | moderator) & !blacklist" do %>
   <%= link_to "Admin & Moderator only link", :action =>'foo' %>
<% end %>

<% if permit? "(admin | moderator) & !blacklist" %>
you can ...
<% else %>
you can't ...
<% end %>


access_control :
使用较麻烦,用法类似linux的权限控制(rwx),让人迷糊,部分功能未完成:
class AdminController < ApplicationController
   authorize "admin:rw"
   authorize "admin:x", :only => :special_action
  
   def index
     ...
   end

   def special_action
     ...
   end
end

 

最后选择了RoleRequirement,并扩展实现了:
@user.can_{action}_{controller}?

如:
@user.can_edit_post?

下一步:model security,如:
@user.can_edit_post?(@post)

转载于:https://my.oschina.net/cometlj/blog/307946

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值