jck has asked for the wisdom of the Perl Monks concerning the following question:

For many years, I have been using Randall Schwartz's script to password protect an area of our organization's website. Recently, members have requested that we post links to PDF files that are confidential for member's eyes only. But, obviously, if I just put the link to the file into one of our protected pages, there's nothing to stop someone from sending that link to a nonmember who can access the file by pasting the URL into a browser. I would like members to be able to access the file if their logged in, and not require them to enter another password to unlock the file (ie by password-protecting the file). Can anyone suggest a way for me to check that a member is logged in before loading the file, and redirecting the login page if they aren't logged in? I'm worried about creating a self-referring loop. Thanks, Janaki

Replies are listed 'Best First'.
Re: Protecting a PDF file
by davido (Archbishop) on Apr 26, 2013 at 01:02 UTC

    I remember reading merlyn's article way back when, but have forgotten the gist of it.

    Nowadays I would be using Mojolicious, and set up an auth-bridge in the Mojolicious router. This would allow you to only serve those PDF files to those who have met the criteria that let's them pass through the authorization bridge. Any other (mis)user won't have access.

    There's a little learning curve to Mojolicious, but once you catch on it's so slick you'll be using it all over the place.


      Dave, this looks perfect!! and, i'm sure that it would be better than using this old code that we've relied on so long, but i'm sure is susceptible to hacks. does this also protect pages? i really want to try to stick with allowing anyone who has logged into the "protected" area of our site to have access to everything.
Re: Protecting a PDF file
by jwkrahn (Monsignor) on Apr 25, 2013 at 18:56 UTC

    s/Randall Schwartz's/Randal Schwartz's/

      my apologies to Mr. Schwartz. i was typing on a mobile device, o/w, i would have checked the spelling before submitting.
Re: Protecting a PDF file
by ksublondie (Friar) on Apr 25, 2013 at 19:32 UTC
    I'm not familiar with the script you mentioned, but if you're using Apache, can you configure it in there? Although I didn't set it up myself, that's how we are doing something similar on our intranet.
Re: Protecting a PDF file
by Anonymous Monk on Apr 26, 2013 at 12:13 UTC
    so what authentication mechanism do you use?
    if( loggedIn() ){ if( userIsAllowed() ){ sendPdfFileWithResumingAndAllThat(); } else { errorNotAllowed(); } } else { errorNotLoggedIn(); }
      there's a login page, which checks that a user is registered in our member database, and, if so, sets a session id cookie in SESSID, as well as a userid in TIUID. SESSID is generated using:
      my $sessid = join("", @chars[ map { rand @chars } (1 .. 20) ]);
      then, every page that is password-protected has the following at the top:
      my $q = new CGI; my $sessid = $q->cookie('SESSID'); my $UIDuser = $q->cookie('TIUID'); my %in = map { $_ => $q->param($_) } $q->param; if (!$sessid) { print $q->redirect("http://mydomain.org/memberarea/login/"); exit; } my $cookie = $q->cookie(-name=>"SESSID", -value=> $sessid, -expires => + "+2h", -domain=> '.mydomain.org'); print $q->header({-type=>"text/html", -charset=>"utf-8", -cookie=>$coo +kie}); my $pagetitle; my $dbh = DBI->connect('DBI:mysql:sitedatabase;host=localhost;port=330 +6', 'ouradminname', 'oursecretpassword') or die "Couldn't open database: $DBI::errstr; stopped"; my $sql = "SELECT UID, firstname, lastname, role FROM members WHERE lo +ginkey = '$sessid'"; # Prepare the SQL query for execution my $sth = $dbh->prepare($sql) || die "Couldn't prepare statement: $DBI::errstr; stopped"; # Execute the query my $result = $sth->execute || die "Error executing: $DBI::errstr"; if ($result == 0) { print $q->redirect("http://mydomain.org/memberarea/login/"); exit; }
      anyone with an expired or non-existent SESSID is redirected to the login page.