X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Manual.git;a=blobdiff_plain;f=lib%2FCatalyst%2FManual%2FTutorial%2FTutorial%2FAuthorization.pod;fp=lib%2FCatalyst%2FManual%2FTutorial%2FTutorial%2FAuthorization.pod;h=0000000000000000000000000000000000000000;hp=9af1ce3452f8fcac54f12b992c10b4683e068b33;hb=5e6026272f809951ac22fae43b73d2c1dc79c7fc;hpb=d442cc9fbdf45a28fe02f13552f44e3e2f7ec22e diff --git a/lib/Catalyst/Manual/Tutorial/Tutorial/Authorization.pod b/lib/Catalyst/Manual/Tutorial/Tutorial/Authorization.pod deleted file mode 100644 index 9af1ce3..0000000 --- a/lib/Catalyst/Manual/Tutorial/Tutorial/Authorization.pod +++ /dev/null @@ -1,413 +0,0 @@ -=head1 NAME - -Catalyst::Manual::Tutorial::Authorization - Catalyst Tutorial - Part 5: Authorization - - -=head1 OVERVIEW - -This is B for the Catalyst tutorial. - -L - -=over 4 - -=item 1 - -L - -=item 2 - -L - -=item 3 - -L - -=item 4 - -L - -=item 5 - -B - -=item 6 - -L - -=item 7 - -L - -=item 8 - -L - -=item 9 - -L - -=back - - - -=head1 DESCRIPTION - -This part of the tutorial adds role-based authorization to the existing -authentication implemented in Part 4. It provides simple examples of -how to use roles in both TT templates and controller actions. The first -half looks at manually configured authorization. The second half looks -at how the ACL authorization plugin can simplify your code. - -You can checkout the source code for this example from the catalyst -subversion repository as per the instructions in -L - -=head1 BASIC AUTHORIZATION - -In this section you learn how to manually configure authorization. - -=head2 Update Plugins to Include Support for Authorization - -Edit C and add C to the list: - - use Catalyst qw/ - -Debug - ConfigLoader - Static::Simple - - StackTrace - - Authentication - Authentication::Store::DBIC - Authentication::Credential::Password - Authorization::Roles - - Session - Session::Store::FastMmap - Session::State::Cookie - /; - - -=head2 Add Config Information for Authorization - -Edit C and update it to match (everything from the -"authorization:" line down is new): - - --- - name: MyApp - authentication: - dbic: - # Note this first definition would be the same as setting - # __PACKAGE__->config->{authentication}->{dbic}->{user_class} = 'MyAppDB::User' - # in lib/MyApp.pm (IOW, each hash key becomes a "name:" in the YAML file). - # - # This is the model object created by Catalyst::Model::DBIC from your - # schema (you created 'MyAppDB::User' but as the Catalyst startup - # debug messages show, it was loaded as 'MyApp::Model::MyAppDB::User'). - # NOTE: Omit 'MyApp::Model' here just as you would when using - # '$c->model("MyAppDB::User)' - user_class: MyAppDB::User - # This is the name of the field in your 'users' table that contains the user's name - user_field: username - # This is the name of the field in your 'users' table that contains the password - password_field: password - # Other options can go here for hashed passwords - # Enabled hashed passwords - password_type: hashed - # Use the SHA-1 hashing algorithm - password_hash_type: SHA-1 - authorization: - dbic: - # This is the model object created by Catalyst::Model::DBIC from your - # schema (you created 'MyAppDB::Role' but as the Catalyst startup - # debug messages show, it was loaded as 'MyApp::Model::MyAppDB::Role'). - # NOTE: Omit 'MyApp::Model' here just as you would when using - # '$c->model("MyAppDB::User)' - role_class: MyAppDB::Role - # The name of the field in the 'roles' table that contains the role name - role_field: role - # The name of the accessor used to map a role to the users who have this role - # See the has_many() in MyAppDB/Role.pm - role_rel: map_user_role - # The name of the field in the user_role table that references the user - user_role_user_field: user_id - - -=head2 Add Role-Specific Logic to the "Book List" Template - -Open C in your editor and add the following -lines to the bottom of the file: - -

Hello [% Catalyst.user.username %], you have the following roles:

