On the conceptual side, look into role based authorization, and make sure authorization and authentication are not too tightly connected. This is an easy distinction to make, and will keep things more more flexible in the future.

Here's how role based authz works: each user is a member of any number of groups, each representing a role that the user can take part in (administrator, regular user, moose hugger), and each page or area in the app simply has guards before each action (the way you manage that is dependent on your web app framework - i don't know CGI::Application) which require a certain role. (under more complicated schemes groups could contain or inherit from each other).

The session info contains the ID of the logged in user, and the check for roles should be dynamic (so that the session doesn't have to be fried if the user's role changes).

The code that actually requires authentication should say something like

$authorization_obj->assert_role($user_id, "role_name"); # note that th +is object knows nothing about usernames/passwords - it assumes the us +er is a known user
and then an exception should be thrown, going to an error handler instead of the normal code.

An error handler around the actions should check to see if there is a login error, and redirect the user to the login page.

If you want finer granularity, you can add exception handlers with higher locality to your application areas, but try very hard to keep things simple - if too much complexity finds it's way into the authentication system people will be sad.

After you've made sure parts are locked out to users who shouldn't be touching them, you can start hiding irrelevant parts from the user in order to keep the interface cleaner. For this you should have a check_role method in addition to an assert_role method that doesn't throw exceptions, but just returns a true/false value.

On the authentication side - your login handler should just check credentials and mark the logged in ID in the session. But this should have no implication whatsoever on what the user can do!

In your code you are on the right track on making sure authorization happens all the time, but return $self->session->param('logged-in'); is just not an abstract enough check. In addition, throwing an exception will assure that the code after the exception will not occur, up to the caller's closest eval boundry - this is an easy way to be sure you're not accidentally running code that shouldn't be run.

-nuffin
zz zZ Z Z #!perl

In reply to Re: User authorization and design of larger web/intranet applications. by nothingmuch
in thread User authorization and design of larger web/intranet applications. by techcode

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.