For use with the Azure API Management, I am trying to add Applications to an Azure Active Directory (AAD) programmatically, in my case by using the Graph API.
My scenario is the following: In order to secure a Web API I want to manage with Azure API Management, I want to leverage AAD's OAuth functionality to do the heavy lifting regarding authentication and issuing JWT Tokens, and then just use the validate-jwt policy to verify everything is okay in Azure API Management. This has the advantage I can more or less omit authentication in my backend service.
This works fine, as long as I have created an application in the Azure AD for the consuming web application, but this has to be done manually from the Azure Portal; Azure APIm does not do it automatically.
Now for what I am trying to do to get the done automatically: I wanted to delegate the subscription to APIs in APIm to some other web app I am writing, and from there I want to leverage the Graph API to create an Application in the Azure AD and grant permissions to the Application of the API.
The first thing I tried to do was to have a third application (my service application) to have full application permissions to the Windows Azure Active Directory application in the Azure AD; this lets my application access AAD using the Graph REST API. I manage to get an Access Token using the client_credentials grant (from login.microsoft.com), but this Token does not let me do a POST
on https://graph.windows.net/(my AAD ID)/applications?api-version=1.5
:
{
"odata.error": {
"code": "Authorization_RequestDenied",
"message": {
"lang": "en",
"value": "Insufficient privileges to complete the operation."
}
}
}
I found (https://msdn.microsoft.com/Library/Azure/Ad/Graph/howto/azure-ad-graph-api-permission-scopes) that even if I grant the Directory.ReadWrite.All
permission, the application (app-only) will not be able to create or update Applications:
Note: Specifically excludes create or update for entities not listed above. This includes: Application, Oauth2PermissionGrant, AppRoleAssignment, Device, ServicePrincipal, TenantDetail, domains, etc.
The next thing I tried was the Resource Owner Password Grant (grant_type=password
), passing my own credentials additionally, so that I can impersonate myself in the Graph API. Now, my POST
to the applications
end point succeeds.
My bottom-of-the-line question is: Can I grant sufficient permissions to my application so that I can add applications programmatically using the client credentials flow, and not any flow which acts on behalf of a user? And if so, how is it done?
Sorry Don. We don't currently have any permission scopes for the client credential flow (app-only) that can be used to create applications or service principals or create any oauth2 permission grants (or any of the other entities that you mentioned above through the Directory.ReadWrite.All permission). We are working on additional app-only permissions that will enable you to light up this scenario, but I don't have an ETA that I can give you.
This operation should be possible if you use the app+user (code flow) and grant the app the Directory.AccessAsUser.All permission - as long as there is a user using your app AND that they are a tenant admin. Not sure if this is an acceptable workaround for you (and I guess is similar to what you are using with the password flow - although I would recommend you use the code flow here).
UPDATE: There are a couple of new app only permissions we added for AAD Graph. Application.ReadWrite.OwnedBy (which allows an app to create/own another app - but only update the apps it created - it won't be able to touch any other apps it doesn't own) AND Application.ReadWrite.All (which allows an app to create/manage ALL apps in a tenant). Seems like the first one would be appropriate. You should see these show up in the Azure Portal for the AAD Graph resource. However they are not currently documented AFAIK.
Hope this helps,