

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Restreindre l'accès à l'origine de l'URL d'une AWS Lambda fonction
<a name="private-content-restricting-access-to-lambda"></a>

CloudFront fournit un *contrôle d'accès à l'origine* (OAC) pour restreindre l'accès à l'origine de l'URL d'une fonction Lambda.

**Topics**
+ [Création d’un nouvel OAC](#create-oac-overview-lambda)
+ [Paramètres avancés pour le contrôle d’accès à l’origine](#oac-advanced-settings-lambda)
+ [Exemple de code de modèle](#example-template-code-lambda-oac)

## Création d’un nouvel OAC
<a name="create-oac-overview-lambda"></a>

Suivez les étapes décrites dans les rubriques suivantes pour configurer un nouvel OAC dans CloudFront.

**Important**  
Si vous utilisez `POST` des méthodes `PUT` or avec l'URL de votre fonction Lambda, vos utilisateurs doivent calculer le corps SHA256 du corps et inclure la valeur de hachage de la charge utile du corps de la demande dans l'`x-amz-content-sha256`en-tête lorsqu'ils envoient la demande à. CloudFront Lambda ne prend pas en charge les données utiles non signées.

**Topics**
+ [Conditions préalables](#oac-prerequisites-lambda)
+ [CloudFront Autoriser l'accès à l'URL de la fonction Lambda](#oac-permission-to-access-lambda)
+ [Création de l’OAC](#create-oac-lambda)

### Conditions préalables
<a name="oac-prerequisites-lambda"></a>

Avant de créer et de configurer OAC, vous devez disposer d'une CloudFront distribution avec une URL de fonction Lambda comme origine. Pour utiliser l’OAC, vous devez spécifier la valeur `AWS_IAM` pour le paramètre `AuthType`. Pour de plus amples informations, veuillez consulter [Utilisation d’une URL de fonction Lambda](DownloadDistS3AndCustomOrigins.md#concept_lambda_function_url).

### CloudFront Autoriser l'accès à l'URL de la fonction Lambda
<a name="oac-permission-to-access-lambda"></a>

Avant de créer un OAC ou de le configurer dans une CloudFront distribution, assurez-vous qu'il CloudFront est autorisé à accéder à l'URL de la fonction Lambda. Procédez ainsi après avoir créé une CloudFront distribution, mais avant d'ajouter l'OAC à l'URL de la fonction Lambda dans la configuration de distribution.

**Note**  
Pour mettre à jour la politique IAM de l’URL de la fonction Lambda, vous devez utiliser l’ AWS Command Line Interface (AWS CLI). La modification de la politique IAM dans la console Lambda n’est pas prise en charge pour le moment.

La AWS CLI commande suivante accorde au CloudFront service principal (`cloudfront.amazonaws.com`) l'accès à l'URL de votre fonction Lambda. L'`Condition`élément de la politique permet d'accéder CloudFront à Lambda *uniquement* lorsque la demande provient de la CloudFront distribution qui contient l'URL de la fonction Lambda. Il s’agit de la distribution contenant l’URL de la fonction Lambda à laquelle vous souhaitez ajouter l’OAC.

**Example : AWS CLI commande pour mettre à jour une politique afin d'autoriser l'accès en lecture seule pour une CloudFront distribution avec OAC activé**  
Les AWS CLI commandes suivantes permettent à la CloudFront distribution (`E1PDK09ESKHJWT`) d'accéder à votre Lambda*`FUNCTION_URL_NAME`*.

```
aws lambda add-permission \
--statement-id "AllowCloudFrontServicePrincipal" \
--action "lambda:InvokeFunctionUrl" \
--principal "cloudfront.amazonaws.com" \
--source-arn "arn:aws:cloudfront::123456789012:distribution/E1PDK09ESKHJWT" \
--function-name FUNCTION_URL_NAME
```

```
aws lambda add-permission \
--statement-id "AllowCloudFrontServicePrincipalInvokeFunction" \
--action "lambda:InvokeFunction" \
--principal "cloudfront.amazonaws.com" \
--source-arn "arn:aws:cloudfront::123456789012:distribution/E1PDK09ESKHJWT" \
--function-name FUNCTION_URL_NAME
```

**Note**  
Si vous créez une distribution et qu'elle n'est pas autorisée à accéder à l'URL de votre fonction Lambda, vous pouvez choisir la **commande Copy CLI** depuis la CloudFront console, puis entrer cette commande depuis votre terminal de ligne de commande. Pour plus d’informations, consultez [Attribution de l’accès à la fonction aux Services AWS](https://docs.aws.amazon.com/lambda/latest/dg/access-control-resource-based.html#permissions-resource-serviceinvoke) dans le *Guide du développeur AWS Lambda *. 

### Création de l’OAC
<a name="create-oac-lambda"></a>

Pour créer un OAC, vous pouvez utiliser le AWS Management Console CloudFormation, AWS CLI, ou l' CloudFront API.

------
#### [ Console ]

**Pour créer un OAC**

1. Connectez-vous à la CloudFront console AWS Management Console et ouvrez-la à l'adresse[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home).

1. Dans le panneau de navigation de gauche, choisissez **Accès à l'origine**.

1. Choisissez **Créer un paramètre de contrôle**.

1. Sur la page **Créer un nouvel OAC**, procédez comme suit :

   1. Entrez un **Nom** et éventuellement une **Description** pour l’OAC.

   1. Dans **Comportement de signature**, nous vous recommandons de conserver le paramètre par défaut **Demandes de signature (recommandé)**. Pour de plus amples informations, veuillez consulter [Paramètres avancés pour le contrôle d’accès à l’origine](#oac-advanced-settings-lambda).

1. Pour **Type de l’origine**, choisissez **Lambda**. 

1. Choisissez **Créer**.
**Astuce**  
Après avoir créé l’OAC, prenez note du **Nom**. Vous en aurez besoin au cours de la procédure suivante.

**Pour ajouter un contrôle d’accès d’origine à une URL de fonction Lambda dans une distribution**

1. Ouvrez la CloudFront console à l'adresse[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home).

1. Choisissez une distribution qui comporte l’URL de fonction Lambda à laquelle vous souhaitez ajouter l’OAC, puis choisissez l’onglet **Origines**.

1. Sélectionnez l’URL de fonction Lambda à laquelle vous souhaitez ajouter l’OAC, puis choisissez **Modifier**.

1. Sélectionnez **HTTPS only** (HTTPS uniquement) pour le paramètre **Protocol** (Protocole) de votre origine.

1. Dans le menu déroulant **Contrôle d’accès d’origine**, choisissez le nom de l’OAC que vous souhaitez utiliser.

1. Sélectionnez **Enregistrer les modifications**.

La distribution commence à se déployer sur tous les emplacements CloudFront périphériques. Lorsqu’un emplacement périphérique reçoit la nouvelle configuration, il signe toutes les demandes qu’il envoie à l’URL de fonction Lambda.

------
#### [ CloudFormation ]

Pour créer un OAC avec CloudFormation, utilisez le type de `AWS::CloudFront::OriginAccessControl` ressource. L'exemple suivant montre la syntaxe du CloudFormation modèle, au format YAML, pour créer un OAC.

```
Type: AWS::CloudFront::OriginAccessControl
Properties: 
  OriginAccessControlConfig: 
      Description: An optional description for the origin access control
      Name: ExampleOAC
      OriginAccessControlOriginType: lambda
      SigningBehavior: always
      SigningProtocol: sigv4
```

Pour plus d'informations, consultez la section [AWS::CloudFront::OriginAccessContrôle](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-originaccesscontrol.html) dans le *guide de AWS CloudFormation l'utilisateur*.

------
#### [ CLI ]

Pour créer un contrôle d'accès à l'origine avec le AWS Command Line Interface (AWS CLI), utilisez la **aws cloudfront create-origin-access-control** commande. Vous pouvez utiliser un fichier d’entrée pour fournir les paramètres d’entrée de la commande, plutôt que de spécifier chaque paramètre individuel comme entrée de ligne de commande.

**Pour créer un contrôle d'accès à l'origine (CLI avec un fichier d'entrée)**

1. Utilisez la commande suivante pour créer un fichier nommé `origin-access-control.yaml`. Ce fichier contient tous les paramètres d’entrée de la commande **create-origin-access-control**.

   ```
   aws cloudfront create-origin-access-control --generate-cli-skeleton yaml-input > origin-access-control.yaml
   ```

1. Ouvrez le fichier `origin-access-control.yaml` que vous venez de créer. Modifiez le fichier pour ajouter un nom à l'OAC, une description (facultative) et remplacez `SigningBehavior` par `always`. Ensuite, enregistrez le fichier.

   Pour plus d'informations sur paramètres OAC, consultez [Paramètres avancés pour le contrôle d’accès à l’origine](#oac-advanced-settings-lambda).

1. Utilisez la commande suivante pour créer le contrôle d'accès à l'origine à l'aide des paramètres d'entrée du fichier `origin-access-control.yaml`.

   ```
   aws cloudfront create-origin-access-control --cli-input-yaml file://origin-access-control.yaml
   ```

   Notez la valeur de `Id` dans la sortie de la commande. Vous en avez besoin pour ajouter l'OAC à l'URL d'une fonction Lambda dans CloudFront une distribution.

**Pour attacher un OAC à une URL de fonction Lambda dans une distribution existante (CLI avec un fichier d’entrée)**

1. Utilisez la commande suivante pour enregistrer la configuration de distribution pour la CloudFront distribution à laquelle vous souhaitez ajouter l'OAC. La distribution doit disposer d’une URL de fonction Lambda comme origine.

   ```
   aws cloudfront get-distribution-config --id <CloudFront distribution ID> --output yaml > dist-config.yaml
   ```

1. Ouvrez le fichier nommé `dist-config.yaml` que vous venez de créer. Modifiez le fichier en apportant les modifications suivantes :
   + Dans l'objet `Origins`, ajoutez l'ID de l'OAC au champ nommé `OriginAccessControlId`.
   + Supprimez la valeur du champ nommé `OriginAccessIdentity`, le cas échéant.
   + Renommez le champ `ETag` en `IfMatch`, mais ne modifiez pas la valeur du champ.

   Enregistrez le fichier lorsque vous avez terminé.

1. Utilisez la commande suivante pour mettre à jour la distribution afin d’utiliser le contrôle d’accès à l’origine.

   ```
   aws cloudfront update-distribution --id <CloudFront distribution ID> --cli-input-yaml file://dist-config.yaml
   ```

La distribution commence à se déployer sur tous les emplacements CloudFront périphériques. Lorsqu’un emplacement périphérique reçoit la nouvelle configuration, il signe toutes les demandes qu’il envoie à l’URL de fonction Lambda.

------
#### [ API ]

Pour créer un OAC avec l' CloudFront API, utilisez [CreateOriginAccessControl](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_CreateOriginAccessControl.html). Pour plus d'informations sur les champs que vous spécifiez dans cet appel d'API, consultez la documentation de référence de l'API pour votre AWS SDK ou autre client d'API.

Après avoir créé un OAC, vous pouvez l’attacher à une URL de fonction Lambda dans une distribution à l'aide de l’un des appels d’API suivants :
+ Pour l'associer à une distribution existante, utilisez [UpdateDistribution](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_UpdateDistribution.html).
+ Pour l'associer à une nouvelle distribution, utilisez [CreateDistribution](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_CreateDistribution.html).

Pour ces deux appels d’API, indiquez l’OAC dans le champ `OriginAccessControlId`, à l’intérieur d’une origine. Pour plus d'informations sur les autres champs que vous spécifiez dans ces appels d'API, consultez la documentation de référence de l'API pour votre AWS SDK ou autre client d'API.

------

## Paramètres avancés pour le contrôle d’accès à l’origine
<a name="oac-advanced-settings-lambda"></a>

La fonctionnalité CloudFront OAC inclut des paramètres avancés destinés uniquement à des cas d'utilisation spécifiques. Utilisez les paramètres recommandés, sauf si vous avez des besoins spécifiques en matière de paramètres avancés.

L'OAC contient un paramètre nommé **Comportement de signature** (dans la console) ou `SigningBehavior` (dans l'API, la CLI et CloudFormation). Ce paramètre fournit les options suivantes :

**Toujours signer les demandes d'origine (paramètre recommandé)**  
Nous vous recommandons d’utiliser ce paramètre, nommé **Signer les demandes (recommandé)** dans la console ou `always` dans l’API, la CLI et CloudFormation. Avec ce paramètre, il signe CloudFront toujours toutes les demandes envoyées à l'URL de la fonction Lambda.

**Ne jamais signer les demandes d’origine**  
Ce paramètre est nommé **Ne pas signer les demandes** dans la console ou `never` dans l’API, la CLI et CloudFormation. Utilisez ce paramètre pour désactiver l’OAC pour toutes les origines dans l’ensemble des distributions qui utilisent cet OAC. Cela permet d’économiser du temps et des efforts par rapport à la suppression d’un OAC de toutes les origines et distributions qui l’utilisent, une par une. Avec ce paramètre, CloudFront ne signe aucune demande envoyée à l'URL de la fonction Lambda.  
Pour utiliser ce paramètre, l’URL de fonction Lambda doit être accessible au public. Si vous utilisez ce paramètre avec une URL de fonction Lambda qui n'est pas accessible au public, CloudFront vous ne pouvez pas accéder à l'origine. L'URL de la fonction Lambda renvoie des erreurs CloudFront et les CloudFront transmet aux utilisateurs. Pour plus d'informations, consultez [la section Modèle de sécurité et d'authentification pour la URLs fonction Lambda](https://docs.aws.amazon.com/lambda/latest/dg/urls-auth.html) dans *AWS Lambda le guide de l'*utilisateur.

**Ne remplacez pas l’en-tête `Authorization` de l’utilisateur (client)**  
Ce paramètre est nommé **Ne pas remplacer l'en-tête d'autorisation** dans la console ou `no-override` dans l'API, la CLI et CloudFormation. Utilisez ce paramètre lorsque vous CloudFront souhaitez signer des demandes d'origine uniquement lorsque la demande d'affichage correspondante ne contient pas d'`Authorization`en-tête. Avec ce paramètre, CloudFront transmet l'`Authorization`en-tête de la demande du visualiseur lorsqu'il y en a un, mais signe la demande d'origine (en ajoutant son propre `Authorization` en-tête) lorsque la demande du visualiseur n'inclut pas d'`Authorization`en-tête.  
+ Si vous utilisez ce paramètre, vous devez spécifier la signature Signature Version 4 pour l'URL de la fonction Lambda au lieu du nom ou du CloudFront CNAME de votre distribution. Lorsque l' CloudFront `Authorization`en-tête de la demande du visualiseur est transféré à l'URL de la fonction Lambda, Lambda valide la signature par rapport à l'hôte du domaine URL Lambda. Si la signature n’est pas basée sur le domaine de l’URL Lambda, l’hôte figurant dans la signature ne correspondra pas à celui utilisé par l’origine de l’URL Lambda. Ainsi, la demande échouera, entraînant une erreur de validation de signature.
+ Pour transmettre l'`Authorization`en-tête de la demande du lecteur, vous *devez* l'`Authorization`ajouter à une [politique de cache](controlling-the-cache-key.md) pour tous les comportements de cache qui utilisent la fonction Lambda URLs associée à ce contrôle d'accès à l'origine.

## Exemple de code de modèle
<a name="example-template-code-lambda-oac"></a>

Si votre CloudFront origine est une URL de fonction Lambda associée à un OAC, vous pouvez utiliser le script Python suivant pour télécharger des fichiers vers la fonction Lambda avec la méthode. `POST` 

Ce code suppose que vous avez configuré l’OAC avec le comportement de signature par défaut défini sur **Toujours signer les demandes d’origine** et que vous n’avez pas sélectionné le paramètre **Ne pas remplacer l’en-tête d’autorisation**.

Cette configuration permet à l’OAC de gérer correctement l’autorisation SigV4 avec Lambda à l'aide du nom d’hôte Lambda. Les données utiles sont signées à l’aide de SigV4 à partir de l’identité IAM autorisée pour l’URL de la fonction Lambda, laquelle est désignée comme type `IAM_AUTH`. 

Le modèle montre comment gérer les valeurs de hachage des données utiles signées dans l’en-tête x-amz-content-sha256 pour les demandes `POST` provenant du côté client. Plus précisément, ce modèle est conçu pour gérer les données utiles des données de formulaire. Le modèle permet le téléchargement sécurisé de fichiers vers l'URL CloudFront d'une fonction Lambda et AWS utilise des mécanismes d'authentification pour garantir que seules les demandes autorisées peuvent accéder à la fonction Lambda.

**Le code inclut les fonctionnalités suivantes :**  
Satisfait à l’exigence d’inclure le hachage des données utiles dans l’en-tête x-amz-content-sha256
Utilise l'authentification SigV4 pour un accès sécurisé Service AWS 
Prend en charge les envois de fichiers à l’aide de données de formulaire en plusieurs parties
Inclut la gestion des erreurs pour les exceptions de demande

```
import boto3
from botocore.auth import SigV4Auth
from botocore.awsrequest import AWSRequest
import requests
import hashlib
import os


def calculate_body_hash(body):
    return hashlib.sha256(body).hexdigest()


def sign_request(request, credentials, region, service):
    sigv4 = SigV4Auth(credentials, service, region)
    sigv4.add_auth(request)


def upload_file_to_lambda(cloudfront_url, file_path, region):
    # AWS credentials
    session = boto3.Session()
    credentials = session.get_credentials()

    # Prepare the multipart form-data
    boundary = "------------------------boundary"

    # Read file content
    with open(file_path, 'rb') as file:
        file_content = file.read()

    # Get the filename from the path
    filename = os.path.basename(file_path)

    # Prepare the multipart body
    body = (
        f'--{boundary}\r\n'
        f'Content-Disposition: form-data; name="file"; filename="{filename}"\r\n'
        f'Content-Type: application/octet-stream\r\n\r\n'
    ).encode('utf-8')
    body += file_content
    body += f'\r\n--{boundary}--\r\n'.encode('utf-8')

    # Calculate SHA256 hash of the entire body
    body_hash = calculate_body_hash(body)

    # Prepare headers
    headers = {
        'Content-Type': f'multipart/form-data; boundary={boundary}',
        'x-amz-content-sha256': body_hash
    }

    # Create the request
    request = AWSRequest(
        method='POST',
        url=cloudfront_url,
        data=body,
        headers=headers
    )

    # Sign the request
    sign_request(request, credentials, region, 'lambda')

    # Get the signed headers
    signed_headers = dict(request.headers)

    # Print request headers before sending
    print("Request Headers:")
    for header, value in signed_headers.items():
        print(f"{header}: {value}")

    try:
        # Send POST request with signed headers
        response = requests.post(
            cloudfront_url,
            data=body,
            headers=signed_headers
        )

        # Print response status and content
        print(f"\nStatus code: {response.status_code}")
        print("Response:", response.text)

        # Print response headers
        print("\nResponse Headers:")
        for header, value in response.headers.items():
            print(f"{header}: {value}")

    except requests.exceptions.RequestException as e:
        print(f"An error occurred: {e}")


# Usage
cloudfront_url = "https://d111111abcdef8.cloudfront.net"
file_path = r"filepath"
region = "us-east-1"  # example: "us-west-2"

upload_file_to_lambda(cloudfront_url, file_path, region)
```