1

I have images successfully served through a Nginx rewrite rule:

# Rewrite part ==============
location ~* "^/([a-z]{5})/([0-9]{5}).png$" {
  rewrite .* "/$1/image_handler.php?x=$2" last;
}

Now I need to add Basic Authentication to this service. I started with the Basic Auth block below and now my config looks as follows:

# Basic Auth part ===========
location ~ ^/my-user-(?<user_id>[^/]+) {
  try_files $uri $uri/ =404;
  auth_basic "Restricted Content";
  auth_basic_user_file /path/to/passwords/my-user-$user_id;
}

# Rewrite part ==============
location ~* "^/([a-z]{5})/([0-9]{5}).png$" {
  rewrite .* "/$1/image_handler.php?x=$2" last;
}

This works in prompting for login details until the correct password is submitted but afterwards, this time, I get an error (404/500) instead of the image.

I thought that by putting the Basic Auth block above the Rewrite block the flow would be from one block to the other. I now realise that it is because of the "try_files" line in the Basic Auth block.

I tried quite a few variations of Nginx directives including a 404/named location trick inside the Basic Auth block but I got stuck with rules such as "location not allowed inside a named location block", "if is evil"(!), and "rewrite always actions before auth_basic".

Ultimately I cannot find a way a achieve the simple task of adding Basic Authentication to my initial rewrite rule above.

=== UPDATE ===

I forgot to add that there are other users, let's say "open-user-xxx" (as well as "my-user-xxx") that don't need to Basic Auth BUT need to access to the same Rewrite rule directly.

Hope you can appreciate I simplified my setup above and there are actually quite a few more rewrite rules that would be duplicated between Basic Auth and Open users if I had separate blocks for both user types. Thanks.

3
  • Nginx chooses a location to process a request. It seems that the images are processed by a location \.php$ block. If you want to authenticate part of the website, you will need to include all of the functionality within the protected location block. For example, see this answer. Jan 25, 2019 at 10:58
  • Thanks for your comment! I forgot to add that there are other users, let's say "open-user-xxx" (as well as "my-user-xxx") that DO NOT need to Basic Auth BUT need to access to the same Rewrite rule directly. Hope you can appreciate I simplified my setup and there are actually quite a few more similar rewrite rules that would be duplicated between Basic Auth and Open users.
    – Jason
    Jan 25, 2019 at 11:10
  • The rewrite rule does not necessarily need to be protected. Unless /$1/image_handler.php is the same for all users. In which case, you may need to use two rewrite rules and make the .php block internal. Jan 25, 2019 at 11:14

1 Answer 1

0

I am resorted to using the 404/named_location trick I mentioned earlier and overcame the nginx rule restrictions I came across earlier.

Here is what works for me:

# Basic Auth part ===========
location ~ ^/my-user-(?<user_id>[^/]+) {
  auth_basic "Restricted Content";
  auth_basic_user_file /path/to/passwords/my-user-$user_id;

  # Go to Rewrite part
  error_page 404 = @imageHandlers;
}

# Go to Rewrite part anyway (without auth)
error_page 404 = @imageHandlers;

# Rewrite part ==============
location @imageHandlers {
  # Handle image1 ==============
  if ($uri ~* "^/([a-z]{5})/([0-9]{5}).png$") {
    rewrite .* "/$1/image_handler.php?x=$2" last;
  }

  # Handle image2 ==============
  if ($uri ... {
    etc.
  }
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .