Protecting web endpoints on Microsoft Azure: a Laravel Nova example

--

Azure Active Directory (AAD) logo. Image by Microsoft from the Microsoft Architecture icons collection. Usage scope: technical documentation blog in the public domain.

Goal

In this blog we will have a look on how to implement a basic protection scheme for a Laravel Nova endpoint while on Azure. In order to do that, we will rely on a few concepts from Active Directory.

While we assume that the Nova endpoint runs on Azure AppService, that does not have to be the case.

Introduction

Active Directory (AD) is a Microsoft service that manages user identities and authentication in an organization. It is a so-called directory service, storing information about users, computers, and other resources on a network. Azure Active Directory (AAD) is a cloud-based version of AD that provides identity management and access control for cloud applications and services.

Enterprise applications are applications that are used by an organization to perform business functions. These applications can be on-premises or cloud-based. In Azure, enterprise applications can be integrated with AAD to provide single sign-on (SSO) and centralized access control.

App registrations are used to register applications in AAD. They provide a way for developers to configure authentication and authorization for their applications. App registrations can be used to authenticate users, to obtain access tokens for accessing APIs, and to configure SSO for enterprise applications.

Active Directory

AD is a directory service that provides a hierarchical view of the resources on a network. It stores information about users, computers, and other resources on a network. It uses a domain name system (DNS) to locate and access resources on the network.

AD provides the following services:

  • Authentication: AD verifies the identity of users and computers on the network.
  • Authorization: AD controls access to resources on the network.
  • Replication: AD replicates changes made to the directory across all domain controllers in a domain.
  • Group Policy: AD allows administrators to configure settings for users and computers on the network.

Enterprise Applications

Enterprise applications are applications that are used by an organization to perform business functions. In Azure, enterprise applications can be integrated with AAD to provide SSO and centralized access control.

Integration with AAD allows users to sign in to an enterprise application using their organizational account. This eliminates the need for users to remember multiple usernames and passwords.

Centralized access control allows administrators to manage access to enterprise applications from a single location. This ensures that only authorized users have access to the application.

App registrations

App registrations are used to register applications in AAD. They provide a way for developers to configure authentication and authorization for their applications.

App registrations can be used to authenticate users, to obtain access tokens for accessing APIs, and to configure SSO for enterprise applications.

Authentication can be configured using various authentication protocols such as OAuth 2.0 and OpenID Connect. Access to APIs can be granted using Azure AD app roles or custom roles.

SSO for enterprise applications can be configured using SAML or WS-Federation protocols. This allows users to sign in to the enterprise application using their organizational account.

In conclusion, AD is a directory service that provides identity management and access control for resources on a network. In Azure, enterprise applications can be integrated with AAD to provide SSO and centralized access control. App registrations are used to register applications in AAD and configure authentication and authorization for the applications.

By leveraging these technologies, organizations can simplify identity and access management for their applications and resources.

A high-level overview of (A)AD & friends

Here is an overview on (Azure) Active Directory, Enterprise Applications, and App Registrations in Azure.

App registrations overview page. Image by O. Olatunbosun.

Authentication

Azure App Registrations allow developers to configure authentication for their applications using various authentication protocols such as OAuth 2.0 and OpenID Connect. To configure authentication, developers can define web reply/redirect URLs that are used to redirect the user to the application after authentication.

Developers can also configure logout URLs to allow users to log out of the application. Additionally, developers can configure directory-only access to allow access only to users who are employees of a specific organization.

Type of issued tokens

Azure App Registrations issue access tokens that can be used to access APIs. These tokens can be issued using various authentication protocols such as OAuth 2.0 and OpenID Connect. Tokens can be issued as either JWTs or SAML tokens.

JWTs are commonly used for web APIs and are JSON-based tokens that contain information about the user and the application. SAML tokens are XML-based tokens that are commonly used for enterprise applications.

Certificates & Secrets

Image credits: FLY:D on Unsplash.

Azure App Registrations can be configured to use certificates and secrets for authentication. Developers can upload certificates and secrets to the app registration to authenticate users and obtain access tokens.

When configuring certificates and secrets, it is important to choose descriptive names for them to make it easier to manage them in the future.

It is also important to consider the expiration of certificates and secrets. Azure provides built-in support for automatically rotating keys to ensure that they are not compromised.

To configure automatic key rotation, developers can enable the “Rotate” option when creating a new key. This will cause Azure to automatically generate and rotate a new key when the old one expires.

By properly managing certificates and secrets, developers can ensure the security and reliability of their applications.

Azure Integration

We will document the basic integration setup, in a way that is transparent to the application.

Azure protection for Nova

Image by d3images on Freepik

Keeping Laravel Nova on a default and public endpoint is a security risk, even if the endpoint supports authentication. Since Nova is an administration panel, and it is meant for internal use only, i.e. only Employees may have access to it, it is a very good idea to have the AAA stack backed by a directory system, in our case Azure Active Directory. This section briefly describes a first setup.

