Link to home
Start Free TrialLog in
Avatar of Aerocom
AerocomFlag for Sweden

asked on

html/php login form for .htaccess validation

Until Microsoft released their latest security update to IE I used an html form for the user to input his username/password which was passed from javascript as 'username:password@www.htaccessProtectedDirectory/UsernameAsSubdirectory.com'.
This no longer works and although you can change the registry to allow it. The general users will not know how.

When searching for solutions to this problem I came accross so discussions on posting the $username $password to a blank page. The code given was as follows:

html page

<html>
 
 <head>
 <title>Login Page</title>
 </head>
 
 <body>
 
 <form method = post action = "login.php">
         <b> Username <input type = text name = username><br>
         <b> Password <input type = password name = password><br>
         <br>
       <input type=submit name=Login value=Login>
 </form>
 </b>
 </body>
 
 </html>

login.php

<?php
$username = $_POST['username'];
$password = $_POST['password'];
echo "<html>";
echo "<title>Welcome to the Restricted Area</title><head>";
echo "<META HTTP-EQUIV=REFRESH CONTENT=\"0; URL=http://$username:$password@www.myserver/protectecteddirectory/index.htm\">";
echo "</head><body>";
echo "<center><h2>Please Wait .... Login Into the Restricted Area ... </h2>";
echo "</body></html>";
?>

When I try to run this I keep getting a syntax error

As I am getting more and more complaints from users who have made the MS update and can no longer get into the protected area I am looking for some help in getting this problem resilved ASAP

Thanks in anticipation

Rick
Avatar of lozloz
lozloz

instead of:

echo "<META HTTP-EQUIV=REFRESH CONTENT=\"0; URL=http://$username:$password@www.myserver/protectecteddirectory/index.htm\">";

you could try:

echo "<META HTTP-EQUIV=REFRESH CONTENT=\"0; URL=http://" . $username . ":" . $password . "@www.myserver/protectecteddirectory/index.htm\">";

what line is the syntax error on?

and if you wanted to do an immediate redirect with no content, you could do:

<?php
$username = $_POST['username'];
$password = $_POST['password'];
header("Location: http://" . $username . ":" . $password . "@www.myserver/protectecteddirectory/index.htm");
exit;
?>

hope that helps,

loz
Avatar of Aerocom

ASKER

The php error is

Warning: Unexpected character in input: '\' (ASCII=92) state=1 in c:\phpdev\www\login.php on line 3

Parse error: parse error in c:\phpdev\www\login.php on line 3

The same error comes up when I use your line:-

echo "<META HTTP-EQUIV=REFRESH CONTENT=\"0; URL=http://" . $username . ":" . $password . "@www.myserver/protectecteddirectory/index.htm\">";

The immediate re-direct will not work when IE has had this so called 'security fix'

The original article I found on the subject is below

http://www.programmingtalk.com/showthread.php?t=4555

Rick
well the code works fine on my server

try commenting lines out to see where the problem is?

loz
Avatar of gr8gonzo
Ummm, I actually think that this shouldn't work at all. A META Refresh does not bypass the MS Update that took out this ability. All a META refresh does is tell the browser to go to a new URL, so the browser is still doing the request, and if they have the latest update (which I hate, by the way - I wish they would've just come up with a better fix), then you're going to run into problems.

HOWEVER, what you COULD do is change the .htaccess protection so that PHP handles the authentication process instead, and then just pass the username and password in the query string, like http://www.domain.com/php_authentication.php?user=blah&password=secret

.htaccess authentication can only be so secure anyway. I like having more control over the process. I also know PHP can emulate .htaccess protection (the pop-up box), but I don't know if it could use the query string variables to log in with that type of protection.

- Jonathan
Avatar of Aerocom

ASKER

Jonathon,

You are right! it does not work the same 'The page cannot be displayed' error comes up as with my existing java script passing of the username:password@www.webaddress.com/directory.

Before the security update
(which I think is also designed to push people to move to a microsoft web server and asp which does not have the same problem)

