Multiple Client applications authorisation to WebApi RRS feed

  • Question

  • I have a webApi that I wish to control authorisation via Azure AD for multiple 3rd party clients. (Using vs2013 .net4.5.1)

    • So I set up an application in Azure AD for my webapi and an application(web not native) for each client app that will access the webApi.
    • I then created a secret key on each azure AD client app and also linked it to the azure AD app for the webapi by adding the app for the webapi to the list "Other applications accessed by this application".
    • In test clients I use the azure AD client app Id and secret key to get a token which works.

    However the token fails authorisation when accessing the API even though they are linked in Azure AD.

    You may ask why did I not create an Azure AD native client app for each client. Well the reason is that I cannot create secret keys against a native client. Thus I cannot I cannot get a token.

    So am I going about this the correct way? or am I overlooking something?

    I also asked this question on StackOverflow with some code


    Monday, March 10, 2014 7:22 PM

All replies

  • A native application should *never* use a client secret. Even if it's a compiled application, it is not considered a confidential client and should never have, hold or use a secret key. The only applications that should use this are hosted applications, where the user never has access to the code/binaries, only the interface (i.e. a web app or a web API).

    You *can* get a token to a native client app when you don't have a secret key. Have you been unable to do so?

    If you have multiple confidential clients (remember, hosted apps, not installed client applications) where it is logical to group them under one application, you can give them each a different secret key (and they all use the same client ID). Then, you can revoke access to individual clients if needed.

    Anyway, it sounds to me that you should do the following:

    • Add a web app/web API: this is the resource that you will protect (e.g. a hosted application that does something)
    • Add a native client app: this is going to represent the client application (e.g. a phone app, a desktop client app or a browser-side client app).

    Once you've created the two apps in your directory, you need to add an app permission to the web API. A recent update allows you to define this in the manifest file. Download the wep API's manifest file, and edit it to add an "appPermission" entry like this (replace the highlighted fields with your own text, and your own generated GUID for permissionId):

    "appPermissions": [   {

        "claimValue": "user_impersonation",

        "description": "Allow the application full access to the Test Web API service on behalf of the signed-in user",
        "directAccessGrantTypes": [],
        "displayName": "Have full access to the Test Web API service",
        "impersonationAccessGrantTypes": [ 
             "impersonated": "User",
             "impersonator": "Application"
          } ],
        "isDisabled": false,
        "origin": "Application",
        "permissionId": "60e76a46-af27-4d3b-bbd2-ac74206346a5",
        "resourceScopeType": "Personal",
         "userConsentDescription": "Allow the application full access to the Test Web API service on your behalf",
        "userConsentDisplayName": "Have full access to the Test Web API service"
      } ],

    • Note: 'resourceScopeType' should be "Personal" if it's something that each user should consent to, or "Global" if it's something that applies to the entire tenant, (and thus, an administrator would have to consent to).
    • Note: Your web API code is where these permissions are enforced, if you have more than one. The 'scp' claim in the JWT token will have the 'claimValue' from the 'appPermission'.

    Once you've uploaded the manifest file for the web API's app, when you go to the 'permissions to other applications' section of any other app, you will have an entry in the drop-down menu which refers to the "appPermission" you just added.

    Now, in you native client app, you should state that the native client app (i.e. any client app identifying themselves with that client ID), should have access to your web API. So, when a user logs in, they will eventually be asked to consent to this.

    Friday, March 14, 2014 11:11 PM
  • So I did it. And yes, in the latest UI, a client app can now reference the webAPI apps (permission).

    Are we Trying to FAIL (by exposing this kind of config method)??

    Please TELL ME THIS IS only an intermediate UI.

    Tuesday, March 18, 2014 11:48 PM
  • Thanks for your response.

    The third party Client Applications that I am trying to grant access to my WebApi are backend server programs that are not running in a browser and have no end user. That was why I was giving them keys as they will never go through a login screen. (And thus the reason I used WebApplications in Azure AD to represent the Client Apps as opposed to Native Client Apps. I was taking a lead from http://code.msdn.microsoft.com/AAL-Server-to-Server-9aafccc1)

    Your solution requires an end user to consent to accessing the webApi which will not work in my case as there is no end user. Is there any work around for this?

    Also you mentioned
    "If you have multiple confidential clients (remember, hosted apps, not installed client applications) where it is logical to group them under one application, you can give them each a different secret key (and they all use the same client ID). Then, you can revoke access to individual clients if needed"

    On the Azure AD application how could I ever tell which key belonged to which Client?

    Wednesday, March 19, 2014 11:21 AM
  • in azure terms, this scenario is one of a mobile azure site having Api scripts that run on a scheduler. Once invoked, the API component (a glorified cron job...) happens to call other APIs, citing the token need to pass the access guards.

    They are hosted, and therefore :confidential clients: - to use the latest buzzwords of the month.

    if there several scripts in a mobile site, I can them all having a distinct symmetric key , and common reply address (the mobile site), and a common clientID of the AAD app.

    I think THAT makes sense.

    Thursday, March 20, 2014 6:40 AM
  • Thanks for the feedback Peter.  This is a preview, and we hope to make some improvements in this area shortly, to at least have this work out of the box with a default user_impersonation scope permission being exposed by newly created applications (web APIs). 

    The JSON app manifest will allow a web API developer to expose more permission scopes that can be used for finer grained authz to their API.

      • Let’s take an example. 
      • Imagine you have a travel API, that exposes the following permission scopes:
        • Read my itinerary (Initerary.Read)
        • Update my itinerary (Itinerary.Update)
        • Read my profile (TravelProfile.Read)
        • Update my profile (TravelProfile.Update)
        • Update travel policy (Policy.Update)
      • You (or another company) builds a client app that requests only Read my profile and Read my itinerary.
      • When using the client app, a user will be asked to consent to the app for those permissions
      • After authorization, the client app calls into the web API, presenting its OAuth access token, which would contain, in the scp claim “Initerary.Read TravelProfile.Read”.
      • Your web API can look at the scp claim and use it to make authorization decisions about the calls that the client is making to your web API.  In this case if the client is trying to read the logged on user’s profile, then great, but if it tries to update the user’s profile, then it should give access denied, because the user never consented to allow the app that level of access

    We may also look at adding a UX to simplify adding web API permissions

    Does this help?  Be glad to get more feedback on this.

    Dan Kershaw [msft]

    Saturday, March 22, 2014 7:34 AM
  • Dont be so defensive!

    There is UI, but its in Visual Studio (which obviously folks in the know, know...)

    new way to get access to office APIs http://wp.me/p1fcz8-4Y3 via @wordpressdotcom

    This has nailed shut any lingering reason to maintain my own (advanced) oauth endpoints (that wrapped ACS delegation APIs). While I will keep them (for websso that does NOT involve office365 accounts or microsoft online interaction), I dont need them AT ALL, now, in office365 integration scenarios. The tokens granted now get our thickclient the access the needed to sharepoint and exchange (which was my goal all along) - by embeddeing a webview.

    Im not sure Im in agreement with moving such controls ONLY into a developer-centric IDE. Folks who run data centers, or cloud deployments FOR REAL, tend to have a system admin personality, and like scripting and web consoles, etc. This allows them to express "control" (distinct from how we developers think).

    Monday, March 24, 2014 3:42 AM