Nginx – Intercepting the browser’s basic authorization popup with nginx

nginx

I am trying to intercept the basic popup with nginx and stuck at the user password.

I have a landing page where users would insert a username/password and the form gets posted to http://localhost/validate.

The following is the block that I got, If I hardcode the base64 encoded username:password, things are working but to do it in a programaticaly its not working.

location /validate/
{
set_form_input $username;
set_form_input $password;
set $auth_raw "$username:$password";
set_encode_base64 $digest $auth_raw; # $digest = some_hash_value

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Authorization "Basic <<<some_hash_value>>>"; # This works
#proxy_set_header Authorization "Basic $digest"; # This does not work
proxy_pass http://localhost:5601/;

}

As shown above,

Hardcoding the hash value allows me to bypass the basic authentication popup:

proxy_set_header Authorization "Basic <<<some_hash_value>>>"; 

But assigning it using a variable does not work:

proxy_set_header Authorization "Basic $digest";

Just by the looks of it, I am unable to dynamically assign the required values for proxy_set_header Authorization.

In short I want to be able to do the following,

  1. User enters username & password on a page & hit submit.
  2. Data get's posted to http://localhost/validate
  3. Nginx sees the request on /validate and start to process the form values and compose the URL (base64 encoded equivalent) http : //username:password@localhost:5601
  4. Server listing on port 5601 sees the username/password and authenticates the user and let the user in.

What am I doing wrong here? Or is there a better way to handle this with nginx?

Best Answer

The form submission URL (action attribute) is missing the trailing slash.

Upon form submission POST request is made to /validate which causes nginx to respond with a redirect to /validate/. The browser foIlows the redirect by issuing a GET request which does not contain the original data. Effectively the nginx rules receive empty credentials.

The solution is to add trailing slash to the <form> element's action attribute so it looks like: action="http://localhost/validate/".