Forum Moderators: phranque
header("Location: blah.html");
What I would like to accomplish is to deny access to everything on the server unless they pass through the login screen.
Example: A remote user can not type in 192.182.82.83/folder/file.html and have it display, unless they pass through 192.182.82.83/folder/index.php
index.php = login page
Thanks.
Welcome to WebmasterWorld!
You might want to post the part of your .htaccess code relevant to authorization. Lacking that, all I can do is to suggest that you read the Apache Authentication, Authorization, and Access Control [httpd.apache.org] tutorial.
Jim
there are methods to doing this with php using sessions as well.
or maybe this would help
HTTP authentication with PHP [php.net]
i will post you some example code from the sort of thing you probably want, it uses sessions in php, using $_SESSION to add session data, etc:
function checkSession(){
//these variables would be defined somewhere else
global $timeout, $dbhost, $dbtable, $dbuser, $dbpass, $dbname;
session_start();
if(!isset($_SESSION['ip'])){//either session is not set
session_destroy();
header("Location: ".getHeader("login.php?msg=no_sess"));
exit;
}
else if($_SESSION['time']+$timeout < time()){//or its exipred
//mark them offline duh!
$user=$_SESSION["user"];
$time=time();
$link = @mysql_connect($dbhost,$dbuser,$dbpass) or die("Could not connect to database");
mysql_select_db($dbname, $link) or die("Could not select table $dbname");
$query="UPDATE $dbtable SET online='0', sid='0', sidtime='0', logouttime='$time' WHERE user='$user'";//
$result=mysql_query($query, $link);
mysql_close($link);
session_destroy();
header("Location: ".getHeader("login.php?msg=sess_exp"));
exit;
}
else if( getTwoOctets($_SESSION['ip'])!= getTwoOctets($_SERVER['REMOTE_ADDR']) ){//or not on right ip
session_destroy();
header("Location: ".getHeader("login.php?msg=ip_addr&valid=".getTwoOctets($_SESSION['ip'])));
exit;
}
else{ //or everything is fine, return username we are logged in as
$_SESSION['time']=time();
$time=time();
$user=$_SESSION['user'];
//then update the sidtime to current
$link = @mysql_connect($dbhost,$dbuser,$dbpass) or die("Could not connect to database");
mysql_select_db($dbname, $link) or die("Could not select table $dbname");
$query="UPDATE $dbtable SET sidtime='$time', WHERE user='$user'";
$result=mysql_query($query, $link);
mysql_close($link);
return $_SESSION['user'];
}
}
basically how that system works, is you define some constants, like a page to go when there is no session data in the header (i.e. user didnt log in), if a time vlaue stored in the session that determines if their session is terminated has expired, if their ip address does not match the one allocated to that session (you might wanna just match it to 2 octets instead of all 4 so that users from big proxies like AOL whos IP's change alot can still access the pages and not get logged out every time the log in) i think i have a method getHeader that generates a [address...] full canonical name as well, thats easy enough to do as well.
this text may end up really weird formatted in this chat, and hopefully its not too long.
its just a sample of a REALLY quick and dirty login system i was making, so i wouldnt recommend you use it for anything of the utmost importance.
but you might consider thinking about it anyways, think of how it works perhaps.
<Directory "C:/Program Files/Apache Group/Apache/htdocs/priv">
Options Indexes IncludesNOEXEC SymLinksIfOwnerMatch MultiViews
AllowOverride None
AuthName "priv"
AuthType Basic
AuthUserFile "C:/Program Files/Apache Group/Apache/users/.htpasswd"
require valid-user
<Limit GET POST>
Order allow,deny
Allow from all
</Limit>
<LimitExcept GET POST>
Order deny,allow
Deny from all
</LimitExcept>
</Directory>
this would block everything in the priv folder, and you could have your login thing be in a directory below it, either that or you can have them all in the same directory and use a <files> directive or something.
as for forwarding the user to the login page if they try to access an authentication requiring page, perhaps you could in the .htaccess set a HTTP 403 ErrorDocument page to be the login page, that would mean if you get the Authorization Required error (by not logging in when apache prompts you to) it would forward you to the login page.
i dont know how well that would work for you, but hopefully it isnt totally useless.
Thank you so much.
If so, then I believe that I need to add 3 more "<directory>" instructions in the httpd.confg to correspond to the client folders.
At that point I need to add the code inbetween the <directory> and </directory>.
That is the part that I do not know anything about.
I would appreciate any help.
I currently have:
<Directory "D:/">
Options Indexes FollowSymLinks
# Options FileInfo AuthConfig Limit
AllowOverride None
Order allow,deny
Allow from all
</Directory>
<Directory "D:/testing">
Options Indexes IncludesNOEXEC SymLinksIfOwnerMatch MultiViews
AllowOverride None
AuthName "Blah Blah Blah"
AuthType Basic
AuthUserFile "C:/password/.htpasswd"
require valid-user
<Limit GET POST>
Order allow,deny
Allow from all
</Limit>
<LimitExcept GET POST>
Order deny,allow
Deny from all
</LimitExcept>
</Directory>
The password screen comes up, but will not accept the username and password.
.passwd file contents:
Testing:4NqkxqpKjbnlo
Thank you.
When the .htaccess login fails, I would like to redirect the user to the index.php page.
Currently it will, but the in the Internet Explorer address area, it still reads [xx.#*$!.xxx.xx...] and by clicking directly on it will take you to testing.html
I would like for it to redirect to the index.php page, and for the address to read [xx.xxx.xx.xx...] or [xx.xxx.xx.xx...]
Current httpd.conf error addition:
ErrorDocument 401 /index.php
Thank you for your help.
[Fri Jan 14 12:22:58 2005] [error] [client blah.blah.blah.blah] (OS 3)The system cannot find the path specified. : Could not open password file: D:/password/.htpasswd, referer: [blah.blah.blah.blah...]
[Fri Jan 14 12:22:58 2005] [error] [client blah.blah.blah.blah] user Testing not found: /testing/testing.html, referer: [blah.blah.blah.blah...]
blah = ip address
Thank you in advance for your help.
you CAN point to a seperate drive, or seperate folder that is outside your server root, usually the htdocs folder, by doing something like this:
make a folder somewhere inside the web root (i.e. "htdocs/private") then you can do something like this: (*note that aliases only, not <directory> directives, have slashes at the end)
Alias /private/ "D:/private/"
then you can access it with a <directory> directive like this:
<Directory "D:/My Music">
...
</Directory>
and basically what happens is the user is able to go to your "/private" folder on your D: drive (assuming windows) but it will tell them they are at [yourwebsite.com...]
you have to do that alias stuff so that apache knows to allow you access to it, otherwise, your configuration most likely restricts the access of your other harddrive, for example:
<Directory />
Options SymLinksIfOwnerMatch
Order allow,deny
Deny from All
AllowOverride None
</Directory>
if you have something like that (apache's default config has a <Directory /> directive that limits access to folders other than your web root (htdocs) and folders inside it.
<Directory "D:/Apps">
Options Indexes IncludesNOEXEC SymLinksIfOwnerMatch MultiViews
AllowOverride None
AuthName "fileshare"
AuthType Basic
AuthUserFile "C:/Program Files/Apache Group/Apache/users/.htpasswd"
require valid-user
<Limit GET PUT>
Order allow,deny
Allow from all
</Limit>
<LimitExcept GET PUT>
Order deny,allow
Deny from all
</LimitExcept>
</Directory>
oh and also, what you want for it to direct you to index.php when you get a 401 is this:
ErrorDocument 401 /401.php
401.php:
<?php
Header("Location: [yourwebsite.com...]
?>
You probably know that the Header function (claims in the documentation at least) that you have to provide it with a full canonical URL address.
i would use a function like this to generate this full canonical name for any given page:
$domainname would be used if you have a www address, and if not you would leave it blank and it would make you a [ip.address.here.x...] style address, or with a port number in it if you use your server on a port besides port 80. $protocol is just the "http" or "https" part of the address you would want it to use.
function getHeader($page, $protocol){
$domainname=""; //if you use a www.com name set this to "www.domainname.com/" or else if you use an ip address leave it blank
if(!isset($domainname) ¦¦ $this->domainname==""){
if(!isset($protocol) ¦¦ $protocol=="")
$protocol="http";
if($portnumber!=""){
return $protocol."://".$_SERVER["SERVER_ADDR"].":".$_SERVER["SERVER_PORT"]."/";
}
else{
return $protocol."://".$_SERVER["SERVER_ADDR"]."/";
}
}
else{
return $domainname;
}
}
hopefully this big mess of code turns out readable when i post it.
thats because i grabbed that code from a php object class that uses instance variables and functions and i forgot to change all the variables to make work in a simple function.
im currently working on a system that would let my users log into a page on my site, then once they log in, they are able to get into my htpasswd protecteed directories, but since i dont have index pages for them i have no way to protect the files from non-users currently, im thinking i might have to make a php script that indexes an entire directory that is above the htdocs directory so apache cant access it, and making the script serve the files, but id rather not do that.
also this script is going to allow my users to log into any of the games on my site i plan to make in the future, and make it so they dont have to enter different passwords, their game accounts all would let them in with their global site login.
im far from a pro at the whole authentication and security thing, but unless my site gets hit by a real cracker, i probably have nothing to worry about, and i hope you realize that any setup you do if youre not a pro at this stuff is bound to have some holes in it somewhere. i would recommend you aim towards simplicity when choosing between simplicity and complex-but-secure-if-it-works ways of thinking.