Call Azure AD secured API from your SPFx code. Story #3: Web app (or Azure Function) and SPFx with AadHttpClient

Call Azure AD secured API from your SPFx code series:

  1. Call Azure AD secured API from your SPFx code. Story #1: Azure Functions with cookie authentication (xhr "with credentials")
  2. Call Azure AD secured API from your SPFx code. Story #1.1: Azure Web App with ASP.NET Core 2.x and cookie authentication (xhr "with credentials")
  3. Call Azure AD secured API from your SPFx code. Story #2: Web app (or Azure Function) and SPFx with adal.js 
  4. Call Azure AD secured API from your SPFx code. Story #3: Web app (or Azure Function) and SPFx with AadHttpClient <—you are here

This post covers the last and recommended way to interact with remote Azure AD protected APIs from SPFx code – AadHttpClient. As of now (Aug 2018) this feature is still in preview and not available for production. I guess it will be available in a few months, however that’s only guessing. Why it’s recommended? Because it’s OOB SPFx way to interact with APIs, it eliminates almost all cons we have with previous methods and it’s much simpler and solid. More info on this topic you can read here - Connect to Azure AD-secured APIs in SharePoint Framework solutions.

Source code for the post is available here at GitHub.

Today’s post covers:

  1. New app registration in Azure AD (step will be taken from previous post)
  2. Create Azure AD secured API (Web App with custom jwt bearer authentication or Azure Function with EasyAuth aka App Service Authentication, I will cover both) and enable CORS (step will be taken from previous post)
  3. SPFx webpart, which uses API via AadHttpClient
  4. Deployment and testing

As usual, let’s get started Smile

Steps #1 and #2 should be taken from previous post - Call Azure AD secured API from your SPFx code. Story #2: Web app (or Azure Function) and SPFx with adal.js . They are exactly the same, there is no need to repeat it here. Let’s go to step #3.

3. SPFx webpart, which uses API via AadHttpClient

First of all, we need SharePoint framework web part. SPFx framework starting from 1.5 version received an update, which allows you to install preview features with a separate flag. As said, AadHttpClient is still in preview, that’s why we should install it using yeoman SharePoint generator and preview flag (plusbeta):

yo @microsoft/sharepoint --plusbeta

--plusbeta makes sure, that all preview features will be available in your code. Caution: preview features are not available at production and available only in targeted tenants. For SPFx generator use “No Javascript Framework” option.

The code is extremely simple in comparison to adal.js option. Basically, you should create an instance of AadHttpClient, pass your ClientId and this is it. You can use aad client to call remote API:

public render(): void {
this.domElement.innerHTML = `
  <div class="${ styles.helloWorld }">
	hello world
  </div>`;

let client = new AadHttpClient(this.context.serviceScope, '6fc2655e-04cd-437d-a50d-0c1a31383775');

client.get('https://localhost:44361/api/clients', AadHttpClient.configurations.v1)
  .then((res: HttpClientResponse): Promise<any> => {
	return res.json();
  })
  .then(data => {
	console.log(data);
  })
}

However to make it fully work we should perform a few more steps.

4. Deployment and testing

AadHttpClient uses some background magic to perform authenticated call. I will cover how it works in a separate post. For now we need to update our package-solution.json and include additional permissions our app is required. Open package-solution.json and under “solution” node insert:

"webApiPermissionRequests": [
  {
	"resource": "api-sso",
	"scope": "user_impersonation"
  }
]

“resource” is the name of our app registration. You can also put ApplicationId (ClientId) here. In my case that might be '6fc2655e-04cd-437d-a50d-0c1a31383775'. “scope” is permissions we need. user_impersonation means, that we want to access to the service using user’s permissions.

Before testing our web part, we need to deploy it and approve our web api request. This can be achieved in a few steps:

  1. Bundle your web part with:
    gulp bundle --ship
    gulp package-solution --ship
  2. Upload your .sppkg to sharepoint app catalog. After upload, you will see trust dialog, saying that you need to approve permissions for SPFx solution:

   3. In order to approve permission request, go to your SharePoint admin site and switch to new experience. In the left you will see API management link. From API management interface you can approve or reject API requests:

I have api-sso approved in my tenant, meaning that I can safely generate access tokens with AadHttpClient for my remote API.

At this point we are ready to finally test our SPFx web part. You don’t have to deploy it, however you can’t test in local workbench. Only hosted workbench is supported as of now. Make sure your API service is running, run “gulp serve”, go to your SharePoint site’s hosted workbench (_layouts/15/workbench.aspx) and add HelloWorld web part. You will data from your service API in console.

Under the hood AadHttpClient uses the same adal.js library I blogged in a previous post. In next post I will make a deeper dive into AadHttpClient architecture and some findings.

Conclusion

AadHttpClient is the last option I’m going to blog about and this option is recommended way to interact with custom (and only custom, you can add permission request to MS Graph or other services) APIs. This approach uses solid modern authentication principles (OAuth), it’s simple and secure. This approach also has a number of advantages over other approaches:

+ you don’t have IE zones issues here, because adal.js, used in AadHttpClient uses iframes from your SharePoint domain

+ OAuth protocol considered better as cookies

+ because of OAuth, you can request tokens for different services, you can extract id token as well to get info about a user (not possible with cookies approach)

+ no popups. Regularly, you won’t see any authentication popups, because of SSO and in the same domain. However, there might be a situation, when you are logged in a multiple directories, in this case I think there will be popup, but that’s rare situation

+ no reply urls

+ all access tokens are shared across multiple webparts, which means that if you add your web part two times to a page, the same access token will be reused

You see, AadHttpClient has a lot of pros. The only thing is that it’s in preview. I bet that this feature will be available in September at Ignite. Will see Smile