Delen via


Webhook-eindpunt beveiligen

Het beveiligen van de bezorging van berichten van end-to-end is van cruciaal belang voor het waarborgen van de vertrouwelijkheid, integriteit en betrouwbaarheid van gevoelige informatie die tussen systemen wordt verzonden. Uw vermogen en bereidheid om informatie te vertrouwen die is ontvangen van een extern systeem, is afhankelijk van de afzender die zijn identiteit verstrekt. Oproepautomatisering heeft twee manieren om gebeurtenissen te communiceren die kunnen worden beveiligd; de gedeelde IncomingCall-gebeurtenis die is verzonden door Azure Event Grid en alle andere gebeurtenissen in het middengesprek die worden verzonden door het Call Automation-platform via webhook.

Gebeurtenis voor binnenkomende oproep

Azure Communication Services is afhankelijk van Azure Event Grid-abonnementen om de IncomingCall-gebeurtenis te leveren. Raadpleeg het Azure Event Grid-team voor hun documentatie over het beveiligen van een webhookabonnement.

Webhook-gebeurtenissen voor Automation aanroepen

Oproepautomatisering-gebeurtenissen worden verzonden naar de webhook callback-URI die is opgegeven wanneer u een oproep beantwoordt of een nieuwe uitgaande oproep plaatst. Uw callback-URI moet een openbaar eindpunt zijn met een geldig HTTPS-certificaat, een DNS-naam en een IP-adres met de juiste firewallpoorten die zijn geopend om Oproepautomatisering in te schakelen. Deze anonieme openbare webserver kan een beveiligingsrisico vormen als u de benodigde stappen niet uitvoert om deze te beveiligen tegen onbevoegde toegang.

Een veelgebruikte manier om deze beveiliging te verbeteren, is door een API KEY-mechanisme te implementeren. Uw webserver kan de sleutel tijdens runtime genereren en deze in de callback-URI opgeven als een queryparameter wanneer u een aanroep beantwoordt of maakt. Uw webserver kan de sleutel in de webhook-callback van Call Automation controleren voordat toegang wordt toegestaan. Sommige klanten hebben meer beveiligingsmaatregelen nodig. In dergelijke gevallen kan een perimeternetwerkapparaat de binnenkomende webhook verifiëren, gescheiden van de webserver of toepassing zelf. Het MECHANISME voor API-sleutels is mogelijk niet voldoende.

Beveiliging van callback van Call Automation-webhook verbeteren

Elke mid-call webhook callback die door Call Automation wordt verzonden, maakt gebruik van een ondertekend JSON-webtoken (JWT) in de verificatieheader van de binnenkomende HTTPS-aanvraag. U kunt standaard JWT-validatietechnieken voor Open ID Verbinding maken (OIDC) gebruiken om de integriteit van het token als volgt te garanderen. De levensduur van de JWT is vijf (5) minuten en er wordt een nieuw token gemaakt voor elke gebeurtenis die naar de callback-URI wordt verzonden.

  1. Haal de Open ID-configuratie-URL op: https://acscallautomation.communication.azure.com/calling/.well-known/acsopenidconfiguration
  2. Installeer het NuGet-pakket Microsoft.AspNetCore.Authentication.JwtBearer.
  3. Configureer uw toepassing om de JWT te valideren met behulp van het NuGet-pakket en de configuratie van uw Azure Communication Services-resource. U hebt de audience waarden nodig zoals deze aanwezig zijn in de JWT-nettolading.
  4. Valideer de uitgever, doelgroep en het JWT-token.
    • De doelgroep is uw Azure Communication Services-resource-id die u hebt gebruikt om uw Call Automation-client in te stellen. Raadpleeg hier hoe u het kunt krijgen.
    • Het JSON Web Key Set-eindpunt (JWKS) in de OpenId-configuratie bevat de sleutels die worden gebruikt om het JWT-token te valideren. Wanneer de handtekening geldig is en het token niet is verlopen (binnen 5 minuten na het genereren), kan de client het token gebruiken voor autorisatie.

Deze voorbeeldcode laat zien hoe Microsoft.IdentityModel.Protocols.OpenIdConnect u de nettolading van de webhook valideert

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

// Add Azure Communication Services CallAutomation OpenID configuration
var configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(
            builder.Configuration["OpenIdConfigUrl"],
            new OpenIdConnectConfigurationRetriever());
var configuration = configurationManager.GetConfigurationAsync().Result;

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.Configuration = configuration;
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidAudience = builder.Configuration["AllowedAudience"]
        };
    });

