Aller au contenu principal
Version: Next

Authentification des Webhooks

Sécuriser vos points de terminaison webhook est essentiel pour garantir que seul Beedeez peut envoyer des notifications à votre système. Ce guide explique les méthodes d'authentification disponibles pour les points de terminaison webhook.

Pourquoi l'Authentification est Importante

Sans authentification appropriée, votre point de terminaison webhook pourrait recevoir :

  • Des requêtes malveillantes de sources non autorisées
  • Des données falsifiées qui semblent provenir de Beedeez
  • Des attaques par déni de service

Implémentez toujours l'authentification pour les points de terminaison webhook en production.

Méthodes d'Authentification

Beedeez supporte cinq méthodes d'authentification pour les points de terminaison webhook. Choisissez la méthode qui correspond le mieux à votre infrastructure et à vos exigences de sécurité.

1. Aucune (Non Recommandé)

Aucune authentification n'est appliquée aux requêtes webhook.

Configuration :

{
"auth": {
"authType": "none"
}
}

Quand Utiliser :

  • Tests et développement uniquement
  • Réseaux internes avec d'autres mesures de sécurité
  • Débogage temporaire

Note de Sécurité : ⚠️ Ne jamais utiliser en environnement de production.


2. Bearer Token

Envoie un en-tête Authorization avec un Bearer token.

Configuration :

{
"auth": {
"authType": "bearer_token",
"token": "votre-token-bearer-secret"
}
}

En-tête de Requête :

Authorization: Bearer votre-token-bearer-secret

Quand Utiliser :

  • APIs REST modernes
  • Systèmes compatibles OAuth 2.0
  • Systèmes d'authentification basés sur des tokens

Bonnes Pratiques :

  • Utilisez des tokens longs générés aléatoirement (minimum 32 caractères)
  • Faites tourner les tokens périodiquement
  • Stockez les tokens de manière sécurisée (jamais dans le code source)
  • Utilisez des tokens différents pour différents environnements

Exemple de Génération de Token (Node.js) :

const crypto = require('crypto');
const token = crypto.randomBytes(32).toString('hex');
// Exemple : "a7f3c9e8b2d4f1a6e9c7b5d3f8e2a1c4..."

3. Authentification Basic

Envoie les identifiants en utilisant l'authentification HTTP Basic.

Configuration :

{
"auth": {
"authType": "basic_auth",
"username": "votre-nom-utilisateur",
"password": "votre-mot-de-passe-securise"
}
}

En-tête de Requête :

Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

(Base64 encodé username:password)

Quand Utiliser :

  • Systèmes legacy nécessitant Basic Auth
  • Exigences d'authentification simples
  • Systèmes avec infrastructure Basic Auth existante

Bonnes Pratiques :

  • Utilisez des mots de passe forts et uniques
  • Combinez avec HTTPS (requis)
  • Envisagez d'utiliser des comptes de service avec permissions limitées
  • Faites tourner les identifiants régulièrement

4. Clé API

Envoie une clé API dans l'en-tête X-API-Key.

Configuration :

{
"auth": {
"authType": "api_key",
"token": "votre-cle-api"
}
}

En-tête de Requête :

X-API-Key: votre-cle-api

Quand Utiliser :

  • APIs qui attendent des clés API dans les en-têtes
  • Architectures microservices
  • Plateformes cloud (AWS API Gateway, Google Cloud Endpoints, etc.)

Bonnes Pratiques :

  • Générez des clés API cryptographiquement sécurisées
  • Implémentez une limitation de débit sur votre point de terminaison
  • Surveillez l'utilisation des clés API
  • Révoquez immédiatement les clés compromises

5. En-tête Personnalisé

Envoie les identifiants d'authentification dans un en-tête personnalisé de votre choix.

Configuration :

{
"auth": {
"authType": "custom_header",
"headerName": "X-Custom-Auth",
"headerValue": "votre-valeur-auth-personnalisee"
}
}

