Reputation: 14544
The site is on shared hosting. I need to password protect a single URL.
http://www.example.com/pretty/url
Obviously that's not a physical file path I'm trying to protect, it's just that particular URL.
Any quick solution with .htaccess?
Upvotes: 54
Views: 96209
Reputation: 855
In Apache2.4 you can do:
<If "%{REQUEST_URI} =~ m#/pretty/url/?#i">
AuthUserFile /var/www/htpasswd
AuthName "Password protected"
AuthType Basic
Require valid-user
</If>
Upvotes: 4
Reputation: 337
This command:
htpasswd -c /etc/apache2/.htpasswd myuser1
If you are using Bitnami Apps (Open edx, for example), you need follow this instruction:
htpasswd -c /opt/bitnami/apps/edx/conf/.htpasswd myuser1
This config:
<VirtualHost *:80>
...
<Location />
Deny from all
#Allow from (Set IP to allow access without password)
AuthUserFile /etc/apache2/.htpasswd
AuthName "Restricted Area"
AuthType Basic
Satisfy Any
require valid-user
</Location>
...
</VirtualHost>
This config to protect all URLs.:
<Location />
Deny from all
#Allow from (Set IP to allow access without password)
AuthUserFile /opt/bitnami/apps/edx/conf/.htpasswd
AuthName "Restricted Area"
AuthType Basic
Satisfy Any
require valid-user
</Location>
In Bitnami Apps:
/opt/bitnami/ctlscript.sh restart apache
Upvotes: 0
Reputation: 9224
All the provided solutions didn't work for me. I figured following directives do the trick:
SetEnvIf Request_URI ^/page-url auth=1
AuthName "Please login"
AuthType Basic
AuthUserFile "/www/live.example.com/files/html/.htpasswd"
# first, allow everybody
Order Allow,Deny
Satisfy any
Allow from all
Require valid-user
# then, deny only if required
Deny from env=auth
Upvotes: 8
Reputation: 101
I updated Jon Lin's code for the purpose of protecting all URLs except for one - for instance robots.txt at the vhost's root. These are Apache 2.2 compliant directives.
<ifmodule mod_setenvif.c>
SetEnv require_no_auth=false
SetEnvIf Request_URI "^/robots.txt" require_no_auth=true
AuthType Basic
AuthName "Restricted"
AuthUserFile /home/someuser/.htpasswd
# Setup a deny/allow
Order Deny,Allow
# Deny from everyone
Deny from all
# 1. a valid authenticated user
Require valid-user
# or 2. the "require_no_auth" var is set
Allow from env=require_no_auth
# except if either of these are satisfied
Satisfy any
</ifmodule>
Same code for Apache 2.4
<ifmodule mod_setenvif.c>
SetEnv require_no_auth=false
SetEnvIf Request_URI "^/robots.txt" require_no_auth=true
AuthType Basic
AuthBasicProvider file
AuthName "Restricted"
AuthUserFile /home/someuser/.htpasswd
# grant access if either of these are satisfied
# 1. a valid authenticated user
Require valid-user
# or 2. the "require_no_auth" var is set
Require env require_no_auth
</ifmodule>
Upvotes: 2
Reputation: 3667
Since Rick stated in a comment that no answer in this question works, here is the snippet I use:
AuthName "Protected Area"
AuthType Basic
AuthUserFile /path/to/your/.htpasswd
AuthGroupFile /dev/null
SetEnvIf Request_URI .* noauth
SetEnvIf Request_URI the_uri_you_want_to_protect !noauth
SetEnvIf Request_URI another_uri !noauth
SetEnvIf Request_URI add_as_many_as_you_want !noauth
<RequireAny>
Require env noauth
Require valid-user
</RequireAny>
If you need support for Apache 2.2 AND Apache 2.4 (apparently there are setups where both versions run in parallel...):
AuthName "Protected Area"
AuthType Basic
AuthUserFile /path/to/your/.htpasswd
AuthGroupFile /dev/null
SetEnvIf Request_URI .* noauth
SetEnvIf Request_URI the_uri_you_want_to_protect !noauth
SetEnvIf Request_URI another_uri !noauth
SetEnvIf Request_URI add_as_many_as_you_want !noauth
<IfModule mod_authz_core.c>
<RequireAny>
Require env noauth
Require valid-user
</RequireAny>
</IfModule>
<IfModule !mod_authz_core.c>
Order Deny,Allow
Deny from all
Satisfy any
Require valid-user
Allow from env=noauth
</IfModule>
The code for Apache 2.2 is taken from Jon Lin.
Upvotes: 14
Reputation: 6177
What about redirecting the user to a password protected subfolder?
.htaccess
RewriteCond %{HTTP_COOKIE} !BadHorsie=secret_cookie_key
RewriteRule ^(pretty/url)$ /protected/login.php?url=$1 [R=307,L]
protected/.htaccess
AuthUserFile /usr/www/{YOUR_PATH}/protected/.htpasswd
AuthGroupFile /dev/null
AuthName "Protected"
AuthType Basic
require user BadHorsie
protected/.htpasswd
BadHorsie:$apr1$fFbaaVdF$Q5ql58g7R4qlpMUDb/5A0/
protected/login.php
<?php
if (isset($_GET['url']) && $_GET['url'] && $_GET['url'][0] != '/' && strpos($_GET['url'], '//') === false) {
setcookie('BadHorsie', 'secret_cookie_key', 0, '/');
header('Location: /' . $_GET['url'], true, 307);
exit;
}
?>
What happens
example.com/pretty/url
example.com/protected/login.php?url=pretty/url
example.com/pretty/url
Note: Of course the "session cookie and back-redirecting"-mechanism is fully optional. Finally you could serve your secret content directly through protected/login.php
. I showed this way only for inspiration.
Optional: Do not use PHP and set the cookie through .htaccess.
Upvotes: 0
Reputation: 304
Unfortunately I can't comment on @jon-lin answer. So, I create a new answer. My adapted solution in an apache 2.4 environment is:
#
# password protect /pretty/url URIs
#
AuthType Basic
AuthName 'Authentication required'
AuthUserFile /path/to/.htpasswd
# Restrict access to some urls
SetEnvIf Request_URI ^/pretty/url auth=1
<RequireAll>
# require the auth variable to be set
Require env auth
# require an valid-user
Require valid-user
</RequireAll>
Upvotes: -1
Reputation: 3103
You can use <LocationMatch>
or simply <Location>
inside your <VirtualHost>
directive to do this (assuming you have access to your httpd.conf / vhost.conf - alternatively you could put something similar in a .htaccess in your document root if you have to configure your site that way).
For example:
<VirtualHost *:80>
ServerName www.example.com
DocumentRoot /var/www/blabla
# Other usual vhost configuration here
<Location /pretty/url>
AuthUserFile /path/to/.htpasswd
AuthGroupFile /dev/null
AuthName "Password Protected"
AuthType Basic
require valid-user
</Location>
</VirtualHost>
You might find <LocationMatch>
more useful if you want to match a regular expression against your pretty URL. The documentation is here.
Upvotes: 24
Reputation: 19
the solution above is too busy and messed up a bit.. I go for simplicity and clarity like this
<Files "protected.html">
AuthName "Username and password required"
AuthUserFile /home/fullpath/.htpasswd
Require valid-user
AuthType Basic
</Files>
The above is to be put into your htaccess file where the "protected.html" is the file you want to protect (it can be anything you wish, for example myphoto.jpg or a document.zip, just re-name it to your preference). The AuthUserFile is the full path to your password file. You are done.
Although you may have to make sure the prerequisites for this are set. AllowOverride and AuthConfig are required in Apache directory tag configs for the code to work but normally it is pre-set out of the box so you should be safe and fine unless you are making your own custom build.
Upvotes: -1
Reputation: 143886
You should be able to do this using the combination of mod_env and the Satisfy any
directive. You can use SetEnvIf
to check against the Request_URI
, even if it's not a physical path. You can then check if the variable is set in an Allow
statement. So either you need to log in with password, or the Allow
lets you in without password:
# Do the regex check against the URI here, if match, set the "require_auth" var
SetEnvIf Request_URI ^/pretty/url require_auth=true
# Auth stuff
AuthUserFile /var/www/htpasswd
AuthName "Password Protected"
AuthType Basic
# Setup a deny/allow
Order Deny,Allow
# Deny from everyone
Deny from all
# except if either of these are satisfied
Satisfy any
# 1. a valid authenticated user
Require valid-user
# or 2. the "require_auth" var is NOT set
Allow from env=!require_auth
Upvotes: 89