主动消息端点的身份验证

Authentication for Proactive Message Endpoint

我正在构建一个需要从 Azure 函数主动触发的 Bot Framework 机器人。我已经基于 this example 将原型部署到 Azure,目前允许我 POST/api/notify REST 端点以便主动发送消息。

但是,我不确定如何向 /api/notify 端点添加身份验证。 /api/messages 端点的消息在应用程序代码中使用机器人服务 API 进行身份验证,但在该示例中,/api/notify 端点的流量没有身份验证(我可以 POST 从我的 CLI 使用 curl 到它,没有任何令牌或密码)。

我尝试在基础应用服务上启用 App Service Authentication,但我的机器人在网络聊天中不再工作。

如何向此端点添加身份验证,以便只有我的 Azure Functions 可以 POST 到它?

事实上,几周前我只是为一个内部项目设置了它。您可能需要根据您的机器人和功能所使用的任何语言来调整此策略,但这是我所做的:

Azure 函数

module.exports = class BotService {
    constructor(context) {
        this.context = context;
        // Get appId and password from environment variables to build credentials
        this.credentials = new MicrosoftAppCredentials(process.env.MicrosoftAppId, process.env.MicrosoftAppPassword);
        this.client = axios.create({
            baseURL: process.env.BotBaseUrl
        });
    }

    async sendData(body) {
        // Get the auth token using the credentials
        const token = await this.credentials.getToken();
        const response = await this.client.post('/api/data', body, {
            // Add the token to the auth header
            headers: { Authorization: `Bearer ${ token }` }
        });
        if (response.status !== 200) {
            this.context.error(JSON.stringify(response, null, 2));
        } else {
            this.context.log(`Successfully sent data to the bot. Response Code: ${ response.status }`);
        }
    }
}

Bot 注意:机器人在 C# 中,而在 /api/data

的控制器中
[HttpPost]
public async Task<HttpStatusCode> PostAsync()
{
    try
    {
        // Build the bot credentials
        var credentials = new SimpleCredentialProvider(Configuration["MicrosoftAppId"], Configuration["MicrosoftAppPassword"]);
        // Grab the auth header from the request
        Request.Headers.TryGetValue("Authorization", out StringValues authHeader);
        // Use Microsoft.Bot.Connector.Authentication.JwtTokenValidation to validate the auth header
        var result = await JwtTokenValidation.ValidateAuthHeader(authHeader, credentials, new SimpleChannelProvider(), Channels.Directline);

        if (result.IsAuthenticated)
        {
            // Do stuff
            // Do stuff
            return HttpStatusCode.OK;
        }

        return HttpStatusCode.Forbidden;
    }
    catch (Exception e)
    {
        Logger.LogError($"Something went wrong in /api/data controller: {e.Message}");
    }
    return HttpStatusCode.BadRequest;
}

您的机器人似乎在 Python。可以看到similar auth validation in one of our Python tests