Utiliser votre Azure Function de manière sécurisée

En tant que développeur, nous nous tournons rapidement vers une Azure Function pour automatiser des tâches. Les Azure Functions offrent une plateforme puissante qui nous permet d’écrire et d’exécuter notre code. Elles nous permettent de créer des applications évolutives et flexibles qui peuvent répondre à des événements et effectuer des tâches en fonction de déclencheurs. Mais au milieu de cette flexibilité et efficacité sans précédent, nous devons nous souvenir que la sécurité est un facteur essentiel lors du développement de toute application, y compris les Azure Functions. Dans cet article, nous examinons de plus près comment utiliser les Azure Functions de manière sécurisée et les meilleures pratiques à suivre pour protéger nos applications contre les menaces potentielles.

Lorsque nous créons une nouvelle Azure Function de type HttpTrigger, nous voyons que la définition de la tâche Run est formatée comme suit :

     public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log)
        {
           ...

Le premier paramètre est l’attribut HttpTrigger composé des paramètres suivants :

  • AuthorizationLevel, nous en discuterons plus en détail dans cet article. Les valeurs possibles sont :
    • Anonymous
    • User
    • Function
    • System
    • Admin
  • Ensuite, nous voyons que les méthodes possibles sont définies pour notre Azure Function sous forme de tableau de chaînes, à savoir get & post. Si aucune n’est définie, la fonction http trigger obéit à toutes les méthodes.
  • Suivi du paramètre Route. Il définit les requêtes auxquelles les URLs répondent. Si aucun n’est défini, alors le nom de la fonction est utilisé.

En plus, nous avons le paramètre HttpRequest, qui est utilisé comme objet d’entrée. Par exemple, le body est récupéré depuis celui-ci lorsque vous utilisez une méthode post.

Enfin, nous avons l’objet ILogger, comme son nom l’indique, il peut être utilisé pour enregistrer des informations, mais aussi une erreur.

Anonymous

Clairement, cela permet à l’Azure Function d’être utilisée par des utilisateurs anonymes et donc par n’importe qui. Il s’agit de la forme de sécurité la plus faible, pour ne pas dire qu’aucune sécurité ne se produit réellement lors de l’appel de l’Azure Function. Cette forme n’est pas recommandée pour une utilisation en production.

     public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log)
        {
           ...

Function

     public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log)
        {
           ...

Lorsque vous utilisez le niveau d’autorisation Function, vous indiquez à l’Azure Function que vous souhaitez utiliser les clés d’application hôte définies dans l’Azure Function. Pour ce faire, accédez à votre Azure Function et cliquez sur App keys. Vous avez ici une subdivision entre 2 types :

  • Host keys
  • System key

Pour ce niveau d’autorisation, vous pouvez utiliser les deux valeurs définies dans la subdivision des host keys, à savoir :

  • _master
  • Default

Cependant, il est recommandé d’utiliser la clé Default ici car la clé _master est en réalité destinée à être utilisée pour les Azure Functions avec le niveau d’autorisation Admin.

Vous pouvez transmettre cette clé en tant que paramètre de requête de la façon suivante (remplacez les parties en gras par vos valeurs) : https://AzureAppName.azurewebsites.net/api/AzureFunctionName?code=YourDefaultCode

Une autre façon est d’appeler l’URL de votre Azure Function sans paramètres de requête et de transmettre le code par défaut avec le paramètre d’en-tête x-functions-key.

Admin

     public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Admin, "get", "post", Route = null)] HttpRequest req, ILogger log)
        {
           ...

Ce niveau d’autorisation est identique à la clé Function, mais destiné à protéger certaines Azure Functions qui requièrent plus de droits. Par exemple, il est uniquement possible d’appeler une Azure Function avec ce niveau d’autorisation avec la clé hôte _master. En la transmettant soit comme paramètre de requête, soit comme paramètre d’en-tête.

L’utilisation du niveau d’autorisation Admin ou Function est-elle un moyen sûr de sécuriser votre Azure Function ? Pas tout à fait. Cela aide bien à sécuriser votre Azure Function de sorte qu’elle ne puisse être appelée que par des personnes qui possèdent la clé pertinente. Mais une fois que vous l’utilisez dans un client en production, votre clé peut être interceptée. La clé _master et la clé Default peuvent toutes deux être renouvelées en cas de faille de sécurité, mais cette nouvelle clé doit également être mise à jour dans chaque client où l’Azure Function est utilisée.

System

Le niveau d’autorisation System est utilisé pour les extensions Azure Function. Vous ne pouvez pas créer ou renouveler cette clé vous-même, et elle ne peut être créée que par l’extension Azure Function concernée.

User

D’après ce que je comprends, il avait initialement été créé pour utiliser EasyAuth, mais ce paramètre enum est un paramètre hérité inutilisé pour le moment. Les dernières informations que je peux trouver à ce sujet se trouvent dans le commentaire de cette issue.

Il n’est actuellement pas utilisé, mais il existe la possibilité de sécuriser votre Azure Function en fonction de l’authentification des utilisateurs, plus d’informations à ce sujet dans la section suivante :

Utiliser Azure Function avec Entra ID

Vous pouvez sécuriser votre Azure Function en fonction de votre AAD, vous pouvez le faire en ajoutant un fournisseur d’identité dans votre Azure Function. Pour cet exemple, nous configurons le fournisseur d’identité avec Microsoft Entra ID, mais vous pouvez également utiliser d’autres tels qu’Apple, Facebook, Github, Google, Twitter ou OpenID Connect.

Tout d’abord, cliquez sur la section Authentication dans votre Azure Function.

Cliquez ensuite sur Add identity provider.

Sur l’écran suivant, vous pouvez sélectionner votre fournisseur d’identité. Nous choisissons ici les identités Microsoft Entra.

Nous pouvons ensuite voir les paramètres de configuration pour le fournisseur d’identité sélectionné. Notez que le fournisseur d’identité utilise une inscription d’application Entra à partir de laquelle l’authentification aura lieu. Ici, nous choisissons de créer une nouvelle inscription d’application.

Cliquez sur Next:Permissions > et consultez les autorisations nécessaires pour l’inscription d’application AAD. Vous pouvez ajouter des autorisations si nécessaire, mais pour les bases, les autorisations Graph User.Read sont suffisantes, je laisse donc cela tel quel.

Enfin, vous devez donner à votre Azure Function le niveau d’authentification Anonymous. L’authentification est effectuée par votre fournisseur d’identité que vous venez de configurer. Cela fonctionne au-dessus du niveau d’authentification, donc ne vous inquiétez pas, votre Azure Function est bien sécurisée.

     public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log)
        {
           ...

Mais comment utiliser votre API maintenant qu’elle est sécurisée avec un fournisseur d’identité ? La méthode get est assez simple, vous pouvez simplement coller l’URL de votre Azure Function dans votre navigateur et vous obtiendrez une invite de connexion, à partir de laquelle un jeton ID est généré et vous êtes libre d’utiliser votre Azure Function. La méthode post est assez différente car elle ne prend pas en charge la redirection de connexion. Pour utiliser votre Azure Function sécurisée avec la méthode post, nous devons obtenir un access token que vous pouvez acquérir avec les endpoints authorize et token.

Pour vous montrer comment appeler avec succès votre Azure Function sécurisée, j’utilise Postman et plus précisément l’onglet Authorization intégré, qui obtiendra le code depuis l’endpoint authorize pour moi et le transmettra à l’endpoint token.

Cliquez sur l’onglet Authorization de votre requête post dans Postman et choisissez le type OAuth 2.0 et choisissez d’ajouter les données d’autorisation aux Request Headers.

Nous avons ensuite besoin de l’URL de callback, cette URL peut être obtenue depuis l’inscription d’application Entra, dans les Redirect Uri’s de la section Authentication.

Ensuite, vous avez besoin des endpoints d’autorisation et de token de votre inscription d’application. Ces 2 URLs peuvent être obtenues depuis la section Endpoint dans l’écran d’aperçu de votre Azure Function.

Avec ces informations, nous revenons à l’onglet Authentication dans Postman et remplissons la configuration suivante :

  • Grant Type : Authorization Code

  • Callback URL : L’URL de la section Redirect URL’s dans la section Authentication de notre inscription d’application

  • Auth URL : L’endpoint Authorize

  • Access Token URL : L’endpoint Token

  • Client ID : Le Client ID de votre inscription d’application

  • Client Secret : Le Client Secret de votre inscription d’application

  • Scope : Il s’agit d’une concaténation de votre Client ID suivi de “/.default”. Par exemple : 1a66ff2a-8201-4ed6-91d6-3d5039ec4421/.default

Ensuite, nous faisons défiler jusqu’en bas et cliquons sur Get New Access Token puis sur Use Token. Après cela, vous verrez qu’un Bearer access token est ajouté aux en-têtes de votre requête, avec lequel vous appellerez avec succès votre Azure Function.

Contenu associé