次の方法で共有


Webhook エンドポイントをセキュリティで保護する方法

メッセージのエンドツーエンドの配信をセキュリティで保護することは、システム間で送信される機密情報の機密性、整合性、および信頼性を確保するために重要です。 リモート システムから受信した情報を信頼できるか、または信頼しようとするかは、送信者が ID を提供することに左右されます。 Call Automation では、 セキュリティで保護できるイベントを通信する 2 つの方法があります。Azure Event Grid より送信される共有 IncomingCall イベントや Webhook 経由で Call Automation プラットフォームより送信されるその他のすべての通話中イベントを配信できます。

着信呼び出しイベント

Azure Communication Services は、 Azure Event Grid サブスクリプションに依存して IncomingCall イベント を配信します。 Webhook サブスクリプションをセキュリティで保護する方法については、「Azure Event Grid チームのドキュメント」を参照してください。

Call Automation の Webhook イベント

Call Automation イベント は、着信に応答するか、新しい発信通話を行ったときに指定された Webhook コールバック URI に送信されます。 コールバック URI は、有効な HTTPS 証明書、DNS 名、IP アドレスを持つパブリック エンドポイントで、適切なファイアウォール ポートを開いて 、Call Automation がアクセスできるようにする必要があります。 この匿名のパブリック Web サーバーは、承認されていないアクセスから保護するために必要な手順を実行しないと、セキュリティ リスクが発生する可能性があります。

このセキュリティを向上させる一般的な方法は、API KEY メカニズムを実装することです。 Web サーバーは、実行時にキーを生成し、呼び出しに応答または発信するときにクエリ パラメーターとしてコールバック URI にキーを指定できます。 Web サーバーは、アクセスを許可する前に、Call Automation からの Webhook コールバックのキーを確認できます。 より多くのセキュリティ対策が必要なお客様もいます。 このような場合、境界ネットワーク デバイスでは、Web サーバーまたはアプリケーション本体とは別に、インバウンド Webhook を確認できます。 API キー メカニズムだけでは不十分な場合があります。

Call Automation Webhook コールバック セキュリティの向上

Call Automation から送信される呼び出し中の各 Webhook コールバックは、インバウンド HTTPS 要求の認証ヘッダーに署名された JSON Web トークン (JWT) を使用します。 標準の Open ID Connect (OIDC) JWT 検証を使用して、次のようにトークンの整合性を確保できます。 JWT の有効期間は 5 分で、コールバック URI に送信されるすべてのイベントに対して新しいトークンが作成されます。

  1. Open ID 設定 URL を取得する: https://acscallautomation.communication.azure.com/calling/.well-known/acsopenidconfiguration
  2. Microsoft.AspNetCore.Authentication.JwtBearer NuGet パッケージをインストールします。
  3. NuGet パッケージと Azure Communication Services リソースの構成を使用して JWT を検証するようにアプリケーションを設定します。 JWT ペイロードにある audience 値が必要です。
  4. 発行者、対象ユーザー、JWT トークンを検証します。
    • 対象ユーザーは、Call Automation クライアントの設定に使用した Azure Communication Services リソース ID です。 取得方法については、「 こちら」を参照してください。
    • OpenId 構成の JSON Web キー セット (JWKS) エンドポイントには、JWT トークンの検証に使用されるキーが含まれています。 署名が有効で、トークンの有効期限が切れていない場合 (生成から 5 分以内)、クライアントはトークンを使って承認できます。

このサンプル コードでは、 Microsoft.IdentityModel.Protocols.OpenIdConnect を使用して webhook ペイロードを検証する方法を示します

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

Call Automation Webhook コールバック セキュリティの向上