I was able to have a single login page for all users they entered their username and password where the username is also the htaccess protected directory name  ie www.mywebsite/htaccesprotectedmasterdirectory/usernamehtaccessprotectedsubdirectory/index.htm

users have user specific files in their own directory and ( because each users username and password is in the master directory htpassword file) they can also get access to common files in the master directory.

At the moment, a temporary fix, is for the user to enter his username which redirects him to his directory and then use the ugly Apache popup ' Enter Network Password' box where he has to enter his username again as well as his password.

I have written software to create users htaccess and htpassword  files and to create user directories ( currently 85 of them).

I am very new to php but am willing to try anything that will provide an elegant looking solution to this problem.

Rick





ASKER CERTIFIED SOLUTION
Avatar of gr8gonzo
gr8gonzo
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
This might do the trick:
http://mod-auth-script.sourceforge.net/

... but I'll keep looking anyway.

- Jonathan
Ah, thought just occurred to me - you MIGHT be able to use mod_rewrite to redirect ALL requests to that PHP authentication script, and then after authentication, you can have your PHP script forward the user to the original destination...

- Jonathan
Avatar of Aerocom

ASKER

Jonathon,

Following up on your idea to use php authorisation I found the script below and did some experimenting.

<?php
 
$PHP_AUTH_USER = $_POST['username'];
$PHP_AUTH_PW = $_POST['password'];

$auth = false; // Assume user is not authenticated

if (isset( $PHP_AUTH_USER ) && isset($PHP_AUTH_PW)) {

    // Read the entire file into the variable $file_contents

    $filename = '/home/yade/bas_web/foretag';
    $fp = fopen( $filename, 'r' );
    $file_contents = fread( $fp, filesize( $filename ) );
    fclose( $fp );

    // Place the individual lines from the file contents into an array.

    $lines = explode ( "\n", $file_contents );

    // Split each of the lines into a username and a password pair
    // and attempt to match them to $PHP_AUTH_USER and $PHP_AUTH_PW.

    foreach ( $lines as $line ) {

        list( $username, $password ) = explode( ':', $line );

        if ( $username == "$PHP_AUTH_USER" ) {

            // Get the salt from $password. It is always the first
            // two characters of a DES-encrypted string.

            $salt = substr( $password , 0 , 2 );

            // Encrypt $PHP_AUTH_PW based on $salt

            $enc_pw = crypt( $PHP_AUTH_PW, $salt );

            if ( $password == "$enc_pw" ) {

                // A match is found, meaning the user is authenticated.
                // Stop the search.

                $auth = true;
                break;

            }

        }
    }

}

if ( ! $auth ) {

    header( 'WWW-Authenticate: Basic realm="Private"' );
    header( 'HTTP/1.0 401 Unauthorized' );
    echo 'Authorization Required.';
    exit;

} else {

     header( 'Location:first.htm' );
}

?>

Placeiing the php file in the .htaccess protected directory and posting the username and password variables  to it from the html form opens the php file without the Apache popup box.

The htpassword file is checked and if I end the script above with

 echo ( 'Accepted' ); I get the message OK

if however I use the redirect

header( 'Location:first.htm' );

It immediately pops up the Apache box and requires re-entry of the username and password.

deleting the .htaccess file from the directory gets around this but opens the directory to everybody which defeats the purpose of the whole thing.

Any ideas ? Your tips so far have borne some fruit just need the final piece of the puzzel

Rick

 
I usualy don't use .htaccess but cookies and that might do the trick here also if your users accept cookies that is...

Replace:
$PHP_AUTH_USER = $_POST['username'];
$PHP_AUTH_PW = $_POST['password'];

with something like:
$PHP_AUTH_USER = $_POST['username'];
$PHP_AUTH_PW = $_POST['password'];
if (!isset($PHP_AUTH_USER)) $PHP_AUTH_USER = $_COOKIE['username'];
if (!isset($PHP_AUTH_PW)) $PHP_AUTH_PW = $_COOKIE['password'];

