Actions

Country-Based Access with Auth0 Actions

How to deal with logins that must meet specific criteria based on the user’s country? Let's see how you can do this.

Last Updated On: February 01, 2022

Actions

Country-Based Access with Auth0 Actions

How to deal with logins that must meet specific criteria based on the user’s country? Let's see how you can do this.

Last Updated On: February 01, 2022

If your application needs conditional access based on the user’s country, you can easily achieve it with a simple Auth0 Action. Let’s see how you can do it.

Why a Country-based Login?

Controlling user access based on the country where they're located when they log in to your application may have different reasons. To mention just a few of them:

  • Legal reasons. Laws are different around the world. This leads to adapting access to services or content offered by your application so that it does not break the laws of a particular country. For example, think of online gambling: it is illegal in some countries. Also, think of the liability requirements of GDPR for Europe: you must comply with them in order to offer your services to European citizens.
  • Business reasons. A company may decide not to offer their services or product to a country for business reasons: maybe because the cost of delivering that product or service in a given country is not affordable, or because the pricing strategy may depend on the country. You can even consider copyright licenses: think of the availability of video on-demand services due to copyright restrictions, for example.
  • Security reasons. You may consider accesses coming from a given country dangerous because most traffic is statistically malicious.

Depending on the reason you want to control user access and on the services or content offered by your application, you can apply different restriction levels. You can range from blocking access to your application (geo-blocking) to adapting your services or content to that country's audience.

Be aware that the most common technique to geolocate a user is based on their IP address. However, blocking users based on their IP address can be easily circumvented through VPNs or anonymizer services.

Using Auth0 Actions

This article will focus on how you can use Auth0 Actions to detect the user's country and how to block them or require a second authentication factor. Auth0 Actions are JavaScript functions running in a Node.js environment executed when specific events happen in a few internal Auth0 Flows, such as the Login Flow, the Change Password Flow, the User Registration Flow, etc.

Each Flow is made up of one or more triggers. For example, the Login Flow runs when a user logs in. This Flow has a post-login trigger: an event fired after the user logs in. You can handle this event through one or more Actions. You can think of Actions as event handlers that run when a specific event fires in an Auth0 Flow.

The following is a graphical representation of an Action (AddRoles) that will be executed in the Login Flow after the user logs in:

Auth0 Action in the Login Flow

In the following, you will use the post-login trigger of the Login Flow to detect the user's country and apply your control strategy.

To learn more, you can check out this blog post for a quick introduction to Auth0 Actions.

Blocking Logins from a Country

Let's assume you want to block users coming from a given country. As I said, you need to create an Auth0 Action to handle the post-login trigger. So, head to your Auth0 dashboard. If you don't have an Auth0 account yet, you can sign up for a free one.

Select Actions on the left side menu and then Flows. You should land on the following page:

Auth0 Flows in the Auth0 Dashboard

Click the Login Flow and enter the Flow editor, as shown below:

Auth0 Flow editor

Here, you can add a custom Action by clicking the Build Custom menu item in the Add Action section of the Flow editor:

Add Custom Action menu

This allows you to assign a name to the Action you are going to create and to access the Action editor:

Auth0 Action editor

Replace the code in the editor with the following:

exports.onExecutePostLogin = async (event, api) => {
  if (event.request.geoip.countryCode === "AQ") {
    const countryName = event.request.geoip.countryName;
    
    api.access.deny(`Users from ${countryName} are not allowed!`);
  };
};

This code defines the onExecutePostLogin() method, which handles the post-login trigger. It receives two parameters: event and api.

The event parameter provides some information about the current running environment. For example, it allows you to access the current user's data, the current request, the tenant, etc. For more details about the Pre User Registration event object, check out the documentation.

The api parameter provides methods for changing the behavior of the Flow. For example, it allows you to deny access to your application or set specific metadata for the user or the application. For more details about the Pre User Registration api object, check out the documentation.

In your Action, you used the event.request.geoip object to get geolocation information about the user logging in. In particular, you checked the countryCode property, which can have one of the ISO country codes as a value. In the example, you want to block users coming from Antarctica, whose country code is AQ. The geoip object also provides you with other information about the user's country. For example, you used the countryName property to get the full name of the country. Check out the post-login event object documentation for more details.

If the user's country is Antarctica, access is denied through the api.access.deny() method. The string passed to the deny() method briefly explains the reason for the denied access.

Click the Save Draft button to store the Action you just created.

To test this Action, you should... move to Antarctica and try to log in to your application from there. This approach is a bit expensive and ineffective 🙂. Alternatively, you can test the Action by using the Test button on the upper-left corner of the Action editor. It opens a sliding window whose content is the event object that will be passed to the Action:

Testing Auth0 Action

You can modify the geoip object's properties to simulate a request coming from Antarctica and click the Run button. At this point, you will get a window showing a result similar to the following:

geoip test result

Requesting MFA from a Country

In addition to or instead of blocking users, you may want to enforce Multi-Factor Authentication (MFA) for users logging in from specific regions. First, you must have configured MFA in your Auth0 dashboard. This lets you define what additional factor you want to use. The next step is to force MFA when a user logs in from specific regions.

For example, assume you want to enforce MFA for North American users. You can create an Action with the following code:

exports.onExecutePostLogin = async (event, api) => {
  if (event.request.geoip.continentCode === "NA") {
    api.multifactor.enable("any");
  };
};

In this case, you used the continentCode property of the geoip object. If a user logs in to your application from one of the North American countries, you force MFA by invoking the api.multifactor.enable() method. The "any" string passed to the method tells Auth0 to use any of the configured factors. Alternatively, you can pass a string identifying a specific provider. Check out the documentation to learn the available values for MFA providers.

To make your Action available to the Login Flow in your production environment, you have to click the Deploy button and drag the newly created Action into the Flow editor, as explained in the introduction to Auth0 Actions.

Recap

In conclusion, throughout this article, you learned the main reasons you may want to control user access to your application on a country-based criterion and how you can implement it with Auth0 Actions. You learned the geolocation features of the event.request.geoip object and how to leverage them to block users or enable MFA when they come from specific countries.

However, remember that while the geolocation approach is pretty straightforward, it is not infallible.

  • Twitter icon
  • LinkedIn icon
  • Faceboook icon