Forum Moderators: phranque
However, I now want to add a custom error document to respond to error 401 - authorisation required (i.e. if the user cancels the login).
The problem is that I can't use an external URL for the file as that is not allowed for 401 error documents, and I can't use a local file as the path is relative to the web root, not the server root, so any such file is protected by .htpasswd - catch 22!
The file I want to use is pretty big, so it's not very practical to include it as text in the ErrorDocument directive (which must all be on the same line).
If I could disable authentication for a sub-directory of the site then I could put the error document there, but I can't find any way of doing this.
Is it possible at all?
- Mark
Welcome to WebmasterWorld!
You can use the "Satisfy any" directive, combined with SetEnvIf, to allow unlimited access to the 401 document. See Apache core, mod_auth, and mod_setenvif. There's also an Authentication, Authorization, and Access Control tutorial on the Apache site that's pretty good.
Jim
I have got it working, thanks to your advice, but I don't know if it's the optimal solution. Here's what I've done.
I created a directory called /error_docs/ and put my error file (401.htm) into it. My root-level .htaccess now uses 'ErrorDocument 401 /error_docs/401.htm' to point to that file, but is otherwise unchanged.
I then created a new .htaccess file in the error_docs directory, which contains the following:
SetEnvIf Remote_Host "\." allow_all
Allow from env=allow_all
Satisfy Any
This essentially means that this entire directory is always readable, as the remote host will always contain a period.
Everything seems to work as I intend now, but are there any other improvements that you think I should make? For instance, is it possible to somehow store 401.htm in the site root (as the only unprotected file), as it is a bit annoying to have a separate directory for a single file. Also, does this open up any security risks that I should be aware of?
- Mark
What I had in mind was something like:
SetEnvIf Request_URI "^/401\.html$" allow_all
Satisfy Any
Allow from env=allow_all
SetEnvIf Request_URI "^/([45][01][0-9]\.html¦robots.txt¦w3c/p3p.xml)$" allow_all
Satisfy Any
Allow from env=allow_all
Neither of these requires a special error-page subdirectory -- In fact, you can't put robots.txt in a subdirectory anyway, and the p3p policy should be located in /w3c/p3p.xml relative to your Web root.
If you do want to use a subdirectory and make separate arrangements for allowing robots.txt and p3p.xml access, then you could place a much simpler .htaccess routine in that subdirectory:
Satisfy Any
Allow from all
Replace all broken pipe "¦" characters above with solid pipe characters (usually Shift-\) before use. Posting on this board modifies them.
Jim
The examples you gave don't seem to work, however. I have stripped my .htaccess file to just the directives which password protect the site, and that works OK, but simply adding the Satisfy Any line (without any further conditions) allows full access. Here's what I've got:
AuthUserFile {path to .htaccess}
AuthGroupFile /dev/null
AuthName "site"
AuthType Basic
require valid-user
Satisfy Any
Presumably there is some other directive at a higher level that is allowing the pass-through, as there is only one access restriction in the file itself. Is there anything I can do about that? Do you have any idea what it might be?
- Mark
Allows full access to what - the whole site?
There are three concerns with access control code: What is the code, where is the code, and where are the files that the code acts upon?
If you have the custom error pages in a separate subdirectory, with the code in an .htaccess file in that subdirectory, then only those files should be made accessible by that code, unless as you say, there's something funny in the server config.
The other examples assumed that the error files were not is a separate subdirectory. If they are, then you'll need to include the full path to the file in the Request_URI pattern. That is,
SetEnvIf Request_URI "^/([b]error-subdirectory/[/b][45][01][0-9]\.html¦robots.txt¦w3c/p3p.xml)$" allow_all
Jim
In the example given it does not matter where the error documents are, as they are not referenced at all.
The example .htaccess code is the ONLY code in the .htaccess file in my web root, and there are no other .htaccess files present below this directory (and none above this directory in the directories that I control. However, there may be other directives in .conf files (or similar) outside my control).
The point is that without the Satisfy Any line, any requests for a file are met be a username/password prompt in the browser. However, if that line is present then all requests are granted without a prompt, even though there are no other access conditions specified in my code.
- Mark
Well, putting it all together, the following should work if placed in .htaccess in your root directory:
ErrorDocument 401 /error-subdirectory/401.html
AuthType Basic
AuthName "site"
AuthUserFile <path to .htpasswd>
AuthGroupFile /dev/null
Require valid-user
SetEnvIf Request_URI "^/(error-subdirectory/401\.html¦robots\.txt)$" allow_all
Order allow,deny
Allow from env=allow_all
Satisfy any
Replace all broken pipe "¦" characters above with solid pipe characters (usually Shift-\) before use. Posting on this board modifies them.
Jim
That's got it working - thanks!
The key thing was the Order allow,deny directive. With that in place the problems from my previous post vanished and everything's slipped into place. I now have a 401.htm file in my root directory which appears when the authentication fails, and the rest of the site is password protected.
Once again, thank you for all your help.
- Mark