Authorizations systems
and Be9's Acl 9
Authorization
vs
Authentication
Authentication is veryfying who you are.
Authorization is saying what you can do.
Types of Authorization
● Clearance based.
● Users have clearance flags and objects have a
clearance type.
● Naïve – checks flags without knowledge of user
relationships
● Easier administration
Types of Authorization(Cont)
● Object based
● Users are related to the object. (Owner of, editor of
etc.)
● Relationships are recorded by the object.
● Highly secure due to permissions being explicity
declared.
● Requires a large amount of administration.
Types of Authorization(Cont)
● Role Based
● Roles relate users to actions. Actions may be
related to a particular object.
● Roles allow for meaningful grouping of actions and
objects.
● Roles map intuitively to types of user, and can often
be planned for free in development.
– “As a <role> I want to edit widgets”.
●
When should I implement roles?
● As soon as you think they're going to be in the
application.
● Implemented early it's easy to add them and
will better define your thinking about the
application.
● Lets you know which parts of the site need
polishing up for external users etc.
How should I implement roles?
● Not with Be9's ACL9
● A good portion of the time you just need a few
global roles.
● Where possible just use a role field in the user
model.
– If current_user.role == 'admin'
● Use Be9's when you need more control over
permissions groups and object relationships.
Be9's ACL9
● A powerful role management system for rails.
● Provides syntax and handlers for relating roles
to objects and actions.
● Consistently deal with roles and relations.
● Multi-table solution allows system to apply roles
to objects or classes quickly.
Getting started.
● Install as a plugin or gem from
[Link]
● Get some kind of authentication system that
includes current_user.
●
Setup database
create_table "roles", :force => true do create_table "roles_users",
|t|
:id => false, :force => true do |t|
[Link] "name", :limit => 40
[Link] "user_id"
[Link] "authorizable_type",
[Link] "role_id"
:limit => 40
[Link] "created_at"
[Link] "authorizable_id"
[Link] "updated_at"
[Link] "created_at"
End
[Link] "updated_at"
end
Don't forget indexes.
acts_as_*
● acts_as_authorization_subject
● acts_as_authorization_object
Options
● :default_role_class_name => 'Role',
● :default_subject_class_name => 'User',
● :default_subject_method => :current_user,
● :protect_global_roles => true
Adding and Removing Roles
● Add role with user.has_role!(role, object = nil)
● Specify a role and optionally an object or class the user
has that role on.
● Remove role with user.has_no_role!(role, object =
nil)
● Remove roles on an object with
user.has_no_roles!(object)
● Remove all roles with user.has_no_roles!
Checking if a user has roles.
● User.has_role?(role, object = nil)
● Checks role and optional object
● User.has_roles_for?(object)
● Checks for any roles on that object
● Most of these methods have an object version
such as object.accepts_role(role, subject).
Finding roles.
● user.role_objects
● user.roles_for(object)
● user.roles_for(class)
● I use this in conjunction with:
user.roles_for(class).map(&:authorizable)
●
●
Access Control
Authorization occurs from a block in the controller
feature allow and deny statements.
access_control do
allow :manager
deny :peon
end
Access Control(cont)
Allow :manager, :to => [:index, :create]
deny :manager, :except => [:index, :create]
Access Control(cont)
● Can also check role relations to variables.
● Set the variable in a before_filter
● Allow :manager, :of => @widget, :to => :edit
● :of is aliased lots for more gooder english. You can
use: :of, :at, :on, :by, :for, :in
Access Control(cont)
● You can also add :if or :unless to the end of
access control statements.
● Allow :manager, :to => :update, :if => :gives_raise
def gives_raise
params[:salary] > @[Link]
end
● Methods must return true or false.
Access Denied
● Catch Acl9::AccessDenied errors in the
controller with rescue_from.
● Often worth catching these conditionally in the
controller for specific access problems and then
raising to a generic block in the
application_controller.