AutoMate Technisch Help

Webhook Push Connector — Authenticatie Architectuur

Overzicht

De webhook push connector stelt externe HR-systemen in staat om medewerkersdata actief naar AutoMate te pushen via HTTP-aanroepen. Omdat de webhook-endpoint publiek bereikbaar moet zijn voor externe systemen, zijn er twee afzonderlijke authenticatielagen ingericht die samen een defence-in-depth strategie vormen.

AutoMate API (Intern)

Management Portal (Publiek bereikbaar)

tenant-id + Authentication header\n+ optioneel IP-check

Haal config op

WebhookSecret + IpSafeList

Payload wrappen\n+ X-Tenant-Id header

POST/DELETE iam/webhooks/employees

Valideer key + SetTenantId

Extern HR-systeem\n(POST/DELETE met payload)

WebhooksController\n(API-Webhooks/Employees)

GET iam/webhooks/settings\n(intern, anonymous + key)

WebhooksBackend HttpClient\n(X-Internal-Api-Key als default header)

WebhookInternalAuthProcessor\n(GlobalPreProcessor)

Webhook Endpoints\n/iam/webhooks/*

De twee lagen zijn bewust van elkaar gescheiden: laag 1 beschermt het externe inkomende verkeer via een HMAC-token en een optionele IP-safelist, laag 2 beschermt de interne API-endpoints zodat ze nooit direct van buitenaf bereikbaar zijn zonder de portaalproxy.

Laag 1 — Externe Authenticatie (WebhooksController)

Locatie van WebhooksController

Portals/ManagementPortal/Src/ManagementPortal.Website/Controllers/WebhooksController.cs

Inkomend verzoek

Externe systemen sturen hun aanroepen naar de Management Portal, niet rechtstreeks naar de API:

HTTP-methode

URL (portal)

Gedrag

POST

API-Webhooks/Employees

Push (aanmaken/wijzigen)

DELETE

API-Webhooks/Employees

Soft delete

POST

API-Webhooks/Employees?dry-run=true

Dry-run push

DELETE

API-Webhooks/Employees?dry-run=true

Dry-run soft delete

DELETE

API-Webhooks/Employees/Force

Hard delete

DELETE

API-Webhooks/Employees/Force?dry-run=true

Hard delete dry-run

Validatiestappen

De WebhooksController voert de volgende controles uit vóór het doorstuuren van het verzoek:

Nee

Ja

Nee

Ja

Nee

Ja

Ja

Nee

Ja

Nee

Nee

Ja

Nee

Ja

Inkomend verzoek

tenant-id header aanwezig?

401 Unauthorized

Geldige GUID?

401 Unauthorized

Haal webhook config op\nvia GET iam/webhooks/settings

Config beschikbaar\nen geconfigureerd?

401 Unauthorized

IpSafeList ingesteld?

IP-adres in safelist?

403 Forbidden

Authentication header\naanwezig?

401 Unauthorized

HMAC-token geldig?

401 Unauthorized

Doorsturen naar API\nmet X-Internal-Api-Key

HMAC-token verificatie

Het authenticatietoken wordt berekend via WebhookAuthenticationHelper.GetToken(string password, Guid tenantId), geïmplementeerd in zowel de portal (ManagementPortal.Website/Helpers/) als de API (Features/IAM/Webhooks/Helpers/).

public static string GetToken(string password, Guid tenantId) { var hash = Rfc2898DeriveBytes.Pbkdf2( password, GetSaltFromTenantId(tenantId), 350000, HashAlgorithmName.SHA256, 64); return Convert.ToBase64String(hash); } private static byte[] GetSaltFromTenantId(Guid tenantId) { return Encoding.UTF8.GetBytes(tenantId.ToString().Replace('-', '~')); }

Parameter

Waarde

Algoritme

PBKDF2 / RFC 2898

Hash-functie

SHA-256

Iteraties

350.000

Output lengte

64 bytes (Base64-gecodeerd)

Salt

Tenant-GUID als UTF-8 bytes (koppeltekens vervangen door ~)

Sleutel

WebhookSecret uit de tenant webhook-configuratie

De tokenvalidatie gebruikt CryptographicOperations.FixedTimeEquals voor constante-tijd vergelijking om timing-aanvallen te voorkomen.

IP-safelist

Als IpSafeList geconfigureerd is in de tenant webhook-instellingen, wordt het IPv4-adres van de beller vergeleken met de puntkomma-gescheiden lijst. IPv4-gemapte IPv6-adressen worden automatisch omgezet naar IPv4 vóór de vergelijking. Verzoeken van niet-gewhitelistede IP-adressen krijgen 403 Forbidden.

Payload transformatie

Na succesvolle validatie wikkelt de controller de originele payload in een Payload-object:

{ "Payload": [ /* originele array of object */ ] }

