Paulw11 Paulw11 - 3 months ago 19
iOS Question

Non-interactive login (cached credentials) against Azure Graph API on iOS

I am creating an app on iOS that will run in a "kiosk" mode. Part of the application requires users to be able to search an organisation's directory. I would like to support Azure AD via the Azure Graph API to provide this function.

I don't want to require an interactive login when the app starts and I don't want to have to use an additional web service; I would like for the iOS app to simply access the Azure Graph API via REST.

I am aware of the risks associated with cached credentials, however the use of "service accounts" for non-interactive logins is fairly well established, the access is read-only and the credentials can be secured in the iOS keychain.

I have looked through numerous Azure samples and read the documentation and it seems that the method that provides what I need

isn't available in the iOS ADAL library (and either is the
ClientCredential
class).

To clarify, this is how I would like my app to work:


  1. User installs the app from the app store and runs it the first time

  2. As part of the setup they authenticate to Azure AD by providing their tenant, application client ID and an application key. If they can't authenticate with an application key, a user id/password is acceptable as long as:

  3. They never get prompted to authenticate again



Is there a solution here or do I just give up on Azure AD?

Answer

This can be done, but not with the ADALiOS framework as it doesn't expose the client_credentials grant that is required to make it work.

I was able to build a working demonstration using p2/OAuth. The sample app is here

The steps to build a working solution are:

  1. Login to the legacy Azure Management portal and select your Azure AD Instance
  2. Create a new application in that AD instance
    1. Select "Add an application my organisation is developing"
    2. Give it a name and select "Web application and/or Web API" not "Native Client Application"
    3. Enter values for sign on url and app id url. These need to be well-formed URLs but do not need to be reachable
  3. Once the application has been created select "Configure". Note the Client ID - you will need this
  4. In the "Keys" selection, select 1 or 2 years from the drop down, then click "Save"
  5. Once the key is displayed, copy this and save it somewhere; it can't be displayed again.
  6. Set the required "Permissions to other applications" to allow your app the access it needs
  7. Finally, at the bottom of the screen click "view endpoints" - You need to copy the OAuth 2.0 Token Endpoint and the OAuth 2.0 Authorization Endpoint
  8. Download the demo code from GitHub
  9. Run pod install
  10. Plug the values into the Settings.plist file
  11. Run the app

The meat of the authentication process is to set up an instance of OAuth2ClientCredentials -

let settings = [
        "client_id": appData.clientId!,
        "client_secret": appData.secret!,
        "authorize_uri": appData.authString!,
        "token_uri": appData.tokenString!,
        "keychain": true,
        "secret_in_body": true
        ] as OAuth2JSON

self.oauth2 = OAuth2ClientCredentials(settings: settings)

Then you can call doAuthorize() to get a token

self.oauth2.doAuthorize()
Comments