Call Automation から送信される呼び出し中の各 Webhook コールバックは、インバウンド HTTPS 要求の認証ヘッダーに署名された JSON Web トークン (JWT) を使用します。 標準の Open ID Connect (OIDC) JWT 検証を使用して、次のようにトークンの整合性を確保できます。 JWT の有効期間は 5 分で、コールバック URI に送信されるすべてのイベントに対して新しいトークンが作成されます。

  1. Open ID 設定 URL を取得する: https://acscallautomation.communication.azure.com/calling/.well-known/acsopenidconfiguration
  2. 次の例では、プロジェクト ビルド ツールの Maven を搭載した spring initializr を使用して作成された Spring フレームワークを使用します。
  3. 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. JWT と Azure Communication Services リソースの構成を検証するようにアプリケーションを設定します。 JWT ペイロードにある audience 値が必要です。
  2. 発行者、対象ユーザー、JWT トークンを検証します。
    • 対象ユーザーは、Call Automation クライアントの設定に使用した Azure Communication Services リソース ID です。 取得方法については、「 こちら」を参照してください。
    • OpenId 構成の JSON Web キー セット (JWKS) エンドポイントには、JWT トークンの検証に使用されるキーが含まれています。 署名が有効で、トークンの有効期限が切れていない場合 (生成から 5 分以内)、クライアントはトークンを使って承認できます。

このサンプル コードでは、JWT を使用して webhook ペイロードを検証するために、OIDC クライアントを設定する方法を示します

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

Call Automation Webhook コールバック セキュリティの向上

Call Automation から送信される呼び出し中の各 Webhook コールバックは、インバウンド HTTPS 要求の認証ヘッダーに署名された JSON Web トークン (JWT) を使用します。 標準の Open ID Connect (OIDC) JWT 検証を使用して、次のようにトークンの整合性を確保できます。 JWT の有効期間は 5 分で、コールバック URI に送信されるすべてのイベントに対して新しいトークンが作成されます。

  1. Open ID 設定 URL を取得する: https://acscallautomation.communication.azure.com/calling/.well-known/acsopenidconfiguration
  2. 次のパッケージをインストールします。
npm install express jwks-rsa jsonwebtoken
  1. JWT と Azure Communication Services リソースの構成を検証するようにアプリケーションを設定します。 JWT ペイロードにある audience 値が必要です。
  2. 発行者、対象ユーザー、JWT トークンを検証します。
    • 対象ユーザーは、Call Automation クライアントの設定に使用した Azure Communication Services リソース ID です。 取得方法については、「 こちら」を参照してください。
    • OpenId 構成の JSON Web キー セット (JWKS) エンドポイントには、JWT トークンの検証に使用されるキーが含まれています。 署名が有効で、トークンの有効期限が切れていない場合 (生成から 5 分以内)、クライアントはトークンを使って承認できます。

このサンプル コードでは、JWT を使用して webhook ペイロードを検証するために、OIDC クライアントを設定する方法を示します

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

Call Automation Webhook コールバック セキュリティの向上

Call Automation から送信される呼び出し中の各 Webhook コールバックは、インバウンド HTTPS 要求の認証ヘッダーに署名された JSON Web トークン (JWT) を使用します。 標準の Open ID Connect (OIDC) JWT 検証を使用して、次のようにトークンの整合性を確保できます。 JWT の有効期間は 5 分で、コールバック URI に送信されるすべてのイベントに対して新しいトークンが作成されます。

  1. Open ID 設定 URL を取得する: https://acscallautomation.communication.azure.com/calling/.well-known/acsopenidconfiguration
  2. 次のパッケージをインストールします。
pip install flask pyjwt
  1. JWT と Azure Communication Services リソースの構成を検証するようにアプリケーションを設定します。 JWT ペイロードにある audience 値が必要です。
  2. 発行者、対象ユーザー、JWT トークンを検証します。
    • 対象ユーザーは、Call Automation クライアントの設定に使用した Azure Communication Services リソース ID です。 取得方法については、「 こちら」を参照してください。
    • OpenId 構成の JSON Web キー セット (JWKS) エンドポイントには、JWT トークンの検証に使用されるキーが含まれています。 署名が有効で、トークンの有効期限が切れていない場合 (生成から 5 分以内)、クライアントはトークンを使って承認できます。

このサンプル コードでは、JWT を使用して webhook ペイロードを検証するために、OIDC クライアントを設定する方法を示します

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

次のステップ