apache password protect specific URL - apache

I need to password protect on specific URL, for instance anyone can access index.php but as soon as they add parameters or "GET" variables I must require valid-user.
index.php -> sweet
index.php?prev=1 -> require valid user

Interesting question.
Here's a solution:
<Location /fakeindex.php>
Order Deny,Allow
Deny from All
Allow from env=REDIRECT_STATUS
AuthType Basic
AuthUserFile /pathto/htpasswd/file/passwords.secret
AuthName This is an example auth
Require valid-user
</Location>
<Directory /path/to/doc/root>
Order allow,deny
allow from all
RewriteEngine On
RewriteCond %{QUERY_STRING} .
RewriteCond %{REQUEST_URI} index.php
RewriteRule .* fakeindex.php [L,QSA]
</Directory>
This part:
Order Deny,Allow
Deny from All
Allow from env=REDIRECT_STATUS
is there to prevent a direct access to /fakeindex.php (but in fact who would like to enforce a direct access to a protected zone). It's optionnal.
The key point is that theses condition Rules detect a non empty Query string, and a request to index.php:
RewriteCond %{QUERY_STRING} .
RewriteCond %{REQUEST_URI} index.php
And that if they match the Rule:
RewriteRule .* fakeindex.php [L,QSA]
Redirect internally the request to /fakeindex.php, keeping the query string with QSA. After that the Location is applied, and authentification is on the Location.

You could use the isset() method on the get variable eg:
if (isset($_GET['prev'])) {
//load password input form
}

Related

How to bypass htpasswd auth on a specific route

mi site has apache authorization but I need to allow access to a certain url request. This url request does not represent an existing file or directory.
This is my .htaccess:
First i tried this approach:
AuthName "Required login"
AuthType Basic
AuthUserFile C:\path\to\apache\.htpasswd
Require expr %{REQUEST_URI} =~ ^specialUrl$
Require valid-user
This gives me an internal server error 500
I've tried:
%{REQUEST_URI} == ^specialUrl$
"%{REQUEST_URI} =~ ^specialUrl$"
I'm not sure how the expression is supposed to be evaluated. I guess i have a syntax error.
Second approach:
As i've seen on this other answer I tried setting an env variable
## Grant access to webhook uri
SetEnvIf Request_URI ^/specialUri noauth=1
## Auth config
AuthName "Required login"
AuthType Basic
AuthUserFile C:\path\to\apache\.htpasswd
Require valid-user
## Allow Deny
Order Deny,Allow
Satisfy any
Deny from all
Allow from env=noauth
This resulted on a 401 error Authentication Required when I POST from a http client.
Authentication required!
This server could not verify that you are authorized to access
the URL
"/specialUri".
You either supplied the wrong credentials (e.g., bad password), or your
browser doesn't understand how to supply the credentials required.
In case you are allowed to request the document, please
check your user-id and password and try again.
.htaccess file:
## Grant access to webhook uri
SetEnvIf Request_URI "\specialUri" noauth
## Auth config
AuthName "Required login"
AuthType Basic
AuthUserFile C:\path\to\.htpasswd
## Allow Deny
Order Deny,Allow
Satisfy any
Deny from all
Require valid-user
Allow from env=noauth
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
</IfModule>
I don't really understand why but it seemed that there was a redirection on my site. This was fixed adding another allow directive:
AuthType Basic
AuthName "Required login"
AuthUserFile C:\path\to\.htpasswd
Require valid-user
SetEnvIf Request_URI "mySpecialUri$" allow
Order deny,allow
Deny from all
Allow from env=webhook
Allow from env=REDIRECT_noauth
Allow from 127.0.0.1
Satisfy any
Note that SetEnvIf Request_URI "mySpecialUri$" is using the latest part of the uri. This is because the redirection I mentioned was generating a longer uri.
The Allow from env=REDIRECT_noauth fixed the problem

using rewrite condition with allow and Satisfy directive

I want to create a rule that allows only the https request to be prompted for user credentials and the http request to be redirected .
SetEnvIfNoCase IS_SSL .*yes.* HTTPS_REQUEST
<Files *>
AuthType Basic
AuthName "MyFirstPage"
AuthBasicProvider file
AuthUserFile /indexing/.pwd
Require valid-user
Order Deny,Allow
Allow from env!=HTTPS_REQUEST
Satisfy All
</Files>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{ENV:IS_HTTPS_REQUEST} off [NC]
RewriteCond %{THE_REQUEST} ^GET [NC]
RewriteRule ^(.*)/Mydata.php https://%{HTTP_HOST}/x1/Mydata.php [R=301,L]
</IfModule>
The above code is prompting for the password for both http and https request . Can you please suggest
Regards
You need to change "All" to "Any"
Satisfy Any
That way if the env!=HTTPS_REQUEST is true, the Require valid-user doesn't need to be satisfied.

RewriteRule / HTTP auth for one url

