Closed xianlin closed 6 months ago
@xianlin Your steps look correct. Did your m365 account and Azure account belong to the same tenant?
Yes both my m365 account and Azure account are under the same tenant ID
Hi @xianlin,
I can make the bot work using your steps above. Could you please double check MicrosoftAppTenantId: config.tenantId
is correctly loaded? and your account which installed this app also belongs to your tenant?
Sure I'll check it again. Thanks
@yukun-dong , I tried again but still encountered 401 error when tried run "curl -X POST https://my_bot_web_app/api/notification". My account installed with this bot web app belongs to the correct tenant and it is successfully loaded to the Nodejs code.
Here is a snippet of my 401 error:
{ "body": { "type": "message", "serviceUrl": "https://smba.trafficmanager.net/emea/", "channelId": "msteams", "from": { "id": "28:4f026db4-208d-46e6-bf70-MASKED_FOR_PRIVACY", "name": "MY_BOT_TEST" }, "conversation": { "conversationType": "personal", "id": "a:116XtG9a4x2E4TUdg8fRrGS-bYPJeDZg8PzJDyxIZSgVTKfQzZeRK7BsHw71A6_Wl9HAvYfAuMpopAtX97iFpR54Tb6aCfJA0s-SfNitEtNr90-MASKED_FOR_PRIVACY", "tenantId": "01c999f0-c6f3-47dc-92cf-MASKED_FOR_PRIVACY" }, "recipient": { "id": "29:1ztu73dhl17_ifUahz1jrajozfJk1yGi4RTEP3MyyldVKvMs6X9B0nurhtl7Zph6U2V2h9hUi0fYwdF50Hi23lw", "aadObjectId": "3fd84a66-b697-4f72-8554-c2c2fe0777ad" (I couldn't find this aad Object ID in my tenant) }, "locale": "en-GB", "text": "The bot encountered unhandled error: Authorization has been denied for this request.", "inputHint": "acceptingInput", "replyToId": "7aba3fd3-7a4d-422b-..." } }
I confirmed that the App ID "4f026db4-208d-46e6-bf70-MASKED_FOR_PRIVACY" belongs to Tenant ID "01c999f0-c6f3-47dc-92cf-MASKED_FOR_PRIVACY".
And if I changed NodeJS code to "MultiTenant" and run, it will report error because my App registration is still using "Single Tenant"
{"code":"Internal","message":"ServerError: unauthorized_client: 700016 - [2024-03-19 04:33:34Z]: AADSTS700016: Application with identifier '4f026db4-208d-46e6-bf70-MASKED_FOR_PRIVACY' was not found in the directory 'Bot Framework'. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You may have sent your authentication request to the wrong tenant. Trace ID: a40c3fb2-4eec-4b80-b9aa-95bec5024d00 Correlation ID: 541c6fc5-67d0-443c-b3b8-dd32f1d85fcf Timestamp: 2024-03-19 04:33:34Z - Correlation ID: 541c6fc5-67d0-443c-b3b8-dd32f1d85fcf - Trace ID: a40c3fb2-4eec-4b80-b9aa-95bec5024d00"}
Hi @xianlin After you switch the App Registration tenant type, could you please try clear the notification storage and try if it works?
Hi @xianlin After you switch the App Registration tenant type, could you please try clear the notification storage and try if it works?
you mean delete the Azure Blog Storage container and start over again? sure I will try it later. thank you.
I deleted the blob from the Azure Storage container "my-bot-test" and remove/re-install the Bot Zip package again in teams, the new blob get created in the Azure storage and I tried to run "curl -X POST https://my_bot_app/api/notification" and here is the nodejs error with verbosed output:
azure:core-http:info ServiceClient: creating signing policy from provided credentials
azure:core-http:info ServiceClient: using default request policies
azure:core-http:info ServiceClient: creating signing policy from provided credentials
azure:core-http:info ServiceClient: using default request policies
azure:core-http:info Request: {
"streamResponseStatusCodes": {},
"url": "https://smba.trafficmanager.net/emea/v3/conversations/a%3A116XtG9a4x2E4TUdg8fRrGS-bYPJeDZg8PzJDyxIZSgVTKfQzZeRK7BsHw71A6_Wl9HAvYfAuMpopAtX97iFpR54Tb6aCfJA0s-SfNitEtNr90-lGK5jSphLnmkMahYJd/pagedmembers?pageSize=REDACTED",
"method": "GET",
"headers": {
"_headersMap": {
"accept": "*/*",
"user-agent": "Microsoft-BotFramework/3.1 botframework-connector/4.22.1 core-http/3.0.4 Node/v18.19.1 OS/(x64-Linux-6.5.0-26-generic)",
"authorization": "REDACTED"
}
},
"withCredentials": false,
"timeout": 0,
"requestId": "19956cef-a95f-4d8d-91a2-e0c43204dd54"
}
azure:core-http:info Response status code: 401
azure:core-http:info Headers: {
"_headersMap": {
"connection": "close",
"content-length": "61",
"content-type": "application/json; charset=utf-8",
"date": "Tue, 19 Mar 2024 08:20:36 GMT",
"ms-cv": "/eSzLdL8GkqBNGUlB+xoOQ.0",
"server": "Microsoft-HTTPAPI/2.0"
}
}
azure:core-http:info ServiceClient: creating signing policy from provided credentials
azure:core-http:info ServiceClient: using default request policies
azure:core-http:info ServiceClient: creating signing policy from provided credentials
azure:core-http:info ServiceClient: using default request policies
azure:core-http:info Request: {
"streamResponseStatusCodes": {},
"url": "https://smba.trafficmanager.net/emea/v3/conversations/a%3A116XtG9a4x2E4TUdg8fRrGS-bYPJeDZg8PzJDyxIZSgVTKfQzZeRK7BsHw71A6_Wl9HAvYfAuMpopAtX97iFpR54Tb6aCfJA0s-SfNitEtNr90-lGK5jSphLnmkMahYJd/activities/22cf293d-d1a4-4da3-9964-188cb33b9946",
"method": "POST",
"headers": {
"_headersMap": {
"content-type": "application/json; charset=utf-8",
"x-ms-conversation-id": "REDACTED",
"accept": "*/*",
"user-agent": "Microsoft-BotFramework/3.1 botframework-connector/4.22.1 core-http/3.0.4 Node/v18.19.1 OS/(x64-Linux-6.5.0-26-generic)",
"authorization": "REDACTED"
}
},
"withCredentials": false,
"timeout": 0,
"requestId": "9b0bd12b-2aab-41d3-a313-28fd4e2d2239"
}
azure:core-http:info Response status code: 401
azure:core-http:info Headers: {
"_headersMap": {
"connection": "close",
"content-length": "61",
"content-type": "application/json; charset=utf-8",
"date": "Tue, 19 Mar 2024 08:20:37 GMT",
"ms-cv": "dnt7IZHiOE6W6qO/gLSMFw.0",
"server": "Microsoft-HTTPAPI/2.0"
}
}
[onTurnError] unhandled error RestError: Authorization has been denied for this request.
{
"name": "RestError",
"statusCode": 401,
"request": {
"streamResponseStatusCodes": {},
"url": "https://smba.trafficmanager.net/emea/v3/conversations/a%3A116XtG9a4x2E4TUdg8fRrGS-bYPJeDZg8PzJDyxIZSgVTKfQzZeRK7BsHw71A6_Wl9HAvYfAuMpopAtX97iFpR54Tb6aCfJA0s-SfNitEtNr90-lGK5jSphLnmkMahYJd/activities/22cf293d-d1a4-4da3-9964-188cb33b9946",
"method": "POST",
"headers": {
"_headersMap": {
"content-type": "application/json; charset=utf-8",
"x-ms-conversation-id": "REDACTED",
"accept": "*/*",
"user-agent": "Microsoft-BotFramework/3.1 botframework-connector/4.22.1 core-http/3.0.4 Node/v18.19.1 OS/(x64-Linux-6.5.0-26-generic)",
"authorization": "REDACTED"
}
},
"withCredentials": false,
"timeout": 0,
"requestId": "9b0bd12b-2aab-41d3-a313-28fd4e2d2239"
},
"details": {
"message": "Authorization has been denied for this request."
},
"message": "Authorization has been denied for this request."
}
azure:core-http:info Request: {
"streamResponseStatusCodes": {},
"url": "https://smba.trafficmanager.net/emea/v3/conversations/a%3A116XtG9a4x2E4TUdg8fRrGS-bYPJeDZg8PzJDyxIZSgVTKfQzZeRK7BsHw71A6_Wl9HAvYfAuMpopAtX97iFpR54Tb6aCfJA0s-SfNitEtNr90-lGK5jSphLnmkMahYJd/activities/22cf293d-d1a4-4da3-9964-188cb33b9946",
"method": "POST",
"headers": {
"_headersMap": {
"content-type": "application/json; charset=utf-8",
"x-ms-conversation-id": "REDACTED",
"accept": "*/*",
"user-agent": "Microsoft-BotFramework/3.1 botframework-connector/4.22.1 core-http/3.0.4 Node/v18.19.1 OS/(x64-Linux-6.5.0-26-generic)",
"authorization": "REDACTED"
}
},
"withCredentials": false,
"timeout": 0,
"requestId": "5d3396ad-a45d-4342-9b1a-c1da4754ad85"
}
azure:core-http:info Response status code: 401
azure:core-http:info Headers: {
"_headersMap": {
"connection": "close",
"content-length": "61",
"content-type": "application/json; charset=utf-8",
"date": "Tue, 19 Mar 2024 08:20:37 GMT",
"ms-cv": "LArIo5vO2E24kwGtquiavw.0",
"server": "Microsoft-HTTPAPI/2.0"
}
}
I still get 401 error and still have the response output from my curl command as the below:
{
"body": {
"type": "message",
"serviceUrl": "https://smba.trafficmanager.net/emea/",
"channelId": "msteams",
"from": {
"id": "28:4f026db4-208d-46e6-bf70-MASK_FOR_PRIVACY",
"name": "MY_BOT_TEST"
},
"conversation": {
"conversationType": "personal",
"id": "a:116XtG9a4x2E4TUdg8fRrGS-bYPJeDZg8PzJDyxIZSgVTKfQzZeRK7BsHw71A6_Wl9HAvYfAuMpopAtX97iFpR54Tb6aCfJA0s-SfNitEtNr90-lGK5jSphLnmkMahYJd",
"tenantId": "01c999f0-c6f3-47dc-92cf-MASK_FOR_PRIVACY"
},
"recipient": {
"id": "29:1ztu73dhl17_ifUahz1jrajozfJk1yGi4RTEP3MyyldVKvMs6X9B0nurhtl7Zph6U2V2h9hUi0fYwdF50Hi23lw",
"aadObjectId": "3fd84a66-b697-4f72-8554-c2c2fe0777ad"
},
"locale": "en-GB",
"text": "The bot encountered unhandled error: Authorization has been denied for this request.",
"inputHint": "acceptingInput",
"replyToId": "22cf293d-d1a4-4da3-9964-188cb33b9946"
},
"withCredentials": false
}
I am using ngrok
for the testing from my local machine but it should be working as before when I used "MultiTenant".
my snippet of the API logic:
server.post(
"/api/notification",
restify.plugins.queryParser(),
restify.plugins.bodyParser(), // Add more parsers if needed
async (req, res) => {
const pageSize = 100;
let continuationToken = undefined;
do {
const pagedData = await notificationApp.notification.getPagedInstallations(
pageSize,
continuationToken
);
const installations = pagedData.data;
continuationToken = pagedData.continuationToken;
for (const target of installations) {
await target.sendAdaptiveCard(
AdaptiveCards.declare(notificationTemplate).render({
title: "New Event Occurred!",
appName: "Contoso App Notification",
description: `This is a sample http-triggered notification to ${target.type}`,
notificationUrl: "https://aka.ms/teamsfx-notification-new",
})
);
}
} while (continuationToken);
res.json({ "code": 200, "msg": "Message sent successfully." });
}
I have seen comments like "Multi-tenant is required because the Bot Framework authentication occurs on the Microsoft server for the service-to-service protocol authentication purpose, making single tenant never work".
Is it still true?
Hi @xianlin, I don't see any problem with your code and configuration. But I also see some comments saying "single tenant not supported", for example: https://github.com/microsoft/botbuilder-js/issues/1447, so I suggest you creating issue on https://github.com/microsoft/botbuilder-js repo to seek clarification on this problem.
I am trying to manually config the Azure Bot Service to use the SingleTenant after switch from MultiTenant to SingleTenant in the AAD app registration as per https://github.com/OfficeDev/TeamsFx/issues/10347
after made the above changes to supply the msAppTenantID
and msAppType
, my bot works with Single Tenant mode.
The test was done with deployed to Azure, not using local mode with ngrok.
Hi @xianlin , could you kindly confirm if you've successfully resolved this issue? Thanks.
Yes @yukun-dong , I confirmed that I have resolved this issue. Thank you
Describe the bug I have a teams bot with Multi tenant enabled in app registration and it works fine. However when I switched the app registration from multi tenant to single Tenant, it produced 401 Authentication failure error.
Of course I have edited my nodejs code to accommodate the single tenant by adding the MicrosoftAppTenatID of my azure app registration and MicrosoftAppType to Single tenant.
Did I miss some steps or is this a bug? Does anyone have the successful testing on the single tenant? Thanks.
To Reproduce
update
src/internal/initialzie.js
package.json
Expected behavior Should receive the test message but received 401 Authentication Failure
Reference Bot Framework Single Tenant V.S. Multi Tenant Discussion