- -
    - [% # Dump list of roles -%] - [% FOR role = Catalyst.user.roles %]
  • [% role %]
  • [% END %] -
- -

- [% # Add some simple role-specific logic to template %] - [% # Use $c->check_user_roles() to check authz -%] - [% IF Catalyst.check_user_roles('user') %] - [% # Give normal users a link for 'logout' %] - Logout - [% END %] - - [% # Can also use $c->user->check_roles() to check authz -%] - [% IF Catalyst.check_user_roles('admin') %] - [% # Give admin users a link for 'create' %] - Create - [% END %] -

- -This code displays a different combination of links depending on the -roles assigned to the user. - -=head2 Limit C to C Users - -C statements in TT templates simply control the output that is sent -to the user's browser; it provides no real enforcement (if users know or -guess the appropriate URLs, they are still perfectly free to hit any -action within your application). We need to enhance the controller -logic to wrap restricted actions with role-validation logic. - -For example, we might want to restrict the "formless create" action to -admin-level users by editing C and -updating C to match the following code: - - =head2 url_create - - Create a book with the supplied title and rating, - with manual authorization - - =cut - - sub url_create : Local { - # In addition to self & context, get the title, rating & author_id args - # from the URL. Note that Catalyst automatically puts extra information - # after the "//check_user_roles('admin')) { - # Call create() on the book model object. Pass the table - # columns/field values we want to set as hash values - my $book = $c->model('MyAppDB::Book')->create({ - title => $title, - rating => $rating - }); - - # Add a record to the join table for this book, mapping to - # appropriate author - $book->add_to_book_authors({author_id => $author_id}); - # Note: Above is a shortcut for this: - # $book->create_related('book_authors', {author_id => $author_id}); - - # Assign the Book object to the stash for display in the view - $c->stash->{book} = $book; - - # This is a hack to disable XSUB processing in Data::Dumper - # (it's used in the view). This is a work-around for a bug in - # the interaction of some versions or Perl, Data::Dumper & DBIC. - # You won't need this if you aren't using Data::Dumper (or if - # you are running DBIC 0.06001 or greater), but adding it doesn't - # hurt anything either. - $Data::Dumper::Useperl = 1; - - # Set the TT template to use - $c->stash->{template} = 'books/create_done.tt2'; - } else { - # Provide very simple feedback to the user - $c->response->body('Unauthorized!'); - } - } - - -To add authorization, we simply wrap the main code of this method in an -C statement that calls C. If the user does not -have the appropriate permissions, they receive an "Unauthorized!" -message. Note that we intentionally chose to display the message this -way to demonstrate that TT templates will not be used if the response -body has already been set. In reality you would probably want to use a -technique that maintains the visual continuity of your template layout -(for example, using the "status" or "error" message feature added in -Part 2). - -B: If you want to keep your existing C method, you can -create a new copy and comment out the original by making it look like a -Pod comment. For example, put something like C<=begin> before C and C<=end> after the closing C<}>. - -=head2 Try Out Authentication And Authorization - -Press C to kill the previous server instance (if it's still -running) and restart it: - - $ script/myapp_server.pl - -Now trying going to L and you should -be taken to the login page (you might have to C your -browser and/or click the "Logout" link on the book list page). Try -logging in with both C and C (both use a password -of C) and notice how the roles information updates at the -bottom of the "Book List" page. Also try the C link on the -book list page. - -Now the "url_create" URL will work if you are already logged in as user -C, but receive an authorization failure if you are logged in as -C. Try: - - http://localhost:3000/books/url_create/test/1/6 - -while logged in as each user. Use one of the 'Logout' links (or go to -L in you browser directly) when you are -done. - - -=head1 ENABLE ACL-BASED AUTHORIZATION - -This section takes a brief look at how the -L -plugin can automate much of the work required to perform role-based -authorization in a Catalyst application. - -=head2 Add the C Plugin - -Open C in your editor and add the following plugin to the -C statement: - - Authorization::ACL - -Note that the remaining C plugins from earlier sections -are not shown here, but they should still be included. - -=head2 Add ACL Rules to the Application Class - -Open C in your editor and add the following B the -C<__PACKAGE__-Esetup;> statement: - - # Authorization::ACL Rules - __PACKAGE__->deny_access_unless( - "/books/form_create", - [qw/admin/], - ); - __PACKAGE__->deny_access_unless( - "/books/form_create_do", - [qw/admin/], - ); - __PACKAGE__->deny_access_unless( - "/books/delete", - [qw/user admin/], - ); - -Each of the three statements above comprises an ACL plugin "rule". The -first two rules only allow admin-level users to create new books using -the form (both the form itself and the data submission logic are -protected). The third statement allows both users and admins to delete -books. The C action will continue to be protected by -the "manually configured" authorization created earlier in this part of -the tutorial. - -The ACL plugin permits you to apply allow/deny logic in a variety of -ways. The following provides a basic overview of the capabilities: - -=over 4 - -=item * - -The ACL plugin only operates on the Catalyst "private namespace". You -are using the private namespace when you use C actions. C, -C, and C allow you to specify actions where the path and -the namespace differ -- the ACL plugin will not work in these cases. - -=item * - -Each rule is expressed in a separate -C<__PACKAGE__-Edeny_access_unless()> or -C<__PACKAGE__-Eallow_access_if()> line (there are several other -methods that can be used for more complex policies, see the C -portion of the -L -documentation for more details). - -=item * - -Each rule can contain multiple roles but only a single path. - -=item * - -The rules are tried in order (with the "most specific" rules tested -first), and processing stops at the first "match" where an allow or deny -is specified. Rules "fall through" if there is not a "match" (where a -"match" means the user has the specified role). If a "match" is found, -then processing stops there and the appropriate allow/deny action is -taken. - -=item * - -If none of the rules match, then access is allowed. - -=item * - -The rules currently need to be specific in the application class -C B the C<__PACKAGE__-Esetup;> line. - -=back - -=head2 Add a Method to Handle Access Violations - -By default, -L -throws an exception when authorization fails. This will take the user -to the Catalyst debug screen, or a "Please come back later" message if -you are not using the C<-Debug> flag. This step uses the -C method in order to provide more appropriate feedback to -the user. - -Open C in your editor and add the -following method: - - =head2 access_denied - - Handle Catalyst::Plugin::Authorization::ACL access denied exceptions - - =cut - - sub access_denied : Private { - my ($self, $c) = @_; - - # Set the error message - $c->stash->{error_msg} = 'Unauthorized!'; - - # Display the list - $c->forward('list'); - } - -Then run the Catalyst development server script: - - $ script/myapp_server.pl - -Log in as C. Once at the book list, click the "Create" link to -try the C action. You should receive a red "Unauthorized!" -error message at the top of the list. (Note that in reality you would -probably want to place the "Create" link code in -C inside an C statement that only displays -the list to admin-level users.) If you log in as C you should -be able to view the C form and add a new book. - -When you are done, use one of the 'Logout' links (or go to the -L URL directly) when you are done. - - -=head1 AUTHOR - -Kennedy Clark, C - -Please report any errors, issues or suggestions to the author. The -most recent version of the Catalyst Tutorial can be found at -L. - -Copyright 2006, Kennedy Clark, under Creative Commons License -(L). -