I need to set auth on few pages and forward user back in case not authorized. For now, it display destination page with error.
Unauthorized
This server could not verify that you are authorized to access the
document requested. Either you supplied the wrong credentials (e.g.,
bad password), or your browser doesn't understand how to supply the
credentials required.
I have 0 knowledges in basic auth and apache conf. I have google deep and didn't find any solution, please advice.
Thank you
SetEnvIf Request_URI ^/en auth=1
AuthName "Please login to access english part"
AuthType Basic
AuthUserFile "/path/to/my/.htpasswd"
# first, allow everybody
Order Allow,Deny
Satisfy any
Allow from all
Require valid-user
# then, deny only if required
Deny from env=auth
This is really a limitation of HTTP Basic Authentication.
However, you could customise the 401 response (which I assume is what you are seeing, as opposed to a 403) the server would otherwise send back. You could directly redirect from the custom 401, however, that would result in the client receiving a 3xx response, rather than a 401, which is not as informative and confusing for users. Or, you present a "friendly" message, with a link back to where they came from.
The additional problem is knowing which page to send the user back to. Unless you are storing this information in the session, then you'll need to examine the Referer HTTP request header, which might not be set at all.
For example... at the top of your .htaccess file, define your custom error document for the 401 response:
ErrorDocument 401 /errordocs/e401.php
In /errordocs/e401.php, you would have something like:
<?php
/**
* 401 Unauthorized - Error Document
*/
// Get the HTTP Referer (if set at all)
$referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : null;
// Immediately redirect back to the referring page if known
// But the client then sees a 3xx response, without any error, which could be confusing for users
if (!empty($referer)) {
header('Location: '.$referer,true,302);
exit;
}
?>
<!DOCTYPE html>
<html>
<head>
<title>401 Unauthorized</title>
</head>
<body>
<h1>401 Unauthorized</h1>
<p>Sorry, you do not have permission to view that resource.</p>
<p>
<?php if (empty($referer)): ?>
Go back to the home page
<?php else: ?>
Go back to <?=$referer?>
<?php endif; ?>
</p>
</body>
</html>
To "automate" this, you could perhaps implement a meta refresh (or JS "redirect") back to the referring page (if set) after so many seconds.
Related
server.conf: https://dpaste.org/6Zgn
This is Apache's config in OpenServer.
Problem:
As far as I understand, it has somethins with Access-Control-Allow-Origin
I wrote:
Header set Access-Control-Allow-Origin "*"
It has not helped. I have either written to a wrong place of rsomething.
Could you help me?
this is because the server is blocking the frontend to make requests.
I faced the same error for a long time
The only possible solution for this situation is to allow the host from the server-side.
Whichever backend you are using, search for a way to somehow allow the domain host from there.
for eg, for PHP
<?php
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
header('Access-Control-Allow-Origin: *');
die();
}
// some other code
?>
more resource: Cross-Origin Request Headers(CORS) with PHP headers
We have an Angular app hosted on Apache that is going through QA testing. The app communicates with an app server hosting our web services via a reverse proxy setup in Apache's httpd.conf:
ProxyPass /SVCS/ https://dev.mycompany.test/SVCS/
ProxyPassReverse /SVCS/ https://devws.mycompany.test/SVCS/
We noticed the original developer hard-coded the Basic Auth header the downstream web services require in the JavaScript. We want to remove this from the web app and instead have Apache append the Basic Auth header in the proxied request.
<IfModule mod_headers.c>
Header add Access-Control-Allow-Origin: "*"
Header set Access-Control-Allow-Methods: "OPTIONS, GET"
Header set Access-Control-Max-Age: 1
Header set Access-Control-Allow-Credentials: true
Header set Access-Control-Allow-Headers: "authorization, X-my-header, X-your-header"
RequestHeader set Authorization "Basic FOOBAR123ZZZZZZZZZZZZZZZZZZZZZ="
</IfModule>
This IfModule snippet was already in the file, I just added the RequestHeader line (obfuscated here). As soon as this is added, the browser starts prompting for a username/password "Authentication Required". I tried setting the Access-Control-Allow-Credentials=false but there was no effect. The Basic auth user/password is a service account created for the app to access the web services, we don't want the end user to have to enter anything, they are already authenticated via SSO from another app.
How can I get the basic auth added to the proxied request's headers and not prompt the user for a password?
I tried something along the lines of this post apache-basic-authentication-issue-with-reverse-proxy which essentially configures a password file. But that wasn't working, even when entering the correct password the service was returning a 401 not authorized (plus I don't want the user to have to enter anything)
The authentication prompt was due to the fact I was setting the Authentication header for ALL requests instead of just the one service that required it. There was a followup service called that if I add the Auth header to, the server was complaining about the Authentication. I was able to narrow the setting of the header to this service only (via RewriteCond and RewriteRule) and all is well.
I looking for a way to make the msg information of the rule (which rule had been triggered) to appears in the error and/or audit log files and sent back to the client in response headers.
I understand that there is phase "msg" but it doesn't sent back to the client in response headers the information so it's doesn't help me.
I want to see the information of the log in the error page in html, what can I do?
thank you for help,
Vladi.
It's a bad idea to let the client know what exactly went wrong. A hacker could use that to work around your security framework. A much better approach is a combination of mod_unique_id and customized error pages. Steps to follow:
enable mod_unique_id with your apache configuration
create customized error pages for the http return codes you're interested in (example below)
enable those in your apache config (ErrorDocument 403 /<url_path_to>/403.php for this example)
Here's an example for a 403 error page, let's call it 403.php (and no, a pure static page won't work):
<?php
$protocol = $_SERVER['SERVER_PROTOCOL'];
header("$protocol 403 Forbidden");
header("Status: 403 Forbidden");
header("Connection: close");
$msg = $_SERVER["UNIQUE_ID"];
?>
<HTML><HEAD>
<TITLE>You have no access to this resource (403)</TITLE>
</HEAD><BODY>
<P>An error occured. Please tell the admin the error code: <?php echo $msg; ?></P>
</BODY></HTML>
That's just a very abbreviated variant with no styling etc (you might want to enhance this), but I incidentally kept it simple for understanding. The $msg will print a unique code. The client can tell you this code, and you can use it to look up the exact line in your error log, where you will see which rule triggered it etc.
If you don't want to use external stuff (mod_perl, mod_php, etc) because, for example, you are on a front end reverse proxy and you don't want to expose a larger attack surface, you can use SSI (Server Side Include), since apache supports SSI internally with mod_include.
Just load mod_include, then add this to your virtualhosts:
# Custom 403 HTML error with base64 encoded date + uniqueid on response
<Directory /var/www/html/common/_Errors>
AddType text/html .shtml
AddOutputFilter INCLUDES .shtml
Options +Includes
</Directory>
ErrorDocument 403 /common/_Errors/403.shtml
<Location "/common/_Errors/403.shtml">
# don't block redirected error page due rule to correlation
SecRuleRemoveById 980130
</Location>
Then, create a HTML file /var/www/html/common/_Errors/403.shtml containing something like this:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>Your request was denied.</p>
<!--#config timefmt="%Y-%m-%d %H:%M:%S" -->
<p><pre><!--#set var="ERR" value="${DATE_LOCAL} - ${UNIQUE_ID}" --></pre></p>
<p><pre><!--#echo encoding="base64" var="ERR" --></pre></p>
</body></html>
If you want you can change #config timefmt to fit your date time format.
SSI on mod_include will create a HTML response expanding the ERR variable with DATE_LOCAL and UNIQUE_ID and will encode the output as a base64 string. Just enough for me to get the uniqueid for the rule that was fired and its date.
The apache SSL is configured to challenge the web page user (based on the particular URL) for Smartcard token (Provider : Safenet) authentication. Here is the portion of the configuration
<Location /abc/xyz>
SSLVerifyClient optional
SSLVerifyDepth 3
SSLOptions +OptRenegotiate +StdEnvVars +ExportCertData
SSLCACertificateFile /opt/APACHE1/httpd/conf.d/CA.crt
RewriteEngine On
RewriteRule ^/$ /abc/sslnocertautherror
ErrorDocument 403 /abc/sslnotokenerror
ErrorDocument 500 /abc/sslnotokenerror
ErrorDocument 404 /abc/sslnotokenerror
ErrorDocument 401 /abc/sslnotokenerror
</Location>
On invoking the URL the Windows Security popup shows up followed by the token challenge pop up for password.
The functionality is working as expected if the user provides right password. If the password is wrong, the error message is displayed and the retry counter is decremented as expected.
If the user cancels the operation instead of entering the password the browser displays a blank page.
I tried to debug the error, it looks like the request is not going to the apache. The browser is stopping the request.
The browser cache and history are not cleared by this operation(Cancel operation in smart card token password popup window).
The browser does not return any HTTP error code except the ERROR_INTERNET_SECURITY_CHANNEL_ERROR when I debugged with HttpWatch.
Environment : JBOSS+APACHE+IE8
I tried a lot for finding the solution for this (getting rid of blank page on Cancel) in the forums, but no luck.
I appreciated you time and help. Please let me know if you need any other details.
Regards,
Srinivas
SSL authentication and secure channel establishment is performed before HTTP when you are using HTTPS. That means that it is performed before any pages can be retrieved using HTTP. The error message (if any) should therefore be returned by the browser. If the browser stays mute then there is very little you can do about that, except try for a better or more up to date browser.
i wonder how i can solve the following problem.
on the root directory of my server lies a file calles upload.php
i want to be able to add a "/upload" (without .php) to my URL and the browser should ask for a password (and maybe username if possible). I i enter the password (and username) correctly upload.php should be opened.
Is this possible with htaccess?
Yes, both those are two distinct questions.
First: remove the .php extension
There are mainly two ways of doing this.
Enable content negotiation throws MultiViews. This will allow you to refer to other resources without extension and even have several files with similar names but different extensions and let Apache pick the best according to what the browser prefers. See the link. You can enable it with Options +MultiViews in a <Directory> block in http.conf or .htaccess if you allows override for this option.
Use mod_rewrite. A rule specifically for your case could be RewriteRule ^upload$ upload.php. This can also be put in a <Directory> block in http.conf or .htaccess (if activated). You will need to have enabled mod_rewrite and the rewrite engine with RewriteEngine on.
Seconds: require authentication
You can do this both with PHP and Apache.
For Apache, see the docs here.
For PHP, using basic authentication (be warned the password will be sent to the server in plain text and unless you are using https it may be snooped by someone watching your traffic), you can do something like this:
function send401() {
$realm = "Credentials for upload";
header('WWW-Authenticate: Basic realm="'.$realm.'"');
header('HTTP/1.1 401 Unauthorized');
die();
}
function verify_credentials($user, $password) {
//check user and password here. Return true or false
return true;
}
if (!array_key_exists('PHP_AUTH_USER',$_SERVER) ||
!array_key_exists('PHP_AUTH_PW',$_SERVER)) {
send401();
}
elseif (!verify_credentials($_SERVER['PHP_AUTH_USER'],
$_SERVER['PHP_AUTH_PW']))
send401();
//if it gets here, the user was successfully authenticated