Teilen über


Schützen des Webhook-Endpunkts

Die Sicherung der Zustellung von Nachrichten von Ende bis Ende ist entscheidend für die Gewährleistung der Vertraulichkeit, Integrität und Vertrauenswürdigkeit vertraulicher Informationen, die zwischen Systemen übertragen werden. Ihre Fähigkeit und Bereitschaft, informationen, die von einem Remotesystem empfangen werden, vertrauen auf den Absender, der seine Identität bereitstellt. Die Anrufautomatisierung verfügt über zwei Arten der Kommunikation von Ereignissen, die gesichert werden können. das freigegebene IncomingCall-Ereignis, das von Azure Event Grid gesendet wird, und alle anderen Mid-Call-Ereignisse, die von der Anrufautomatisierungsplattform über Webhook gesendet werden.

Eingehendes Anrufereignis

Azure Communication Services basiert auf Azure Event Grid-Abonnements, um das IncomingCall-Ereignis bereitzustellen. Informationen zum Sichern eines Webhook-Abonnements finden Sie im Azure Event Grid-Team.

Webhookereignisse der Anrufautomatisierung

Anrufautomatisierungs-Ereignisse werden an den Webhook-Rückruf-URI gesendet, der angegeben wird, wenn Sie einen Anruf annehmen oder einen neuen ausgehenden Anruf tätigen. Ihr Rückruf-URI muss ein öffentlicher Endpunkt mit einem gültigen HTTPS-Zertifikat, DNS-Namen und einer IP-Adresse sein, wobei die richtigen Firewallports geöffnet sind, um die Anrufautomatisierung zu erreichen. Dieser anonyme öffentliche Webserver könnte ein Sicherheitsrisiko erstellen, wenn Sie nicht die erforderlichen Schritte ausführen, um ihn vor unbefugtem Zugriff zu schützen.

Eine gängige Möglichkeit, diese Sicherheit zu verbessern, besteht darin, einen API KEY-Mechanismus zu implementieren. Ihr Webserver kann den Schlüssel zur Laufzeit generieren und ihn im Rückruf-URI als Abfrageparameter bereitstellen, wenn Sie einen Anruf annehmen oder erstellen. Ihr Webserver kann den Schlüssel im Webhook-Rückruf über die Anrufautomatisierung überprüfen, bevor der Zugriff zugelassen wird. Einige Kunden benötigen mehr Sicherheitsmaßnahmen. In diesen Fällen kann ein Umkreisnetzwerkgerät den eingehenden Webhook unabhängig vom Webserver oder der Anwendung selbst überprüfen. Der API-Schlüsselmechanismus allein reicht möglicherweise nicht aus.

Verbessern der Anrufautomatisierungs-Webhook-Rückrufsicherheit

Jeder mid-call-Webhook-Rückruf, der von der Anrufautomatisierung gesendet wird, verwendet ein signiertes JSON-Webtoken (JWT) im Authentifizierungsheader der eingehenden HTTPS-Anforderung. Sie können standardmäßige Open ID-Verbinden (OIDC) JWT-Validierungstechniken verwenden, um die Integrität des Tokens wie folgt sicherzustellen. Die Lebensdauer des JWT beträgt fünf (5) Minuten, und für jedes Ereignis, das an den Rückruf-URI gesendet wird, wird ein neues Token erstellt.

  1. Rufen Sie die Open ID-Konfigurations-URL ab: https://acscallautomation.communication.azure.com/calling/.well-known/acsopenidconfiguration
  2. Installieren Sie das Microsoft.AspNetCore.Authentication.JwtBearer NuGet-Paket .
  3. Konfigurieren Sie Ihre Anwendung, um das JWT mithilfe des NuGet-Pakets und der Konfiguration Ihrer Azure Communication Services-Ressource zu überprüfen. Sie benötigen die audience Werte, da sie in der JWT-Nutzlast vorhanden sind.
  4. Überprüfen Sie den Aussteller, die Zielgruppe und das JWT-Token.
    • Die Zielgruppe ist Ihre Azure Communication Services-Ressourcen-ID, die Sie zum Einrichten Ihres Anrufautomatisierungs-Clients verwendet haben. Hier erfahren Sie, wie Sie es erhalten.
    • Der JSON Web Key Set (JWKS)-Endpunkt in der OpenId-Konfiguration enthält die Schlüssel, die zum Überprüfen des JWT-Tokens verwendet werden. Wenn die Signatur gültig ist und das Token nicht abgelaufen ist (innerhalb von 5 Minuten nach der Generierung), kann der Client das Token für die Autorisierung verwenden.

In diesem Beispielcode wird veranschaulicht, wie Microsoft.IdentityModel.Protocols.OpenIdConnect Sie die Webhook-Nutzlast überprüfen.

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 implemenation on the callback event
    return Results.Ok();
})
.RequireAuthorization()
.WithOpenApi();

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

app.Run();

Verbessern der Anrufautomatisierungs-Webhook-Rückrufsicherheit