and where you do:
$auth = true;
also do:
setcookie('username',$PHP_AUTH_USER,time()+/*INSERT TIMEOUT IN SECONDS */);
setcookie('password',$PHP_AUTH_PW,time()+/*INSERT TIMEOUT IN SECONDS */);

Avatar of Aerocom

ASKER

I am very willing to try a replacement for .htaccess such as cookies (although some users may not accept cookies) however It is not just the page that I need to protect but also the whole directory which also includes some downloadable exe files which are specific to specific clients.

Using .htaccess, once a user has got access to the directory by username/password entry he then able to download his exe files that are in the directory.
In my old method, with .htaccess, when a user enters his username/password, he gets access to his specific  exe files in his own directory and some general  exe files that are kept in another protected directory where his username/password is included in the .htpassword file.

If I get rid of .htaccess, and replace it with cookies/ mysql db or something else, isn't only the page protected but  the directory is open to everyone to get access to the executable files in the directory?

As a PHP newby I have searched for information on directory protection but only seem to find references to pages.

Logically  I would expect to be able to protect directories, other than via .htaccess, But How ??

Rick


How do I secure the whole directory
Now that I'm fully awake, I think the mod_rewrite suggestion would work out best. Screw $PHP_AUTH variables - those aren't going to get you anywhere - I'm sorry I suggested them. My full suggestion is this:

Create another directory called "files" and put all other users' directories inside it. Have a PHP script sit next to the files directory, and use a database for usernames/passwords. Whenever anyone tries to access their directory, use mod_rewrite to capture the name of their directory and redirect to the PHP script (and pass the name of the directory to the PHP script, as well). Use the PHP script as a middle-man between the user and his/her files.

So there will be three parts to the PHP script - one part authentication, one part directory listing, and one part file retrieval. If the user hasn't been authenticated, you can require them to log in before they can access their files. Once logged in, your PHP script reads in their directory and allows them to click on any file in order to "get it." Once they click on it, the PHP just reads in the file and streams it back out to the user.

This is all very doable - I've done it a few times before, and you gain a lot of flexibility in the end. For instance, you can expand the directory listing part of the script so that it becomes a file manager, so people can rename & delete files, upload more files without FTP, etc... You can even expand the functionality so you can manage your users all from a simple script or from the database and give them selective access to other people's directories if necessary - all without logging in again as the other person. You can also track usage and statistics... there are a lot of possibilities, but it's a very good way of doing things. The ONLY downsides of this (that I know of) are:

1) It's a little more resource drain on the system because literally everything is being passed through the PHP script, so if they're downloading a large file, foe example, all data will be "tunnelled" through the PHP script and out to the user.

2) If you break your PHP script, you break access to everything until you get it fixed (but you should always use a development script first and after you're certain a change works, then you can swap out the scripts).

3) You're adding more dependency on PHP to yourself.

Now, #2 and #3 are somewhat "small" downsides because if you take all factors into consideration, you shouldn't be breaking things that often, and dependency isn't always a bad thing - sometimes it just means consistency. :) And #1 isn't too bad, either - it's an acceptable downside for all the positives you get (in my opinion).

- Jonathan
Avatar of Aerocom

ASKER

Jonathon,

All a bit OTT for what I need.

Currently the client clicks on a 'check for updates' button in my software. A hidden binary registration file and a program ini file provide information on the current version number of the installed software and data files. a file is downloaded from the web site to the users PC containing version numbers of files on the web site. A comparison is made of the users and web site versions/dates of the program and users files. If later versions are available on the web a popup box in  the software tells the user that udates are available for him. Clicking on OK opens up his web browser and opened the userlogin page where entering his username ( which is also his directory name in the .htaccess protected directory) and his password would open the index.htm file in his directory which has information on the changes involved in the latest updates, and hyperlinks to files in that directory and links to some general files in a common download directory.

Users are able to actually make new program installations- opening installation files over the internet ( as long as they have a reasonable ADSL connection) Some installation files are 15mb. There is no way that I would want or allow users to either upload files or to rename files. What they do need is clear  user specific information on the updates and installation procedures which may be different for different users.