En-tête de Requête :

X-Custom-Auth: votre-valeur-auth-personnalisee

Quand Utiliser :

  • Schémas d'authentification personnalisés
  • Systèmes legacy avec authentification non standard
  • Intégration avec des plateformes spécifiques nécessitant des en-têtes personnalisés

Bonnes Pratiques :

  • Utilisez des noms d'en-tête descriptifs (ex : X-Webhook-Secret, X-Integration-Key)
  • Évitez les noms d'en-tête courants qui pourraient entrer en conflit
  • Documentez votre schéma d'authentification personnalisé
  • Validez strictement les valeurs d'en-tête sur votre point de terminaison

Combiner l'Authentification avec des En-têtes Personnalisés

Vous pouvez combiner les méthodes d'authentification avec des en-têtes personnalisés supplémentaires pour une sécurité renforcée :

{
"auth": {
"authType": "bearer_token",
"token": "votre-bearer-token"
},
"customHeaders": {
"X-Webhook-Source": "beedeez",
"X-Environment": "production",
"X-Correlation-ID": "identifiant-unique"
}
}

En-têtes de Requête Résultants :

Authorization: Bearer votre-bearer-token
X-Webhook-Source: beedeez
X-Environment: production
X-Correlation-ID: identifiant-unique
Content-Type: application/json

Validation des Requêtes Webhook

Sur votre point de terminaison webhook, validez toujours les requêtes entrantes :

1. Vérifier l'Authentification

Vérifiez que l'en-tête d'authentification correspond à vos identifiants attendus :

// Exemple : validation Bearer Token (Node.js/Express)
app.post('/webhooks/beedeez', (req, res) => {
const authHeader = req.headers.authorization;
const expectedToken = process.env.WEBHOOK_BEARER_TOKEN;

if (!authHeader || authHeader !== `Bearer ${expectedToken}`) {
return res.status(401).json({ error: 'Non autorisé' });
}

// Traiter le webhook...
res.status(200).json({ received: true });
});

2. Vérifier le Type de Contenu

Assurez-vous que la requête a le bon type de contenu :

if (req.headers['content-type'] !== 'application/json') {
return res.status(400).json({ error: 'Type de contenu invalide' });
}

3. Valider la Structure de la Charge Utile

Vérifiez que la charge utile contient les champs attendus :

const payload = req.body;

if (!payload._id || !payload._userId || !payload._ownerId) {
return res.status(400).json({ error: 'Structure de charge utile invalide' });
}

4. Vérifier la Source (Optionnel)

Si vous définissez des en-têtes personnalisés, vérifiez-les :

if (req.headers['x-webhook-source'] !== 'beedeez') {
return res.status(403).json({ error: 'Source de webhook invalide' });
}

Bonnes Pratiques de Sécurité

Utiliser HTTPS Uniquement

  • ✅ Utilisez toujours des points de terminaison HTTPS (requis par Beedeez)
  • ✅ Assurez-vous de certificats SSL/TLS valides
  • ✅ Utilisez TLS 1.2 ou supérieur

Implémenter une Limitation de Débit

Protégez votre point de terminaison contre les abus :

// Exemple : limitation de débit simple (Node.js)
const rateLimit = require('express-rate-limit');

const webhookLimiter = rateLimit({
windowMs: 1 * 60 * 1000, // 1 minute
max: 100, // Max 100 requêtes par minute
message: 'Trop de requêtes webhook',
});

app.post('/webhooks/beedeez', webhookLimiter, (req, res) => {
// Gérer le webhook...
});

Stocker les Identifiants de Manière Sécurisée

  • ✅ Utilisez des variables d'environnement ou des systèmes de gestion de secrets
  • ✅ Ne commitez jamais les identifiants dans le contrôle de version
  • ✅ Chiffrez les identifiants au repos
  • ✅ Utilisez des identifiants différents par environnement