builder.Services.AddAuthorization();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.MapPost("/api/callback", (CloudEvent[] events) =>
{
    // Your implementation on the callback event
    return Results.Ok();
})
.RequireAuthorization()
.WithOpenApi();

app.UseAuthentication();
app.UseAuthorization();

app.Run();

Beveiliging van callback van Call Automation-webhook verbeteren

Elke mid-call webhook callback die door Call Automation wordt verzonden, maakt gebruik van een ondertekend JSON-webtoken (JWT) in de verificatieheader van de binnenkomende HTTPS-aanvraag. U kunt standaard JWT-validatietechnieken voor Open ID Verbinding maken (OIDC) gebruiken om de integriteit van het token als volgt te garanderen. De levensduur van de JWT is vijf (5) minuten en er wordt een nieuw token gemaakt voor elke gebeurtenis die naar de callback-URI wordt verzonden.

  1. Haal de Open ID-configuratie-URL op: https://acscallautomation.communication.azure.com/calling/.well-known/acsopenidconfiguration
  2. In het volgende voorbeeld wordt Spring Framework gebruikt, gemaakt met spring initializr met Maven als projectbuildhulpprogramma.
  3. Voeg de volgende afhankelijkheden toe in uw pom.xml:
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-security</artifactId>
  </dependency>
  <dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-oauth2-jose</artifactId>
  </dependency>
  <dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-oauth2-resource-server</artifactId>
  </dependency>
  1. Configureer uw toepassing om de JWT en de configuratie van uw Azure Communication Services-resource te valideren. U hebt de audience waarden nodig zoals deze aanwezig zijn in de JWT-nettolading.
  2. Valideer de uitgever, doelgroep en het JWT-token.
    • De doelgroep is uw Azure Communication Services-resource-id die u hebt gebruikt om uw Call Automation-client in te stellen. Raadpleeg hier hoe u het kunt krijgen.
    • Het JSON Web Key Set-eindpunt (JWKS) in de OpenId-configuratie bevat de sleutels die worden gebruikt om het JWT-token te valideren. Wanneer de handtekening geldig is en het token niet is verlopen (binnen 5 minuten na het genereren), kan de client het token gebruiken voor autorisatie.

Deze voorbeeldcode laat zien hoe u de OIDC-client configureert om de nettolading van de webhook te valideren met behulp van JWT

package callautomation.example.security;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult;
import org.springframework.security.oauth2.jwt.*;

@EnableWebSecurity
public class TokenValidationConfiguration {
    @Value("ACS resource ID")
    private String audience;

    @Value("https://acscallautomation.communication.azure.com")
    private String issuer;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .mvcMatchers("/api/callbacks").permitAll()
                .anyRequest()
                .and()
                .oauth2ResourceServer()
                .jwt()
                .decoder(jwtDecoder());

        return http.build();
    }

    class AudienceValidator implements OAuth2TokenValidator<Jwt> {
        private String audience;

        OAuth2Error error = new OAuth2Error("invalid_token", "The required audience is missing", null);

        public AudienceValidator(String audience) {
            this.audience = audience;
        }

        @Override
        public OAuth2TokenValidatorResult validate(Jwt token) {
            if (token.getAudience().contains(audience)) {
                return OAuth2TokenValidatorResult.success();
            } else {
                return OAuth2TokenValidatorResult.failure(error);
            }
        }
    }

    JwtDecoder jwtDecoder() {
        OAuth2TokenValidator<Jwt> withAudience = new AudienceValidator(audience);
        OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(issuer);
        OAuth2TokenValidator<Jwt> validator = new DelegatingOAuth2TokenValidator<>(withAudience, withIssuer);

        NimbusJwtDecoder jwtDecoder = (NimbusJwtDecoder) JwtDecoders.fromOidcIssuerLocation(issuer);
        jwtDecoder.setJwtValidator(validator);

        return jwtDecoder;
    }
}

Beveiliging van callback van Call Automation-webhook verbeteren

Elke mid-call webhook callback die door Call Automation wordt verzonden, maakt gebruik van een ondertekend JSON-webtoken (JWT) in de verificatieheader van de binnenkomende HTTPS-aanvraag. U kunt standaard JWT-validatietechnieken voor Open ID Verbinding maken (OIDC) gebruiken om de integriteit van het token als volgt te garanderen. De levensduur van de JWT is vijf (5) minuten en er wordt een nieuw token gemaakt voor elke gebeurtenis die naar de callback-URI wordt verzonden.

  1. Haal de Open ID-configuratie-URL op: https://acscallautomation.communication.azure.com/calling/.well-known/acsopenidconfiguration
  2. Installeer de volgende pakketten:
npm install express jwks-rsa jsonwebtoken
  1. Configureer uw toepassing om de JWT en de configuratie van uw Azure Communication Services-resource te valideren. U hebt de audience waarden nodig zoals deze aanwezig zijn in de JWT-nettolading.
  2. Valideer de uitgever, doelgroep en het JWT-token.
    • De doelgroep is uw Azure Communication Services-resource-id die u hebt gebruikt om uw Call Automation-client in te stellen. Raadpleeg hier hoe u het kunt krijgen.
    • Het JSON Web Key Set-eindpunt (JWKS) in de OpenId-configuratie bevat de sleutels die worden gebruikt om het JWT-token te valideren. Wanneer de handtekening geldig is en het token niet is verlopen (binnen 5 minuten na het genereren), kan de client het token gebruiken voor autorisatie.

Deze voorbeeldcode laat zien hoe u de OIDC-client configureert om de nettolading van de webhook te valideren met behulp van JWT

import express from "express";
import { JwksClient } from "jwks-rsa";
import { verify } from "jsonwebtoken";

const app = express();
const port = 3000;
const audience = "ACS resource ID";
const issuer = "https://acscallautomation.communication.azure.com";

app.use(express.json());

app.post("/api/callback", (req, res) => {
    const token = req?.headers?.authorization?.split(" ")[1] || "";

    if (!token) {
        res.sendStatus(401);

        return;
    }

    try {
        verify(
            token,
            (header, callback) => {
                const client = new JwksClient({
                    jwksUri: "https://acscallautomation.communication.azure.com/calling/keys",
                });

                client.getSigningKey(header.kid, (err, key) => {
                    const signingKey = key?.publicKey || key?.rsaPublicKey;

                    callback(err, signingKey);
                });
            },
            {
                audience,
                issuer,
                algorithms: ["RS256"],
            });
        // Your implementation on the callback event
        res.sendStatus(200);
    } catch (error) {
        res.sendStatus(401);
    }
});

app.listen(port, () => {
    console.log(`Server running on port ${port}`);
});

Beveiliging van callback van Call Automation-webhook verbeteren

Elke mid-call webhook callback die door Call Automation wordt verzonden, maakt gebruik van een ondertekend JSON-webtoken (JWT) in de verificatieheader van de binnenkomende HTTPS-aanvraag. U kunt standaard JWT-validatietechnieken voor Open ID Verbinding maken (OIDC) gebruiken om de integriteit van het token als volgt te garanderen. De levensduur van de JWT is vijf (5) minuten en er wordt een nieuw token gemaakt voor elke gebeurtenis die naar de callback-URI wordt verzonden.

  1. Haal de Open ID-configuratie-URL op: https://acscallautomation.communication.azure.com/calling/.well-known/acsopenidconfiguration
  2. Installeer de volgende pakketten:
pip install flask pyjwt
  1. Configureer uw toepassing om de JWT en de configuratie van uw Azure Communication Services-resource te valideren. U hebt de audience waarden nodig zoals deze aanwezig zijn in de JWT-nettolading.
  2. Valideer de uitgever, doelgroep en het JWT-token.
    • De doelgroep is uw Azure Communication Services-resource-id die u hebt gebruikt om uw Call Automation-client in te stellen. Raadpleeg hier hoe u het kunt krijgen.
    • Het JSON Web Key Set-eindpunt (JWKS) in de OpenId-configuratie bevat de sleutels die worden gebruikt om het JWT-token te valideren. Wanneer de handtekening geldig is en het token niet is verlopen (binnen 5 minuten na het genereren), kan de client het token gebruiken voor autorisatie.

Deze voorbeeldcode laat zien hoe u de OIDC-client configureert om de nettolading van de webhook te valideren met behulp van JWT

from flask import Flask, jsonify, abort, request
import jwt

app = Flask(__name__)


@app.route("/api/callback", methods=["POST"])
def handle_callback_event():
    token = request.headers.get("authorization").split()[1]

    if not token:
        abort(401)

    try:
        jwks_client = jwt.PyJWKClient(
            "https://acscallautomation.communication.azure.com/calling/keys"
        )
        jwt.decode(
            token,
            jwks_client.get_signing_key_from_jwt(token).key,
            algorithms=["RS256"],
            issuer="https://acscallautomation.communication.azure.com",
            audience="ACS resource ID",
        )
        # Your implementation on the callback event
        return jsonify(success=True)
    except jwt.InvalidTokenError:
        print("Token is invalid")
        abort(401)
    except Exception as e:
        print("uncaught exception" + e)
        abort(500)


if __name__ == "__main__":
    app.run()

Volgende stappen