There are also a lot of directories for customised Demo versions of my software so one PHP file in the 'files' folder would not suffice -as each user has a separate requirement.

.htaccess worked fine, providing sufficient level of security with ease of use and using java script to pass the username:password to the .htaccess file in the users directory.

because of the microsoft 'security update' I now need to change the type of authentcation used to allow users entry into their directory.

I have no problems with changing to a PHP flat file or MySQL DB but I want to have directory security ( Many of my airline clients are bitter rivals and would love to get their hands on their competitors files) and the ability to open html files within the directory once they have been authenticated.

Rick
Well, that solution that I mentioned may seem a bit OTT because I tried to explain what you COULD do with everything. However, when it is just reduced to its smallest components, you're basically just using PHP authentication instead of that popup one. The problem is that if you use the popup, then you cannot pass the username/password to it automatically.

That one apache module I mentioned, http://mod-auth-script.sourceforge.net/ seems like it would do a similar thing, as well, but it would still go hand-in-hand with a PHP script that does the authentication. In order to pass the username/password, you'll have to do it by a form POST or by a GET string, and in that case, you'll need to have SOME script. The mod_rewrite is just another way of getting people TO that script so they authenticate before accessing files. The mod_auth_script is another way.

And remember, the script doesn't need to be fantastic with all these features - I'm just explaining what you COULD do in the future, if you were ever asked to expand the functionality. The bare-bones authentication, directory listing, and file retrieval would work just fine and wouldn't require all that much code.

- Jonathan
Avatar of Aerocom

ASKER

Following up on your comments I think I am getting my head around it.

It seems as if the mod_auth script uses .htaccess so that essential directory protection that I need is still there.

I also ave some of the pieces in place - the php athoristaion script above that I got working is able to read the htpassword file and authenticate the username and password in it. The reason that the Apache popup box came up again is that the .htaccess file in the directory is pointing to the same htpassword file that the php script has just verified.

with the mod_auth script
instead of AuthUserFile /path to htpassword file/
the htaccess file uses
AuthScriptURI "/login/authorize.php?filter=thisdir"

It seems to me that if I have a php file with a login form imbeded and the htpassword  authorisation script that is called by the .htaccess file when an attempt is made to gain access to the directory Then this should work.

What do you think

Rick



It might. Sorry to say that I'm not in a position to test it out right now, but theoretically it should work. :) (Although I still like the mod_rewrite method better - it's cleaner, in my opinion)

- Jonathan
Avatar of Aerocom

ASKER

Although I have not had time to work on the ideas provided, to find a working solution, the links and other comments provided by Jonothan have pointed me in the right directon to get a working solution and I will be able to sort something out.

When I do, I will post the solution here

With Thanks

Rick
Aerocom / Rick
It looks like you had the same problem that I’m running into now.
Before the IE patch, I was able to login through my webpage using username:password@www.domain.com/restricted.
I’ve been forced to change the way my site works. I now have AuthUserFile in my .htaccess file so that my browser pops up a login window.
My goal is to login through my webpage again and not see this browser login.
I’ve been really struggling with this and was really excited to see your thread.
I just can’t seem to get it working. I’m using Apache.
It would be incredible if you could respond with a copy of your .htaccess and your auth.php file. Of course you would take out any secure information.
I’m also not sure if I need to add anything to my restricted files.. If so could you add that?
It would be an incredible help to me and to anyone else struggling with this. This seems like the only thread that I could find on this issue.
Avatar of Aerocom

ASKER

Sorry to say, I have not been able to get anything working.

It seems that there would be too many changes that my web hosting service cannot/willnot make on a shared hosting basis.

It would mean renting a dedicated server which is not worth it.

I now get the user to put in his username which directs him to the .htaccess protected folder and then enter the username and password again to gain entry.

Sorry  about that

Rick
Do you by any chance have any suggestions on how I can get this up and running? I can't believe that we are the only two that have run into this issue.
Maybe I should start a new thread.