Some cool extensions with HTTP Basic Authentication
Tags: nginx, authentication, cookie, ipaddress
Published: 2020-07-08 16:03:57

Earlier, I explained about [username/password authentication](https://dev.to/etribes/restricting-access-with-http-basic-authentication-5ac0) to authenticate the users before serving the content. Let's check out few cool extensions on basic authentication together with IP address, specific URLs, and cookie handling this time. 

#### Prerequisites
- The password file is already created (htpasswd)
- username/password authentication is already working

### Basic Authentication together with Access Restriction by IP address

Restricting certain IP address together with HTTP basic authentication can be also achievable with few configurations. Let's see this implementation in the following two cases.

#####Case 1: Allowing access to the user with a **valid username/password** as well as with a **valid IP Address**

````
server {
	location / {
                # satisfy all conditions
                satisfy all;

                deny  192.168.1.2;
                allow 192.168.1.1/24;
                allow 127.0.0.1;
                deny  all;

                # add http basic authentication 
      		    auth_basic "Password Required";
                auth_basic_user_file /etc/nginx/.htpasswd;
	}
}
```
This example shows a combo use case of HTTP basic authentication and IP restriction where **satisfy all** denotes that the user has to satisfy both conditions to be able to pass the authentication. This example will grant access for the **192.168.1.1/24** network excluding the **192.168.1.1** address.

#####Case 2: Allowing access to the user either with a **valid username/password** or with a **valid IP address**

````
server {
	location / {
                # satisfy at least one condition
                satisfy any;

                deny  192.168.1.2;
                allow 192.168.1.1/24;
                allow 127.0.0.1;
                deny  all;

                # add http basic authentication 
      		    auth_basic "Password Required";
                auth_basic_user_file /etc/nginx/.htpasswd;
	}
}
```
**satisfy any** denotes that the user has to satisfy at least one condition to pass the authentication.

**takeaway points**
- The **allow** and **deny** directives will be applied in the order they are defined.
- **satisfy all** denotes that the user has to satisfy all conditions whereas **satisfy any** denotes that the access is granted if the user satisfies at least one condition.

### Basic Authentication for specific URLs
It is also possible to achieve authentication rules applied to a specific URL instead of applying to all. 

````
server {
        location /api {
                # add http basic authentication 
      		    auth_basic "Password Required";
                auth_basic_user_file /etc/nginx/.htpasswd;
	}

	location / {
                auth_basic off;
	}
}
```
This example shows that the basic authentication only applies to **/api** and the rest of the URLs are freely accessible. 

### Basic Authentication together with Cookie and IP address for specific URL (Final episode 😜) 

````
map $cookie_bettercallsaul $cookie_bettercallsaul_exists {
  "hailSatanIsubmitToTheDarkSide" "true";
  default                         "false";
}

geo $valid_ip {
  192.168.1.1/24 "true";  #access granted 
  127.0.0.1      "true";  #access granted 
  192.168.1.2    "false"; #access not granted
  default        "false";
}


map $cookie_bettercallsaul_exists$valid_ip $cookie_ip_authentication {
  "truetrue"   "off";  #cookie and IP are valid
  "truefalse"  "off";  #cookie is valid but IP not
  "falsetrue"  "off";  #cookie is not valid but IP
  default      "Password Required"; 
}

server {
	location /api {
                auth_basic  $cookie_ip_authentication;
                auth_basic_user_file  /etc/nginx/.htpasswd;
                add_header Set-Cookie "bettercallsaul=hailSatanIsubmitToTheDarkSide;max-age=3153600000;path=/"; #setting the cookie if authentication is succeeded
                proxy_pass http://127.0.0.1:8000/;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $remote_addr;
	}

	location / {
                auth_basic off;
	}
}

```
This example grants access to the users to **/api** if they are coming from valid networks or they have specified cookie (bettercallsaul) set. It shows the basic authentication dialog if none of the conditions are satisfied and it will set the cookie once the user has access. 

**takeaway points**
 - **map** is extremely flexible and powerful module in Nginx configuration. It allows creating variables whose values depend on the values of other variables.  

```
map <InputValue> <OutputValue> {
  <Match1> <Match1ReturnValue>;
  <Match2> <Match2ReturnValue>;
  default <DefaultReturnValue>;
}
```
- **geo** module also possesses the same behavior in terms of input and output variables but it is based on IP address.  

````
geo $geo{
  192.168.1.1/24 1;  
  default        0;
}
```

Last but not the least, don't forget to apply your configuration changes. 

```
$ sudo service nginx reload
```
####Conclusion

Well, that's it. That was a simple implementation of basic authentication together with IP restricting, cookie handling, and specific configuration for specific URLs with powerful commands like **geo** and **map**.

I hope this post helped you! 👊