Jeder mid-call-Webhook-Rückruf, der von der Anrufautomatisierung gesendet wird, verwendet ein signiertes JSON-Webtoken (JWT) im Authentifizierungsheader der eingehenden HTTPS-Anforderung. Sie können standardmäßige Open ID-Verbinden (OIDC) JWT-Validierungstechniken verwenden, um die Integrität des Tokens wie folgt sicherzustellen. Die Lebensdauer des JWT beträgt fünf (5) Minuten, und für jedes Ereignis, das an den Rückruf-URI gesendet wird, wird ein neues Token erstellt.

  1. Rufen Sie die Open ID-Konfigurations-URL ab: https://acscallautomation.communication.azure.com/calling/.well-known/acsopenidconfiguration
  2. Im folgenden Beispiel wird das Spring-Framework verwendet, das mit spring initializr mit Maven als Projektbuildtool erstellt wurde.
  3. Fügen Sie die folgenden Abhängigkeiten zu Ihrem 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. Konfigurieren Sie Ihre Anwendung, um das JWT und die Konfiguration Ihrer Azure Communication Services-Ressource zu überprüfen. Sie benötigen die audience Werte, da sie in der JWT-Nutzlast vorhanden sind.
  2. Überprüfen Sie den Aussteller, die Zielgruppe und das JWT-Token.
    • Die Zielgruppe ist Ihre Azure Communication Services-Ressourcen-ID, die Sie zum Einrichten Ihres Anrufautomatisierungs-Clients verwendet haben. Hier erfahren Sie, wie Sie es erhalten.
    • Der JSON Web Key Set (JWKS)-Endpunkt in der OpenId-Konfiguration enthält die Schlüssel, die zum Überprüfen des JWT-Tokens verwendet werden. Wenn die Signatur gültig ist und das Token nicht abgelaufen ist (innerhalb von 5 Minuten nach der Generierung), kann der Client das Token für die Autorisierung verwenden.

Dieser Beispielcode veranschaulicht, wie OIDC-Client zum Überprüfen der Webhook-Nutzlast mit JWT konfiguriert wird.

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;
    }
}

Verbessern der Anrufautomatisierungs-Webhook-Rückrufsicherheit

Jeder mid-call-Webhook-Rückruf, der von der Anrufautomatisierung gesendet wird, verwendet ein signiertes JSON-Webtoken (JWT) im Authentifizierungsheader der eingehenden HTTPS-Anforderung. Sie können standardmäßige Open ID-Verbinden (OIDC) JWT-Validierungstechniken verwenden, um die Integrität des Tokens wie folgt sicherzustellen. Die Lebensdauer des JWT beträgt fünf (5) Minuten, und für jedes Ereignis, das an den Rückruf-URI gesendet wird, wird ein neues Token erstellt.

  1. Rufen Sie die Open ID-Konfigurations-URL ab: https://acscallautomation.communication.azure.com/calling/.well-known/acsopenidconfiguration
  2. Installieren Sie die folgenden Pakete:
npm install express jwks-rsa jsonwebtoken
  1. Konfigurieren Sie Ihre Anwendung, um das JWT und die Konfiguration Ihrer Azure Communication Services-Ressource zu überprüfen. Sie benötigen die audience Werte, da sie in der JWT-Nutzlast vorhanden sind.
  2. Überprüfen Sie den Aussteller, die Zielgruppe und das JWT-Token.
    • Die Zielgruppe ist Ihre Azure Communication Services-Ressourcen-ID, die Sie zum Einrichten Ihres Anrufautomatisierungs-Clients verwendet haben. Hier erfahren Sie, wie Sie es erhalten.
    • Der JSON Web Key Set (JWKS)-Endpunkt in der OpenId-Konfiguration enthält die Schlüssel, die zum Überprüfen des JWT-Tokens verwendet werden. Wenn die Signatur gültig ist und das Token nicht abgelaufen ist (innerhalb von 5 Minuten nach der Generierung), kann der Client das Token für die Autorisierung verwenden.

Dieser Beispielcode veranschaulicht, wie OIDC-Client zum Überprüfen der Webhook-Nutzlast mit JWT konfiguriert wird.

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}`);
});

Verbessern der Anrufautomatisierungs-Webhook-Rückrufsicherheit

Jeder mid-call-Webhook-Rückruf, der von der Anrufautomatisierung gesendet wird, verwendet ein signiertes JSON-Webtoken (JWT) im Authentifizierungsheader der eingehenden HTTPS-Anforderung. Sie können standardmäßige Open ID-Verbinden (OIDC) JWT-Validierungstechniken verwenden, um die Integrität des Tokens wie folgt sicherzustellen. Die Lebensdauer des JWT beträgt fünf (5) Minuten, und für jedes Ereignis, das an den Rückruf-URI gesendet wird, wird ein neues Token erstellt.

  1. Rufen Sie die Open ID-Konfigurations-URL ab: https://acscallautomation.communication.azure.com/calling/.well-known/acsopenidconfiguration
  2. Installieren Sie die folgenden Pakete:
pip install flask pyjwt
  1. Konfigurieren Sie Ihre Anwendung, um das JWT und die Konfiguration Ihrer Azure Communication Services-Ressource zu überprüfen. Sie benötigen die audience Werte, da sie in der JWT-Nutzlast vorhanden sind.
  2. Überprüfen Sie den Aussteller, die Zielgruppe und das JWT-Token.
    • Die Zielgruppe ist Ihre Azure Communication Services-Ressourcen-ID, die Sie zum Einrichten Ihres Anrufautomatisierungs-Clients verwendet haben. Hier erfahren Sie, wie Sie es erhalten.
    • Der JSON Web Key Set (JWKS)-Endpunkt in der OpenId-Konfiguration enthält die Schlüssel, die zum Überprüfen des JWT-Tokens verwendet werden. Wenn die Signatur gültig ist und das Token nicht abgelaufen ist (innerhalb von 5 Minuten nach der Generierung), kann der Client das Token für die Autorisierung verwenden.

Dieser Beispielcode veranschaulicht, wie OIDC-Client zum Überprüfen der Webhook-Nutzlast mit JWT konfiguriert wird.

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()

Nächste Schritte