Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

OT: WebApp Authorization Question

by jimbus (Friar)
on May 05, 2006 at 18:27 UTC ( #547719=perlquestion: print w/ replies, xml ) Need Help??
jimbus has asked for the wisdom of the Perl Monks concerning the following question:

This is methodology related more than Perl related, but I'm using Perl to impliment and PerlMonks is one of the best communities I've ever been a part of... so here it goes.

Bishop Summary: I'm having issues getting my head wrapped around the authorization patterns and would appreciate any input or pointers to documents that discuss this. I've done webapps and document management for many years, but the rules of engagement have always been dictated by the customer or the software. This is my first time at designing authentication from the ground up.

My applications will fall into three basic catagories:

  • System report and documentation: I've got various Perl scripts digesting billing and log files from several system to give us usage stats. There will also be disaster recovery aspect to this, documenting the system's location, functionality and recovery process.
  • Document management: I'd like to use lucene to create search engine/knowledge based to find documents.
  • Process management: A ticketing/issue tracking system, outage/maintenance documents... And there will be some overlap.

    Pretty basic stuff, were it gets more complicated for me is the authorization. Parts of this will be segregated by department and some sections will be by person, but it will be all role based.

    At a page/webapp level, I figured it would be pretty easy. I would just pass the authenticated name and required role for the page against the user roles db and redirect if it failed.

    The first area I get overwhelmed is the menuing. I've got the main menu in a strip across the top and then menus downthe right side for the app, user role and quick links. Except for the main menu which will be fairly static, I'd like to build/maintain the context sensitive side menus from a DB.

    The other issue I have is the knowledge base. How do I build a document db with lucene, but tell the search engine that only certain roles can see certain docs?

    I know TIMTOWTDI, but... and this seems to be a common thread to my posts... there seems to be patterns and best practices that everyone seems to know but me :).


  • --Jimbus aka Jim Babcock
    Wireless Data Engineer and Geek Wannabe
    jim-dot-babcock-at-usa-dot-com

    Comment on OT: WebApp Authorization Question
    Re: OT: WebApp Authorization Question
    by derby (Abbot) on May 05, 2006 at 18:39 UTC

      jimbus,
      Sorry I can't help with most if this ... but

      The other issue I have is the knowledge base. How do I build a document db with lucene, but tell the search engine that only certain roles can see certain docs?

      The way we handle that is to pass an extra search param that reduces the result set to that role. For instance, to return all docs containing the word bar that only the foo department can see, your query may look like this: dept:foo AND all:bar.

      You just need to ensure there's no back doors into your search and that all queries pass the appropriate role param.

      -derby

      Update:Forgot to mention it but just as important you would need to create your index with those role appropriate fields.

    Re: OT: WebApp Authorization Question
    by hesco (Deacon) on May 06, 2006 at 07:52 UTC
      These days I'm using CGI::Application, with CGI::Application::Plugin::Authentication and Authorization. There is a lot that those two modules can offer you. I adapt the user/group/roles schema offered by Auth and Authz so that it is compatible with DBIx::UserDB and DBIx::GroupDB. Throw in CGI::Session for handling the authentication tokens across requests and its about handled. Together these five modules seem to provide all I ever needed for a web-resource privilege and access control system. I still haven't sorted out how to store and test against encrypted passwords, but that is on my todo list.

      Apparently this system is far more flexible than the sample code below from a project I'm developing, permitting LDAP, ip-based filters, etc., etc.

      Understand that unless your connection is encrypted, that passwords are subject to man-in-the-middle sniffing attacks. Even if you store them encrypted on your server, they'll come at port 80 in clear text.

      -- Hugh

      use warnings; use strict; use base 'CGI::Application'; use CGI::Application::Plugin::Session; use CGI::Application::Plugin::Authentication; use CGI::Application::Plugin::Authorization; use CGI::Application::Plugin::Authentication::Driver::Filter::md5; . . . DistroPrsRls_www->authen->config( DRIVER => [ 'DBI', DBH => $authdb, TABLE => 'userdb', CONSTRAINTS => { 'userdb.username' => '__CREDENTIAL_1__', 'userdb.password' => '__CREDENTIAL_2__' }, ], STORE => 'Session', CREDENTIALS => [ 'authen_username','authen_password' ], LOGIN_SESSION_TIMEOUT => { IDLE_FOR => '15m', EVERY => '1h' }, ); DistroPrsRls_www->authz->config( DRIVER => [ 'DBI', DBH => $authdb, TABLES => ['userdb', 'groupmembers', 'groupdb'], JOIN_ON => 'userdb.uid = groupmembers.uid AND groupdb.gid = grou +pmembers.gid', USERNAME => 'userdb.username' , CONSTRAINTS => { 'groupdb.groupname' => '__PARAM_1__', } ], ); DistroPrsRls_www->authz('dpradmin')->config( DRIVER => [ 'DBI', DBH => $authdb, TABLES => ['userdb', 'groupmembers', 'groupdb'], JOIN_ON => 'userdb.uid = groupmembers.uid AND groupdb.gid = grou +pmembers.gid', USERNAME => 'userdb.username' , CONSTRAINTS => { 'groupdb.groupname' => '__PARAM_1__', } ], ); DistroPrsRls_www->authen->protected_runmodes(qr/^(login_|admin_|dpr_)/ +);
      if( $lal && $lol ) { $life++; }
    Re: OT: WebApp Authorization Question
    by CountZero (Bishop) on May 06, 2006 at 12:54 UTC
      For difficult authorization problems, nothing beats an Access Control List in my opinion.

      Catalyst together with Catalyst::Plugin::Authorization::ACL is my preferred solution.

      CountZero

      "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

    Re: OT: WebApp Authorization Question
    by ryantate (Friar) on May 07, 2006 at 21:27 UTC
      How do I build a document db with lucene, but tell the search engine that only certain roles can see certain docs?

      When I encountered this issue with Plucene, a Perl port of Lucene, I simply included a "userids" field with each document, which was a space-separated list of the id numbers of users allowed to see that document.

      I had to make sure my Plucene tokenizer class considered numbers a word constituent rather than word boundary, which was not the default.

      Then, when the user performed a search, my script would programmatically add a clause requiring that the user's user_id be present in that documents userids field. This was done using various classes and methods of Plucene; I did NOT just concatenate to the search string, which could have some issues. That said, what I did is roughly the same as adding " AND userid:5" to each search.

      In your case, you could have a similar field, called "role_ids".

        When I encountered this issue with Plucene, a Perl port of Lucene, I simply included a "userids" field with each document, which was a space-separated list of the id numbers of users allowed to see that document.

        The only concern with this mechanism is the ease of updating the "userids" field. If the user list changes often, this becomes a lot of work to maintain.

        That said, what I did is roughly the same as adding " AND userid:5" to each search.

        On the other hand, if you have your search compare the permissions associated with the userid to those allowed (and have dealt with the possible problems of spoofed messages), then you're right, it becomes a relatively simple, easily maintained db.

        (Note: I'm utterly unfamiliar with lucerne or the actual tools you've used. The above comments are what came to mind as a programmer, considering the question posed).
    Re: OT: WebApp Authorization Question
    by jimbus (Friar) on May 08, 2006 at 13:37 UTC

      Thanks for all your input, especially on the Plucene parts, but I'm not looking for products and packages, I'm looking for pattern theory and methodology.

      I'll send this out to the mason mailing list and see what input I get there.

      Thanks! :)


      --Jimbus aka Jim Babcock
      Wireless Data Engineer and Geek Wannabe
      jim-dot-babcock-at-usa-dot-com
    Re: OT: WebApp Authorization Question
    by exussum0 (Vicar) on May 08, 2006 at 16:16 UTC
      On security, make it transparent as possible. Create classes that implement the overall picture, piece by piece. For instance, a "forgot password" class would do a bit of work to either grab your email address or username and mail out a password.

      But these classes would never do silly things like call CPAN packages directly for doing email or database calls. Usually not. They should call an API that you design to do these things. Something similar to $user = $api->get_user({id=>$id});  $api->mail_password({user=>$user}); Then you need to use either the facility of your language or your api, to deal with security. It should be VERY light weight and pluggable. Why? Testing is hard. Really hard. Switching gears by adding new authentication schemese is hard as well. Or providing new schemes, like single-signon, RSA keys, browser certs. Think of it as hard as swapping DBs. At least with databses, and a user-written API, you can swap DBs without disrupting all those classes that implement the overall picture. :)

      I could imagine something simple like, using the perl autoloader to act as a transparent proxy to your api calls. So you could do something like:

      Exussum::SecureApi->set_api("Exussum::Api"); $api = Exussum::SecureApi->new(); $api->set_ser("exussum"); $api->set_password("admin-password"); $api->deposit("X932323",5000,"USD"); $api->transfer("X932323","X812812",20,"USD");
      If for some reason, a day I don't want to use my Exussum::Api, and use some sorta test api that doesn't do real work, I may feed my SecureApi, Exussum::TestApi.

      It's a lot to take in. A hell of a lot. Summed up, some things, like DB access, security, cross-cutting visual design (think left bar, top banner, w/ a logo and colour scheme via CSS), usually should be very lightweight. Otherwise, you tie yourself down to the underlying technology with unusally specific, rigid requirements.

    Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Node Status?
    node history
    Node Type: perlquestion [id://547719]
    Approved by NetWallah
    Front-paged by Arunbear
    help
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others making s'mores by the fire in the courtyard of the Monastery: (5)
    As of 2014-08-31 04:12 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      The best computer themed movie is:











      Results (294 votes), past polls