9

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?

donmartin
  • 1,753
  • 2
  • 15
  • 30
  • I found one more discussion which most probably boils down to exactly the same problem I have: https://social.technet.microsoft.com/Forums/en-US/82ab8a7d-e17b-4e4a-9615-2bdf43f1866a/graph-api-call-returns-insufficient-privileges-to-complete-the-operation?forum=WindowsAzureAD Additionally, I also found the page where the Graph API Permissions are discussed: https://msdn.microsoft.com/Library/Azure/Ad/Graph/howto/azure-ad-graph-api-permission-scopes – donmartin Jan 13 '16 at 09:49
  • Do they provide the solution for your problem? – juvchan Jan 13 '16 at 21:19
  • Nope, unfortunately not. Impersonating an Admin is the only "solution" I have found so far. – donmartin Jan 14 '16 at 07:06

1 Answers1

5

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 can see these show in the Azure Portal for the AAD Graph resource.

Dave Neeley
  • 3,526
  • 1
  • 24
  • 42
Dan Kershaw - MSFT
  • 5,833
  • 1
  • 14
  • 23
  • Yes, this would be a sort-of acceptable workaround. In the mean time, we also came up with the following idea (not verified), which goes in the same direction, but does not require the user having the API consumer role to be an AD admin: We can "kickstart" the controlling web app with an Authorization Code grant using an AD admin's credentials (so that we don't have to store them in the app), and then subsequently refresh the token in the app to keep that admin's impersonation inside the app without requiring manual intervention. But this also sort of leaves a bad taste. – donmartin Jan 29 '16 at 08:25
  • No. It doesn't. Resource Owner Password Grant does. – donmartin Nov 13 '16 at 20:16
  • 1
    I'll update this thread once we have the necessary application permission available. Once we have that, this flow would work for client credentials flow. Don, what you are doing will work (caching the refresh token), but you need to ensure that this is securely stored - plus that token will eventually expire (either through last of use or the admin's password expiring), requiring your admin to consent again. Client credentials sounds like the way to go, when we have the application permission. – Dan Kershaw - MSFT Dec 10 '16 at 23:48
  • @DanKershaw-MSFT: I know you told that you would follow this thread, but do you have any update ? – Loul G. Sep 05 '17 at 14:28
  • Sorry for the late response. Just added an update to the answer. – Dan Kershaw - MSFT Sep 05 '17 at 15:49