How to restrict access to Azure Function to only allow requests from a custom Microsoft Teams App?

Viewed 566

I am building a Teams app using React. The backend is an Azure Functions app. This Teams app is meant for internal organization only and I need to allow Function backend to only accept API requests from this Teams app. How can I do that?

When deploying a Teams app, it actually creates a static web app hosted in an Azure storage container. I couldn't find a static IP address for this container endpoint to whitelist this IP.

Is there any other way to allow Azure Function to allow requests from this particular Teams app (static web app hosted in Storage container)

2 Answers

As far as I can tell, you cannot limit the function to accept the requests only from a specific teams app. Your azure function is actually called not "from the static app" but from the user's browser (or Teams client) that can be anywhere.

I mean, the browser (or teams client) downloads the app javascript files from your static hosting, and then runs them. Running these files results in calling your azure function. So, the call to your azure function is coming from a browser, and not your static hosting.

What you could do, is to make your function authenticate your users, and allow only users from your organization to call it. All users who are logged in Teams are already authenticated by Teams, so you could use that identity (Teams can provide that identity in a form of a token to your app if the app asks for it).

This is definitely possible, and the way to do this is to have a multi-tenant Azure AD app registration with an "api" capability. This article will help get you started with Tab SSO, and shows how you can get the token you need. You can pass this token as a "bearer" tokens to your backend API, using the Authorization HTTP header, like this:

Bearer [token value] (so notice the word "Bearer" at the front, then a space, then your actual token).

These tokens are JWT tokens, so you can see what they look like by visiting a site like JWT.io, and pasting it into the text box - it will show the contents of the token on the right side, decoded.

On the backend, your API is able to verify these signed tokens, to ensure they are issued from your own Azure AD application, and to validate the user's AadOjectId, UPN, Tenant, and so on. This blog post shows how to do the actual token validation on the server. Validation ensures that the token is valid, and issued by your app, but it also includes a TenantId and the user's Azure AD Object ID, email address, and display name - everything you should need to securely identify the user and the tenant.

Incidentally, this applies to any front end, but works perfectly with a static react app in Azure storage (tested it to confirm).

[Update]: Microsoft just published an informative and up to date video walkthrough today on SSO. It doesn't fully cover your scenario (it doesn't validate the tokens on the backend), but it shows a lot of the preliminary steps nicely. See How to restrict access to Azure Function to only allow requests from a custom Microsoft Teams App?

Related