Reputation: 136
How to secure the traffic from Microsoft Teams to a bot, so that bot could be answering on company specific questions / discussions and would not need to be exposed as anonymous WebAPI?
Bot integration to Teams UIs is easy from bot framework side, but right now there's no documentation for how to isolate bot only for specific enterprise.
Business case - We want to build enterprise specific bot, which could answer questions only specific to that particular enterprise where the questions are coming from. Technically this could be done with app-only access to SharePoint or Microsoft Graph, but we cannot expose this kind of WebAPI anonymously for Internet.
Any design patterns for this?
Upvotes: 0
Views: 1533
Reputation: 21
Here's how to do this in C#, the SDK exposes the TenantFilter
that allows you to add this action filter to the controller class as shown below.
using Microsoft.Bot.Connector.Teams;
namespace Microsoft.Teams.Samples.HelloWorld.Web.Controllers
{
[BotAuthentication, TenantFilter]
public class MessagesController : ApiController
{
[HttpPost]
public async Task<HttpResponseMessage> Post([FromBody] Activity activity)
The tenant filter will take a comma separated list of tenantIds that will need to be placed in the web.config
<configuration>
<appSettings>
<!--other settings-->
<add key="AllowedTenants" value="*TenantId1,TenantId2,...*"/>
Find your Office 365 tenant ID shows how you can do it through PowerShell.
Upvotes: 2
Reputation: 3581
This is now possible, and I've actually even implemented it for Hubot in CoffeeScript and Node.JS. What I've described below is what it would look like in JavaScript/Node.JS.
Define an environment variable that, when set, filters for a particular tenant ID, OFFICE_365_TENANT_FILTER
. (Doing it this way is a handy way of turning this feature on in production but not necessarily during development.)
For Microsoft Teams, the Office 365 tenant ID can be found here: session.message.sourceEvent.tenant.id
.
The most elegant way to do it is to check for the tenant ID as middleware, and just drop further processing of the message if the filter is set and it doesn't match:
// [...]
var connector = new builder.ChatConnector({
appId: process.env.MICROSOFT_APP_ID,
appPassword: process.env.MICROSOFT_APP_PASSWORD
});
var bot = new builder.UniversalBot(connector);
// Middleware to check for OFFICE_365_TENANT_FILTER and only continue processing if it matches.
// If OFFICE_365_TENANT_FILTER is not specified, do nothing.
bot.use({
botbuilder: function(session, next) {
var targetTenant = typeof(process.env.OFFICE_365_TENANT_FILTER) !== "undefined" ? process.env.OFFICE_365_TENANT_FILTER : null;
var currentMsgTenant = typeof(session.message.sourceEvent.tenant) !== "undefined" ? session.message.sourceEvent.tenant.id : null;
if (targetTenant !== null) {
if (targetTenant == currentMsgTenant) {
next();
}
else {
console.log("MS Teams: Attempted access from a different Office 365 tenant (" + currentMsgTenant + "): message rejected");
}
}
else {
next();
}
}
});
// [...]
Upvotes: 6
Reputation: 321
Although not exactly what you are looking for, you can create custom bots which will be scoped to individual Teams.
The security key/HMAC auth will prevent others from accessing the API. With the drawback that you will have to configure the bot with a separate security token for every Team where you want to use it.
Upvotes: 0
Reputation: 261
It is not currently possible to know the tenant-id of the user chatting with the bot right away, unless the bot authenticates the user first. Please take a look at AuthBot. It illustrates how to send a sign-in link to a user and authenticate the user against AAD.
Upvotes: 0