HTTP Digest authentication fails with Ajax requests - .htaccess

Apologies if this should be on ServerFault, please move/vote to move if necessary.
I have come across a problem with a .htpasswd file whereby
Accessing a page normally requests a username and password as expected
I can then browse the site as expected and navigate through pages without authentication being requested on each page load.
Accessing a page on the same server, same base URL, using the same protocol but using AJAX re-requests authentication.
If I then authenticate, the AJAX request is successful, but the authentication on the main browser window is no longer valid and therefore the next refresh requests authentication.
This only happens on one vhost of many on the server, all of which use the same .htpasswd file. The Request for authentication is in the global Apache config file, and not specific to a vhost.
<Directory "/var/www/html">
Options Indexes FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
AuthUserFile /var/www/private/.htpasswd
AuthGroupFile /dev/null
AuthName "My Private Directory"
AuthType Basic
<Limit GET POST>
require valid-user
</Limit>
</Directory>
The .htaccess file in the only vhost in which it does not work is as follows. Nothing special which should affect it.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI} !.*\.(gif|png|jpe?g|ico|swf)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/=$1 [L,QSA]
</IfModule>
My question therefore is why do AJAX requests require a user to authenticate again?

Related

Cannot exclude route from http basic auth

I am trying to exclude a specific route from http basic authentication.
My .htaccess looks like this:
# Set an environment variable if requesting /dev
SetEnvIfNoCase Request_URI ^/dev/? DONT_NEED_AUTH=true
# Require authentication
AuthUserFile /etc/users
AuthName "This is a protected area"
AuthGroupFile /dev/null
AuthType Basic
# Set the allow/deny order
Order Deny,Allow
# Indicate that any of the following will satisfy the Deny/Allow
Satisfy any
# First off, deny from all
Deny from all
# Allow outright if this environment variable is set
Allow from env=DONT_NEED_AUTH
# or require a valid user
Require valid-user
# Rewrite url (make it pretty)
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^?]*)$ index.php?path=$1 [NC,L,QSA]
If I use that exact same .htaccess http authentication is removed for route "/dev", so this works as expected, however the problem is that I want password protection for route "/dev", but I want to remove password protection for route "/dev/guest".
I have tried changing to the following:
SetEnvIfNoCase Request_URI ^/dev/guest/? DONT_NEED_AUTH=true
and with escaping the slash in the middle:
SetEnvIfNoCase Request_URI ^/dev\/guest/? DONT_NEED_AUTH=true
but none of those two options are working, all routes are password protected again.
also, since the route is rewritten the actual url I want to allow is "dev/index.php?path=guest" but I am not sure if I should care about that since part of that is the query string, and a end-user will never use that route directly.
Any help is highly appreciated.
Finally found a working solution.
Used this:
SetEnvIf Request_URI /dev/guest noauth=1
<RequireAny>
Require env noauth
Require env REDIRECT_noauth
Require valid-user
</RequireAny>

Redirect all IP but mine + protect with password

I've a live website and due to maintenance I want to redirect all IP but mine and another one. I want also that every PC from the two enabled IP has to login to see the website. How can I have both things working at the same time?
To redirect all IP I'll add this to.htacces:
RewriteEngine On
RewriteBase /
RewriteCond %{REMOTE_HOST} !^1.2.3.4
RewriteRule .* http://www.anothersite.com [R=302,L]
Source: http://kb.siteground.com/how_to_redirect_all_visitors_except_your_ip_to_another_site/
But how can I protect everything also with password, in a way that users IP are redirected to anothersite.com? Also, how can I allow multiple IP? Add them with commas?
You can have a workaround like this
SetEnvIfNoCase REMOTE_ADDR "^(?:x\.x\.x\.x|x\.x\.x\.x)$" GET_AUTH=1
RewriteEngine On
RewriteCond %{ENV:GET_AUTH} !1
RewriteRule ^ - [R=503,L]
AuthType Basic
AuthName "Forbidden"
AuthUserFile /path/to/.htpasswd
Require valid-user
Satisfy any
Order allow,deny
Allow from all
Deny from env=GET_AUTH
This code will redirect any other IP but yours and the other one (with a HTTP 503 error: maintenance specific and google friendly).
Otherwise, you have the authentication process.

How do I enable https only on certain pages with htaccess?

