I want to authenticate users with Azure Active Directory (AD) in a mobile app that calls its own REST API and possibly, make it simple.
Looks like the documented way (here or here) to do so is to
- register the API app with AD, expose some scope(s) as delegated permissions
- register the mobile app, add these scopes as API permissions to this app
- do authorization decisions in the API app based on these scopes
Question:
Now, since I feel the front-end and back-end parts of my app should belong into the same "black box" plus there are no fine-granular user roles within the app that would justify usage of multiple scopes or require the user to consent to using them, I’m wondering whether there is a recommended (and secure) way to go with just one app registration instead of two?
What I tried:
When using Okta in a similar scenario, I only had one app (clientId) and the back-end configuration pretty much validated the JWT token issuer, domain and a default audience string (in my understanding). I tried inspecting tokens from AD acquired via the authorization code flow for usual scopes (openid profile) to see what their audience was and if this could be reproduced – this is what I’ve got:
- the well known GUID of Microsoft Graph (for the access token) – this one doesn’t feel "correct" to validate, as pretty much any AD user could present an access token for MS Graph and only assigned users should be able to use my app
- client ID of the app (for the ID token) – but the docs says these should not be used for authorization, so not sure if it’s a great idea to pass them as Bearer tokens to the API
2
Answers
The standard thing in OAuth technologies is to only register a client for your mobile app. Azure has some vendor specific behaviour when it comes to APIs, related to the resource indicators spec. When there is no API registration, your mobile app will receive JWT access tokens with a
nonce
field in the JWT header. These are intended to be sent to Graph, and will fail validation if you ever try to validate them in your own APIs.If like me you want to stay close to standards, one option is to add a single logical app registration, to represent your set of APIs. You might design an audience of
api.mycompany.com
, though Azure will give you a technical value likecb398b43-96e8-48e6-8e8e-b168d5816c0e
. You can then expose scopes, and use them in client apps. This is fairly easy to manage. Some info in my blog post from a couple of years back might help clarify this.You can create just one app registration; in fact the newer app registration model was designed to do that.
In the case where an API is used only by the app itself, I would register a single scope, something like MobileApp.Access.
Your API should verify the presence of this scope to prevent unauthorized applications from calling it.
In addition to verifying the scope, you will need to verify user permissions.
And filter the data based on their identity, depending on your use case.
Your question seems to suggest that you might be mixing scopes and user roles.
Scopes are permissions given to an application.
Also called delegated permissions; they allow an app to do some actions on behalf of the signed in user.