Big picture

The idea is very simple: in order to login on Nova, you must have an Azure account. In order to take care of this in a low-code fashion, we are relying on a few things:

While we found this to be the best way to integrate our Nova service with Azure’s AAD, we are well aware that there are more advanced integration schemes, as far Azure is concerned: maybe we will have a look at those in a future blog story.

Nova middleware

At the moment of writing, this configuration file for Nova defines its own middleware stacks, middleware and middleware_api .

Nova relies on Laravel’s middleware system. The library provided above has a ready-made middleware which allows us to check the following: a request is passed only if it is coming from a client authenticated on the Azure side. The details are not relevant here. If you want to study and understand this for good, start here. In a nutshell: Azure will assign a token to the client, and this token must be used at all times; the assignment relies on authenticating on the Azure portal.

In Nova 2 the middleware is added to the provider in the below code snippet app/Providers/NovaServiceProvider.php

Nova::routes()
->withAuthenticationRoutes(['web', \App\Http\Middleware\AzureNovaMiddleware::class])
->register();

While in Nova 4, we are just stacking this extra middleware in middleware and middleware_api from config/nova.php,

'middleware' => [
'web',
HandleInertiaRequests::class,
DispatchServingNovaEvent::class,
BootTools::class,
AzureNovaMiddleware::class
],

'api_middleware' => [
'nova',
Authenticate::class,
Authorize::class,
AzureNovaMiddleware::class
],

So basically, in Nova 4, we are just stacking this extra middleware in middlewareand middleware_api from config/nova.php, but in Nova 2 that would not work — the extra middleware is just ignored. See https://github.com/laravel/nova-issues/issues/2036.

Once the middleware is installed, a number of variables for its config/azure.php configuration must be provided. These variables are mandatory:

AZURE_TENANT_ID=???
AZURE_CLIENT_ID=???
AZURE_CLIENT_SECRET=???
AZURE_RESOURCE=https://graph.microsoft.com/

(see the sections below for the actual values). The redirection mechanism needs to point to the Nova login URL after a successful authentication; for that reason, the provided Azure middleware is customized (see AzureNovaMiddleware).

Apps & registrations

Image credits: Adobe Free Stock.

If you want to know more about the concepts around this part, start here with the idea of service principal for a service.

AppService supports Managed Service Identities: they are fully-managed service principals useful to give an identity to the resource, and give the resource access to other resources: for example, give read-only data access to a webapp on a blob container. In this case, we are creating manual registrations, and use them as a way to authenticate users via web — passing on this information to the application. We are using manual (unmanaged) identities because we need to have known secrets for them (passwords), and managed MSIs do not expose such things, it seems.

You will have to create two objects (follow the links for two actual examples on the portal):

  • an enterprise application
  • an application registration (appreg)

According to the interface you are using on the portal (i.e. legacy AAD vs Microsoft Entra) you might have to create both, or just create the application registration (the enterprise app, which is the public tenant-level face of the appreg basically, might get created automatically).

The variables needed in the .env file relate to these two. In particular:

  • AZURE_CLIENT_ID is the application id of the appreg
  • AZURE_CLIENT_SECRET is a client secret (password) for the app (see Certificates & secrets menu)

To get the tenant (directory) id, see here.

Attention. Without a key recycling scheme, the authentication system will break if the secret expires or is deleted; maintain them properly!

It is not OK to share and configure the same appreg for multiple slots within the same webapp. In terms of security it wouldn’t be a concern really, it just seems that Azure is not able to resolve automatically which reply url should be used in the redirection, if there are multiple ones on different hostnames. So basically: do not share the same service principal across multiple AppService’s (security) for slots either technical reason!

The most important part of the configuration, next to the secrets, is the URL redirect. In the Authentication tab of the appreg, set the following:

Finally, green checkbox for both types of issued session tokens.

The most important part of the configuration, next to the secrets, is the URL redirect. In the Authentication tab of the appreg, set the following:

Finally, green checkbox for both types of issued session tokens.

Logging in

Image by O. Olatunbosun.

You will head to the Nova login page, here for example. If you are not logged in already in the browser window, you will have to login on Azure first, with your account. It shouldn’t be possible to proceed, unless you are logged in (if you can disprove this, tell us!).

For the time being, you will still need to log in with your Nova account, after you are logged in with your Azure one. This is because we have not replaced the default web authentication guard for Nova with the azure one above, nor the internal users repository of the Laravel application gets synced with Active Directory.

Blog by Riccardo Vincelli and Olulode Olatunbosun brought to you by the engineering team at Sharesquare.

Please thumb up the story if you like it! If you have question or remarks, start the conversation here :)

--

--

Sharesquare.co engineering blog by R. Vincelli

This is the Sharesquare.co engineering blog, brought to you by Riccardo Vincelli, CTO at Sharesquare. Real-life engineering tales from the crypt!