Exposing Azure Function web API to native & web clients through Azure AD authentication

Problem

Azure AD writeups are prevalent but I was really struggling to find examples of calling the same Azure Function API, secured by Azure AD Authentication, by both Native as well as Web clients (since we can only select one app type in the Azure AD App registration, not both).

TL;DR

The kicker solution for me was having both a web and native App registration (i.e. two Client Id’s) and providing the WEB App registration’s Application Id as the “RESOURCE” parameter to the AuthenticationContext.AcquireTokenAsync() call in the Native app (see code sample below).

So the web registration is tied directly to the Azure Function… and then we’re piggybacking the web registration by requesting the web as the resource parameter in the native client call … i haven’t seen this documented yet so i can’t say whether this is an officially preferred solution.

Basic Steps

This is a good getting started guide guide, in parity with current landscape.

  1. get your Azure Function working as a web api… probably doesn’t matter whether web or native comes first but it seems like the web is more “trusted” from an OAuth standpoint and more clearly documented… OAuth refers to native clients as “public” and requiring a couple more OAuth contortions than web clients.
  2. create a Web type entry for your Function under New Portal > Azure Active Directory > App registrations… all the defaults are good, except you’ll need to create the Reply URLs that are valid for you… reply url is a parameter to your ADAL.js client call… in the end this entry provides the crucial Application Id aka Client Id
  3. now configure this web registration for AD Auth via New Portal > App Services > {your Function app} > Function app settings > Configure authentication > Authentication Providers > Azure AD > Express >
    1. Azure AD App = the Web App registration name you gave above
  4. Now create another Azure AD > App registration as Native type and (HERE’S THE KICKER) > Settings > Required Permissions > Add > Select an API > TYPE IN YOUR web App registration name in the search box and it’ll show up to be selected
  5. finally, use the Application Id guid from your web app as the RESOURCE parameter to the AcquireTokenAsync() call in your native app

Working ADAL.js web client code sample

Working Xamarin Native iOS app client code sample

Typical error responses

Various attempts at sussing out a valid resource value for the AcquireTokenAsync() in my Xamarin Forms native iOS app would yield the following error:
AADSTS65005: The client application has requested access to resource <xyz>. This request has failed because the client has not specified this resource in its requiredResourceAccess list

i was also getting these where {app} was the resource i was passing when i had the ClientId parameter wrong
AADSTS50001: The application named {app} was not found in the tenant named {tentant}.

Helpful references

What is my Tenant Id or “Authority” URL ???

Wanted to mention this in closing since “Tentant” is currently so ambiguously referred to in the documentation i ran into…
New Portal > Azure Active Directory > App registrations > Endpoints is where you pull the “Authority” Url from the “OAUTH 2.0 AUTHORIZATION ENDPOINT” slot – the main argument for new AuthenticationContext()

for example:
https://login.windows.net/9198d419-6ce5-4229-a457-8c38421f7466/oauth2/authorize
this “9198…” guid is your Tenant Id (don’t worry this one is made up)

our tenant appears to be simply our azure ad domain name, at least in typical configurations… so this works here as well:
https://login.windows.net/XYZ.onmicrosoft.com/oauth2/authorize

image