This article explains an issue that you probably shouldn’t run into – unless you’re doing something a bit dumb. Just like I was. Or still am.
Namely, I really needed an app I registered in Entra ID to have multiple “app identifier URIs” for reasons that are not great, but that I’ll go into momentarily.
Background
Well, this was a bit random 😁
I already mentioned I’m doing something a little bit unconventional for not very great reasons. See, I recently ended up in a situation, where I had an environment where I wanted to run both code from my local environment to serve a Teams tab, and from my Azure environment after a GitHub Actions pipeline had deployed my code there.
Simple, right? Ehh.. It should be.
But using Teams Toolkit, I had built multiple Teams apps, gotten them added to Teams and everything was loading nicely… Except I realized only after setting everything up in Teams that the Teams toolkit – kind of smartly, but now annoyingly – uses the tab URL to also modify the “resource” key’s value in “webApplicationInfo” – and this is used as app identifier URI, when trying to authenticate against the right app in Entra ID.
But what exactly goes wrong, then?
Problem
Well, a lot, in fact.
If you just have one app registration in Entra ID, but you have 2 separate manifests with different tab urls and different resource URIs…. Only one of them is going to work, and that’s the one that was used to generate the app registration in Entra ID (if you used Teams toolkit dependency preparation to create it) or that you used as the redirection URI when you registered it.
If you used a localhost url for your app, and now are trying to reuse the same client id for your app that’s hosted in Azure, you’ll get a 400 “Bad Request” in the console and the authentication will fail. Something like below:
865969-ed34c22bf9e81d6a.js:1
POST https://login.microsoftonline.com/7f34bc08-7585-4811-b5e3-124306325c55/oauth2/v2.0/token 400 (Bad Request)
Or as a screenshot:
And if you take a closer look at the response, you might see something like this:
{
"error": "invalid_resource",
"error_description": "AADSTS500011: The resource principal named api://myextension.azurewebsites.net/fc5d7662-0000-aaaa-ffff-75da016762af was not found in the tenant named Contoso. 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 might have sent your authentication request to the wrong tenant. Trace ID: 37e401bf-dd0d-48e6-8769-e0667de31001 Correlation ID: d01a05d4-daf8-4f19-a099-f9388ea0a75d Timestamp: 2024-10-09 09:19:27Z",
"error_codes": [
500011
],
"timestamp": "2024-10-09 09:19:27Z",
"trace_id": "37e401bf-dd0d-48e6-8769-e0667de31001",
"correlation_id": "d01a05d4-daf8-4f19-a099-f9388ea0a75d",
"error_uri": "https://login.microsoftonline.com/error?code=500011"
}
Or, again, as a screenshot:
Make note of the URI the error gives you as the missing resource principal. You’ll need it later.
I also like that the error message contains an error_uri property – can’t remember seeing this before – but of course for this error, it doesn’t explain super well what’s going wrong.
Here’s what it says when you follow the link for details:
Error Code 50001
Message The resource is disabled or the resource named could not be found. This can happen if the application has not been installed by the administrator of the tenant, or if the resource principal was not found in the directory or is invalid due to a typo.
Remediation Check your app's code to ensure that you have specified the exact and correct resource URL for the resource you are trying to access. Please see the returned exception message for details.
Nothing that wasn’t immediately obvious already. Okay. So what gives?
Reason
Well, obviously – the Teams manifest file in your app package tells Teams to locate an app registration with the Application identifier URI (or “Application ID URI” like it’s called in the UI) that doesn’t currently exist for any app. Unless you have 2 separate registrations – one for local and one for Azure – but I couldn’t be bothered to set that up for a test environment.
So instead, I decided I wanted to have this app respond to both URIs. And this should be easy – you can find and edit the URI under “Expose an API” tab in Entra.
In theory, you can always change the value here by clicking “Edit” next to the “Application ID URI” -box:
However… That will literally change your Application ID URI. It will stop your hypothetical (well, for me it was real) other environment from working.
Bothersome!
But can we enable 2 separate Application ID URIs for an app?
Solution
Well, let’s face it – you would probably not be reading this article unless there was indeed a way to add multiple Application ID URIs to the app registration, would you? 😅
You can add additional URIs by modifying the manifest for your app registration directly.
So even though it can’t be done using the UI, you can do it by modifying JSON in the same portal. Fun times!
Here’s how.
1. Navigate to your app registration in Entra ID
In short, you’ll get there by navigating to Applications > App Registrations.
2. Click “Manifest” under “Manage”
We’ll need to get the JSON view open for the app registration. You’ll get access to that by clicking “Manifest” under “Manage”.
3. Locate “identifierUris”
Now you’ll want to find the section that – surprisingly – is an array of strings, called “identifierUris”.
Yep. It’s an array with one entry. Intriguing…
4. Add your second URI to it
You should have the second URI – the one that didn’t work – from the error message you ran into earlier. Or you can get it from the manifest file for your Teams app package.
You can then add it as a new identifier in the array. Something like in my sample below:
"identifierUris": [
"api://localhost:44302/fc5d7662-0000-aaaa-ffff-75da016762af",
"api://myextension.azurewebsites.net/fc5d7662-0000-aaaa-ffff-75da016762af"
],
Et Voilà! There you have it. An app registration that responds to multiple Teams apps. Something completely unnecessary if you just modified the generated manifest files before uploading them… But eh. This is easier.
Perhaps a configuration like this isn’t recommended for production, but I’d argue it’s absolutely fine for test and dev environments.
- “Performing cleanup” – Excel is stuck with an old, conflicted file and will never recover. - November 12, 2024
- How to add multiple app URIs for your Entra app registration? - November 5, 2024
- How to access Environment Secrets with GitHub Actions? - October 29, 2024