.htaccess authentication w/ friendly url - php

I'm trying to setup my .htaccess file to enable basic authentication on our development website.
I want the authentication to work on all my site but for certain URL. We are using friendly URL on our site..
I would also like to bypass authentication for certain file types like png, css, etc...
What I have so far looks like this :
SetEnvIfNoCase Request_URI ^/upload/ NO_AUTH
AuthName "Restricted Area"
AuthType Basic
AuthUserFile /path/to/.htpasswd
Require valid-user
Satisfy any
Order deny,allow
Deny from all
Allow from env=NO_AUTH
<FilesMatch "\.(gif|jpe?g|png|css|js|swf)$">
Satisfy Any
</FilesMatch>
The authentication is working fine, but the SetEnvIfNoCase does not seem to work because I'm still asked for authentication when going to the friendly URL '/upload/'.
The FilesMatch part does not seem to work either ..
Anyone can help me with that ?
Thanks !

There's 2 things you need to address.
Your <FilesMatch> container is doing nothing. You already have a Satisfy Any. You should add those extensions to a separate SetEnvIfNoCase
When you are using rewrite rules that rewrite /upload/, you need to include both the "friendly" URI as well as the rewritten URI, because the auth module is applied at every step (obviously, since it's really really bad to allow bypassing of authentication by rewrite/alias). That means, for example, if you have this rule:
RewriteRule ^upload/(.*)$ /upload_script.php?file=$1 [L]
Then you need to have a NO_AUTH line for both /upload/ and /upload_script.php:
SetEnvIfNoCase Request_URI ^/upload/ NO_AUTH
SetEnvIfNoCase Request_URI ^/upload_script.php NO_AUTH
Then to address #1:
SetEnvIfNoCase Request_URI \.(gif|jpe?g|png|css|js|swf)$ NO_AUTH
So an example of the suggestion:
something that you can try is to add a rule (similar to the above RewriteRule example), to route the /upload/ to an intermediate script other than index.php, then from the intermediate script, call index.php.
So using the above example of /upload_script.php you'd add this before any of your rules:
RewriteRule ^upload/ /upload_script.php [L]
So that it looks something like:
RewriteEngine On
RewriteRule ^upload/ /upload_script.php [L]
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
Then, you create a script called upload_script.php which will have something like:
<?php
include_once "index.php";
?>
You may want to dump the $_SERVER[''] array first to see if everything's set to what Zend's index.php is expecting to see.

Related

htaccess: redirect certain file types to PHP script

I am trying to prevent direct access to certain file types and redirect them to PHP script.
Example: user/browser requests
http://example.com/files/example.pdf
And I want it to be handled by download.php script. So basically final url should be
http://example.com/tools/download.php?file=files/example.pdf
What I've tried:
<FilesMatch "\.(psd|log|sh|pdf|doc)$">
RewriteRule ^/files/(.*)$ /tools/download.php?file=$1 [NC,L]
#Order Allow,Deny - with or without this
#Deny from all - with or without this
</FilesMatch>
and
RewriteRule ^.*\.(pdf|doc|xls|xlsx|docx|zip)$ /tools/download.php?file=$1 [R=301,L]
And I can't seem to get it work. Any ideas?
I recommend navigating all about index.php and then dealing with php code instead of htaccess
RewriteEngine On
RewriteRule ^.*\.(pdf|doc|xls|xlsx|docx|zip)$ /tools/download.php?file=$1 [R=301,L]
This should do the trick. Please report back, if it won't work.
I would also suggest, like the others already said, to deny all direct access and to perform all routing via PHP.
A better idea is to tell htaccess that if the file is there in the public folder, just serve it, and if not, fire it through your index.php, which would then no doubt route to your download controller.
Something like this:
RewriteEngine On
# The following rule tells Apache that if the requested filename
# exists, simply serve it.
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
# The following rewrites all other queries to index.php. The
# condition ensures that if you are using Apache aliases to do
# mass virtual hosting, the base path will be prepended to
# allow proper resolution of the index.php file; it will work
# in non-aliased environments as well, providing a safe, one-size
# fits all solution.
RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L]
So basically I managed to make it work.
NB! RewriteRule keeps serving the file if it exists, it fires only if file
does not exist.
The solution for me is to use RedirectMatch:
RedirectMatch ^.*\.(psd|pdf|whatever)$ /tools/download.php?file=$0
...And play with it using Private browser windows on each link click, because browser - Firefox in my case - is somehow caching "click response".

Why doesn't my .htaccess file redirect properly?