I want to redirect "?p_id=62" to http authentification but it does not work.
my conf:
<LocationMatch ^/>
RewriteCond %{QUERY_STRING} !^\?p_id=62$
RewriteRule ^ - [E=NO_AUTH:1,L]
Order deny,allow
Deny from all
AuthType basic
AuthName "Auth Needed"
AuthUserFile "/var/www/site/.htpasswd"
Require valid-user
Allow from env=NO_AUTH
Satisfy Any
</LocationMatch>
Can anyone help?
You don't need to match the ? part of the query string:
RewriteCond %{QUERY_STRING} !^p_id=62$
RewriteRule ^ - [E=NO_AUTH:1,L]
However, this is not going to work. The mod_auth modules are applied before mod_rewrite gets applied, so by the time the rewrite rule checks the query string to set the environment variable, mod_auth has already flagged the request as a 401 (needs auth). You might have to settle for a scripted solution, like:
RewriteCond %{QUERY_STRING} !^\?p_id=62$
RewriteRule ^ /auth_script.php [L]
<Files "auth_script.php">
Order deny,allow
Deny from all
AuthType basic
AuthName "Auth Needed"
AuthUserFile "/var/www/site/.htpasswd"
Require valid-user
</Files>
and the auth_script.php will simply load the content at the $_SERVER['REQUEST_URI'] URI and return it to the browser (not redirect).

use basic auth based on query_string

I'm trying to protect urls containing a specific string:
RewriteCond %{QUERY_STRING} foo
RewriteRule - [E=NEED_AUTH:1]
Options -Indexes
AuthType Basic
AuthUserFile /etc/apache2/.htpasswd
Order allow,deny
allow from all
satisfy any
deny from env=NEED_AUTH
Require valid-user
I suppose this should bring up the authentication dialog when loading
index.php?format=foo
but it doesn't work. I tried several other RewriteConds like for example
RewriteCond %{QUERY_STRING} format=foo
RewriteCond %{QUERY_STRING} ^format=foo$
with no luck. Using
RewriteLog "/var/log/apache2/rewrite.log"
RewriteLogLevel 3
doesn't log anything.
Any suggestions? :)
To add to Jon's answer, I had a similar issue as the OP. But I found that allow from env=!NEED_AUTH was not working so I had to reverse it in the Rewrite Condition RewriteCond %{QUERY_STRING} !format=foo and then reverse the allow allow from env=NEED_AUTH. So, here is the snippet that works:
RewriteCond %{QUERY_STRING} !foo=bar
RewriteRule ^ - [E=NO_AUTH:1]
Order deny,allow
Deny from all
AuthType basic
AuthName "Auth Needed"
AuthUserFile "/etc/httpd/conf.d/.htpasswd"
Require valid-user
Allow from env=NO_AUTH
Satisfy Any
Make sure you've turned on the rewrite engine using RewriteEngine On. Also, there's an error in your RewriteRule:
RewriteRule - [E=NEED_AUTH:1]
Needs to have 2 parameters before the flags:
RewriteRule ^ - [E=NEED_AUTH:1]
Aside from that, it doesn't look like you've setup authentication correctly. You'll need a AuthName to define the realm, apache won't do authentication without it. And I don't think you can force authentication with a allow from all, you might need to do this the other way around, by denying all and allow from env=!NEED_AUTH
As described here (Apache permissions based on querystring), I cannot get the combination of "RewriteRule" and "Allow from env" working in Apache 2.4.6.

Can an htpasswd apply to all URLs except one?

I have an htaccess setup for my domain, but I want one specific URL to not have htpasswd protection. That URL is a rewritten URL and doesn't have an actual directory associated with it.
Is there a way to use the root htaccess to htpasswd protect the entire site except for that one specific URL?
Edit (my code, including Jon Lin's suggestion, which isn't working for me):
RewriteCond %{SERVER_NAME} =subdomain.example.com
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
SetEnvIf Request_URI "^/messenger/parse" NOPASSWD=true
AuthUserFile /xxx/xxx/xxx/xxxxxx/subdomain.example.com/.htpasswd
AuthName "Staging Server"
AuthType Basic
Order Deny,Allow
Satisfy any
Deny from all
Require valid-user
Allow from env=NOPASSWD
You can setup something like SetEnvIf to set an environment variable for a given Request URI. Then in the auth definition, you can use the Satisfy Any and Allow from env directives to tell apache that access can be granted either by authentication or if the environment variable exists (which is only set for a specific URI). Example:
# set the NOPASSWD variable if the request is for a specific URI
SetEnvIf Request_URI "^/specific/uri/nopasswd/$" NOPASSWD=true
# Auth directives
AuthUserFile /var/www/htpasswd
AuthName "Password Protected"
AuthType Basic
Order Deny,Allow
# Any requirment satisfies
Satisfy any
# Deny all requests
Deny from all
# except if user is authenticated
Require valid-user
# or if NOPASSWD is set
Allow from env=NOPASSWD