I have an ecommerce site, and I want to enable https only on the ecommerce section of the site located at https://mysite.com/buy
Since all of the links on my pages are relative, when someone visits http://mysite.com and clicks on Buy, they are taken to http://mysite.com/buy
Also, if they visit https://mysite.com/buy and click on a link to another page, they are taken to https://mysite.com.
The reason I want https only on that one section is because I have external elements (i.e. Google Maps, Youtube, Twitter, etc) that cannot be sent over https.
Is there a way with htaccess that I can make the /buy directory force https, but every other page force http?
Edit:
In case anyone is interested, I was able to solve this using PHP. I would still prefer an htaccess solution, but this will work for now:
if($_SERVER['HTTPS'] == "on") {
if(strpos($_SERVER['REQUEST_URI'],"buy") === false) {
Header("Location: http://$_SERVER['HTTP_HOST']."".$_SERVER['REQUEST_URI']");
}
}
Try this in your .htaccess file:
Options +FollowSymLinks
RewriteEngine on
# redirect for http /buy page
RewriteCond %{SERVER_PORT} =80
RewriteRule ^buy/?$ https://mysite.com/buy [R=301,QSA,L,NE]
# redirect for https non /buy pages
RewriteCond %{SERVER_PORT} =443
RewriteCond %{REQUEST_URI} !^/buy [NC]
RewriteRule ^/?(.*)$ http://mysite.com/$1 [R=301,QSA,L,NE]
R=301 will redirect with https status 301
L will make last rule
NE is for no escaping query string
QSA will append your existing query parameters
NC is for ignore case comparison
$1 is your REQUEST_URI
I don't have hands on experience, but from what I see, it looks like the htaccess configuration file should impact only the files in the folder in which the file is stored.
So you should be able to do something like this:
http://www.besthostratings.com/articles/force-ssl-htaccess.html
And put it in the /buy folder of your site.
If your web page is hosted on 9001 port just enable any port on your linux box and make these changes in /etc/httpd/conf.d/ssl.conf.Then set your Listen Port to 9002 and create SSL certificate and key and put following configuration in your httpd.conf file
Listen 9001
<VirtualHost *:9001>
ServerAdmin root#localhost
DocumentRoot /mnt/work/httpd
<Directory "/mnt/work/httpd">
Options FollowSymLinks
AllowOverride AuthConfig
</Directory>
SSLEngine On
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP
SSLCertificateKeyFile /etc/httpd/www.test.example.com.key
SSLCertificateFile /etc/httpd/www.test.example.com.crt
RewriteCond %{HTTPS} off
RewriteRule (.*) https://www.test.example.com:9002%{REQUEST_URI}
and your .htaccess file should look like this
AuthType Digest
AuthName "Protected"
AuthDigestProvider file
AuthGroupFile /dev/null
AuthUserFile /mnt/work/httpd/digest_auth
Require user username**

htaccess permissions on addon domains

i have two domains setup one called fastcms.com and the other is called fastautos.com.
fastautos.com is based in the /home/speedycm/public_html/fastautos/ directory on my fastcms.com server (acting as an add on domain)
the problem i'm having now is that i want to allow users to use the fastautos.com website but continue to restrict usage to the fastcms.com website (password request).
currently both sites ask for a passsword. i only want it to ask for a password on the fastcms.com website.
this is my htaccess file at the moment!
RewriteEngine on
AuthType Basic
AuthName "restricted area"
AuthUserFile /home/fastcm/public_html/.htpasswd
require valid-user
RewriteCond %{HTTP_HOST} ^fastautos.co.uk$ [OR]
RewriteCond %{HTTP_HOST} ^www.fastautos.co.uk$
RewriteRule ^/?$ "http\:\/\/fastcms\.co\.uk\/fastautos\/" [R=301,L]
please help! many thanks in advance
If my memory is good, you can put the AuthType etc into a Directory section, that is applied to one directory only.
Also, if you have not denied it, you can create .htaccess file within directories of each of your site the override general settings.

How to force HTTPS on a directory AND force HTTPS authentication

I am wondering what the best way to force HTTPS authentication is.
When I have this in my .htaccess file:
AuthType Basic
AuthName "Developer"
AuthUserFile /usr/local/etc/apache22/passwords/passwords
Require user david
Authentication works, but it authenticates over port 80, sending the password in the clear.
So I figured I would add a Redirect Rule to redirect all non-HTTPS requests to equivalent HTTPS requests:
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteBase /~david/
RewriteRule ^(.*)$ https://myserver.tld/~david/$1 [R,L]
This also works, but it first authenicates on port 80, then redirects, then authenicates again on port 443. I do NOT want to authenticate on port 80, because the password will be sent in clear text. I have not been able to figure out a good way to redirect immediately to HTTPS, and then authenicate.
The only way I could figure how to do this is by doing this:
AuthType Basic
AuthName "Developer"
AuthUserFile /usr/local/etc/apache22/passwords/passwords
Require user david
ErrorDocument 403 /403.php
SSLRequireSSL
And having a 403.php PHP script on the / of my server:
<?php
header('Location: https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
?>
This is the desired behavior. It requires SSL, so when you try to access the directory on port 80, it spits out a custom error document, and that document to redirects the page to HTTPS.
This seems like a kludge. Is there a better way to accomplish this?
So the issue you are having is that your or block right now applies to both the HTTPS and the HTTP case. You need untangle this (well actually - you could also use 'satisfy any' - but that is a bit messy in this case).
An easy to debug/understand approach is to go to a structure like:
<VirtualHost *:80>
...
RewriteRule ^/foo/bar/?(.*)$ https://myserver.tld/foo/bar/$1 [R,L]
# and to guard against typo's...
<Directory /foo/bar/>
deny from all
</Directory>
</VirtualHost>
<VirtualHost *:443>
...
<Directory /foo/bar/>
BasicAuth .. etc.
allow from all
</Directory>
</VirtualHost>
and take things from there.
Dw.

Resources