This is my code:
Header set Cache-Control "max-age=0, private, no-store, no-cache, must-revalidate"
RewriteEngine on
RewriteCond %{REQUEST_URI} !(admin)
RewriteRule !maintenance\.php$ /maintenance.php [R=301,L]
I want to redirect all traffic on the site to maintenance.php except for any requests for files in /admin. I've tried so many combinations that never work. It always redirects no matter what. I can't figure out what could be causing this.
UPDATE:
I figured something out. If I comment out the .htaccess in the admin folder, Ben's code works. Here's the code there:
AuthType Basic
AuthName "Restricted area"
AuthUserFile "/home1/user/.htpasswds/public_html/example/admin/passwd"
require valid-user
What can I do to this .htaccess file to allow it to work?
Don't use permanent redirect R=301 in this purpose, you site is not maintenance permanently. Use temporary redirect R=302 only, otherwise your users will always see maintenance page even if you remove this rule, because R=301 is cached by browser.
%{REQUEST_URI} starts with /.
RewriteCond %{REQUEST_URI} !^/admin
RewriteCond %{REQUEST_URI} !^/maintenance.php$
RewriteRule ^ /maintenance.php [R=302,L]
why don't you use this line DirectoryIndex maintenance.php in .htaccess in order to redirect to this page . ones your site is ready you can remove maintenance mode by commenting the above line

htaccess - Redirect to error page if user attempts direct file access?

I have a website where the main directory contains a few files i don't want to be directly accessed using urls like this:
http://website.com/somefile1.ext1
http://website.com/somefile2.ext1
http://website.com/somefile1.ext2
http://website.com/somefile2.ext2
Currently they download if you enter the urls in a browser. Instead i would like to redirect them to a error page like this:
http://website.com/404
I found this snippet online but it doesn't work, it also doesn't redirect:
<Files ~ "\.(ext1)$">
Order allow,deny
Deny from all
</Files>
What would the correct .htaccess code be to do this task?
Edit:
I redirect site.com/script.php etc to site.com/script with this code:
RewriteEngine On
# turn on the mod_rewrite engine
RewriteCond %{REQUEST_FILENAME}.php -f
# IF the request filename with .php extension is a file which exists
RewriteCond %{REQUEST_URI} !/$
# AND the request is not for a directory
RewriteRule (.*) $1\.php [L]
# redirect to the php script with the requested filename
Try it like this I didn't tried it for now,
RewriteEngine On
RewriteCond %{REQUEST_URI} \.ext\d$
RewriteRule ^ 404 [R=301]
Try
<FilesMatch "somefile\.ext$">
Deny from all
</FilesMatch>
You don't need to use the Order directive if you want to deny access from all.

Directory protection asking for password twice on my https website?

I am trying to protect my website with a directory protection code. The website is in PHP.
My website has https and it is like https://www.example.com.
When I Open the website it is asking for username and password twice. I think it is taking once for http and once for https.
Can anyone please help me how to solve this problem.
Below is my .htaccess file code
options -multiviews
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^example.com$ [NC,OR]
RewriteCond %{HTTP_HOST} ^www.example.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
</IfModule>
AuthType Basic
AuthName "example.com"
AuthUserFile /www.example.com/web/content/.htpasswd
Require valid-user
<IfModule mod_security.c>
# Turn off mod_security filtering.
SecFilterEngine Off
# The below probably isn't needed,
# but better safe than sorry.
SecFilterScanPOST Off
</IfModule>
Thanks in advance for any help.
You're getting authentication dialogue twice because Apache runs mod_auth directive before mod_rewrite directive. Also authentication session set in HTTP URL isn't valid in HTTPS URL anymore therefore it Apache has to follow the BASIC auth directive under HTTPS as well.
There can be some work-around type solutions to skip BASIC auth for http URL and do it only for HTTPS but it is not straight forward.
UPDATE: Here is a workaround solution that you can use to avoid showing BASIC auth dialogue twice.
RewriteEngine On
RewriteBase /
# redirect to HTTPS and set a cookie NO_AUTH=1
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,CO=NO_AUTH:1:%{HTTP_HOST}]
# If cookie name NO_AUTH is set then set env variable SHOW_AUTH
SetEnvIfNoCase COOKIE NO_AUTH=1 SHOW_AUTH
# show Basic auth dialogue only when SHOW_AUTH is set
AuthType Basic
AuthName "example.com"
AuthUserFile /www.example.com/web/content/.htpasswd
Require valid-user
Order allow,deny
allow from all
deny from env=SHOW_AUTH
Satisfy any
Since cookie is only set for http://domain.com therefore env variable is also set only once and BASIC auth dialog is also shown only once.

limit GET using .htaccess in a KISSMVC php based site

I have a KISSMVC php based site with the following .htaccess to allow only authenticated users to see the site
RewriteEngine On
RewriteBase /myphpsite/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?/$1 [L]
# Protect app files
RewriteRule ^((app|system|scripts).*)$ index.php/$1 [L]
AuthName "Please enter your username and password"
AuthType Basic
<Limit GET>
require user THEUSERNAME
</Limit>
This works with no problem.
The problem is that I want to allow clients to retrieve a value from the site with no authentication. This value is obtained through the index.php function because it is calculated per client, plus there is no folder structure where these values are stored.
as an example this URL should not prompt:
http://fancywebsite.com/myphpsite/index.php/inventory/hash/variable
but this one should still be prompting:
http://fancywebsite.com/myphpsite
If I could somehow specify in the .htaccess file to bypass or satisfy the authentication when the requested URL contains "index.php/inventory/hash" that would be perfect.

Categories