Het verzoek wordt doorgestuurd via de named HttpClient("WebhooksBackend") inclusief:

  • X-Tenant-Id header met de gevalideerde tenant-GUID

  • X-Internal-Api-Key als default header (automatisch door de HttpClient-registratie)

  • Accept-Language header overgenomen uit de huidige cultuur

Laag 2 — Interne Authenticatie (WebhookInternalAuthProcessor)

Locatie van WebhookInternalAuthProcessor

API/Src/AutoMate.API/Processors/WebhookInternalAuthProcessor.cs

Werking

De WebhookInternalAuthProcessor is een FastEndpoints IGlobalPreProcessor die alle inkomende verzoeken naar /iam/webhooks/* onderschept, met uitzondering van /iam/webhooks/configuration.

public sealed class WebhookInternalAuthProcessor : IGlobalPreProcessor { private const string WebhookPathPrefix = "/iam/webhooks"; private const string ConfigurationPathPrefix = "/iam/webhooks/configuration"; public async Task PreProcessAsync(IPreProcessorContext ctx, CancellationToken ct) { // Alleen paden onder /iam/webhooks verwerken if (!httpContext.Request.Path.StartsWithSegments(WebhookPathPrefix, ...)) return; // /iam/webhooks/configuration gebruikt JWT, niet de interne key if (httpContext.Request.Path.StartsWithSegments(ConfigurationPathPrefix, ...)) return; // 1. Valideer X-Internal-Api-Key (constante-tijd vergelijking) var expectedKey = config["Webhooks:InternalApiKey"] ?? string.Empty; var providedKey = httpContext.Request.Headers["X-Internal-Api-Key"].ToString(); if (!CryptographicOperations.FixedTimeEquals(...)) { // 401 Unauthorized return; } // 2. Extraheer tenant uit X-Tenant-Id en zet tenant context multiTenantService.SetTenantId(tenantId); // 3. Push TenantId naar Serilog log context scopes.Add(LogContext.PushProperty("TenantId", tenantId)); } }

De processor vervangt hier het normale TenantGuard-mechanisme: omdat webhook-endpoints [AllowAnonymous] zijn (ze hebben geen JWT-sessie), slaat TenantGuard ze over. De WebhookInternalAuthProcessor neemt deze taak over door expliciet IMultiTenantService.SetTenantId(tenantId) aan te roepen.

Tenant context

Na succesvolle validatie is de tenant context beschikbaar via IMultiTenantService voor alle downstream services en endpoint-handlers — exact hetzelfde mechanisme als bij gewone API-endpoints met de X-Tenant-Id header. Zie ook de platformdocumentatie over Multi-Tenancy.

Endpoint Overzicht

Methode

Pad

Auth

Beschrijving

GET

/iam/webhooks/configuration

Identity (JWT)

Wizard: configuratie tonen/beheren

GET

/iam/webhooks/settings

[AllowAnonymous] + intern key

Portal proxy haalt config op

POST

/iam/webhooks/employees

Intern key + tenant header

Push: medewerkers aanmaken/wijzigen

DELETE

/iam/webhooks/employees

Intern key + tenant header

Soft delete medewerkers

POST

/iam/webhooks/employees/dry-run

Intern key + tenant header

Dry-run push zonder schrijven

DELETE

/iam/webhooks/employees/dry-run

Intern key + tenant header

Dry-run soft delete

DELETE

/iam/webhooks/employees/force

Intern key + tenant header

Hard delete medewerkers

DELETE

/iam/webhooks/employees/force/dry-run

Intern key + tenant header

Dry-run hard delete

Configuratie

Beide de portal en de API lezen Webhooks:InternalApiKey uit hun respectievelijke configuratie. De waarden moeten identiek zijn.

Setting

Component

Beschrijving

Webhooks:InternalApiKey

Management Portal

Wordt als default header op WebhooksBackend HttpClient gezet

Webhooks:InternalApiKey

AutoMate API

Verwachte waarde in WebhookInternalAuthProcessor

HttpClient registratie (portal Program.cs)

builder.Services.AddHttpClient("WebhooksBackend", client => { client.BaseAddress = new Uri("http+https://api"); client.DefaultRequestHeaders.Add("api-version", "v1"); var internalApiKey = builder.Configuration["Webhooks:InternalApiKey"]; if (!string.IsNullOrEmpty(internalApiKey)) client.DefaultRequestHeaders.Add("X-Internal-Api-Key", internalApiKey); });

De X-Internal-Api-Key wordt eenmalig ingesteld bij registratie van de HttpClient en wordt automatisch meegestuurd met alle verzoeken van WebhooksController naar de API — zonder dat de controller daar expliciet iets voor hoeft te doen.

Gerelateerde pagina's

Last modified: 29 May 2026