Surveiller et Alerter

  • ✅ Loggez toutes les requêtes webhook (y compris les échecs d'authentification)
  • ✅ Configurez des alertes pour les échecs d'authentification
  • ✅ Surveillez les modèles inhabituels
  • ✅ Suivez les taux de succès de livraison des webhooks

Faire Tourner les Identifiants

  • ✅ Faites tourner les identifiants d'authentification périodiquement (tous les 90 jours)
  • ✅ Ayez un processus pour la rotation d'urgence des identifiants
  • ✅ Mettez à jour les identifiants dans Beedeez et votre point de terminaison

Liste Blanche d'IP (Amélioration Future)

Bien que non implémenté actuellement, le schéma de configuration des webhooks inclut le support pour la liste blanche d'IP :

{
"security": {
"allowedIps": ["203.0.113.1", "203.0.113.2"]
}
}

Cette fonctionnalité vous permettra de restreindre la livraison des webhooks à des adresses IP spécifiques. Contactez le support si vous avez besoin de cette fonctionnalité.

Dépannage de l'Authentification

Erreurs 401 Non Autorisé

Si votre point de terminaison retourne des erreurs 401 :

  1. Vérifiez que les identifiants d'authentification dans Beedeez correspondent à votre point de terminaison
  2. Vérifiez que le type d'authentification est configuré correctement
  3. Assurez-vous que votre point de terminaison valide correctement l'en-tête d'authentification
  4. Vérifiez les fautes de frappe dans les tokens ou mots de passe

Erreurs 403 Interdit

Si votre point de terminaison retourne des erreurs 403 :

  1. Vérifiez les restrictions IP ou les règles de pare-feu
  2. Vérifiez la logique de validation des en-têtes personnalisés
  3. Assurez-vous que la source de la requête est autorisée

L'Authentification ne Fonctionne pas

  1. Testez avec curl : Envoyez une requête de test à votre point de terminaison avec les mêmes en-têtes que Beedeez utilise
  2. Vérifiez les Logs : Consultez les logs de Beedeez et de votre point de terminaison
  3. Vérifiez HTTPS : Assurez-vous que votre point de terminaison utilise HTTPS valide
  4. Testez les Identifiants : Vérifiez que les identifiants fonctionnent isolément

Exemple de test curl :

curl -X POST https://votre-endpoint.com/webhooks/beedeez \
-H "Authorization: Bearer votre-token" \
-H "Content-Type: application/json" \
-d '{"test": "payload"}'

Exemples d'Implémentation

Node.js/Express avec Bearer Token

const express = require('express');
const app = express();

app.use(express.json());

const WEBHOOK_TOKEN = process.env.BEEDEEZ_WEBHOOK_TOKEN;

app.post('/webhooks/beedeez', (req, res) => {
// Valider l'authentification
const authHeader = req.headers.authorization;
if (!authHeader || authHeader !== `Bearer ${WEBHOOK_TOKEN}`) {
return res.status(401).json({ error: 'Non autorisé' });
}

// Traiter le webhook
const payload = req.body;
console.log('Webhook reçu:', payload);

// Répondre rapidement
res.status(200).json({ received: true });

// Traiter de manière asynchrone
processWebhookAsync(payload);
});

app.listen(3000);

Python/Flask avec Clé API

from flask import Flask, request, jsonify
import os

app = Flask(__name__)

WEBHOOK_API_KEY = os.environ.get('BEEDEEZ_WEBHOOK_API_KEY')

@app.route('/webhooks/beedeez', methods=['POST'])
def handle_webhook():
# Valider l'authentification
api_key = request.headers.get('X-API-Key')
if api_key != WEBHOOK_API_KEY:
return jsonify({'error': 'Non autorisé'}), 401

# Traiter le webhook
payload = request.get_json()
print(f'Webhook reçu: {payload}')

# Répondre rapidement
return jsonify({'received': True}), 200

if __name__ == '__main__':
app.run(port=3000)

Prochaines Étapes