SharePoint Framework ???Azure AD ??????????????????? ???????? API ???Consume multi-tenant enterprise APIs secured with Azure AD in SharePoint Framework

重要

????????????????????????????????AadHttpClientThe AadHttpClient class is currently in preview and is subject to change. ?????????????????Do not use it in a production environment. ???package-solution.json ? webApiPermissionRequests ?????????????????????????Also note that the webApiPermissionRequests properties in package-solution.json are not supported in production tenants.

???????SharePoint Framework ??????????Azure Active Directory ??????????????????? ???????? API ??????????????This article illustrates how you would connect to a multi-tenant enterprise API secured with Azure Active Directory from a SharePoint Framework solution. API ????????????????????SharePoint Framework ????????????????????????????It covers both creating and securing the API as well building the SharePoint Framework solution.

Azure AD ??????????????????? ???????? API ???Create a multi-tenant enterprise API secured with Azure AD

???Azure Active Directory ??????????????????? ???????? API ???????Start with creating a multi-tenant enterprise API secured with Azure Active Directory. SharePoint Framework ????????? API ?????????????????????????????????Azure Functions ????? API ?????Azure App Service ??????? API ?????????????While there are no restrictions how the API should be implemented from the SharePoint Framework point of view, in this tutorial, you will build the API using Azure Functions and secure it using Azure App Service Authentication.

??????????????????? API ?????????????????????????????????????????????????While your organization most likely already has specific APIs exposing their applications, this section is meant to give you a complete overview of the implementation and configuration steps.

Azure ???????Create Azure function

Azure Portal ????? Function ??????????In the Azure Portal (, create a new Function App.

Azure ? Function App ??????????????????????Azure Portal ???????????????????????For more information on creating Function Apps in Azure see the Create a function app from the Azure portal help article.

Function App ??HTTP ????????????????????In the Function App, create new HTTP-triggered function. ????? C# ????????????????????????????????????????????In this example, you will build it using C#, but there is no restriction with regards to which programming language you can use.

Function App ??[????] ??????????In the Function App, select the Create new button.

Azure Portal ???????? [????] ???

???HTTP ???????????????????????[??????] ??????????Next, select on the Custom function link, to create a custom HTTP-triggered function.

Azure Portal ???????? [??????] ???

?????????????????[HTTP ????] ???????From the list of available function types, choose HTTP trigger.

Azure Portal ???????? [HTTP ????] ?????

???????[C#] ???????????????????[?????] ? [??] ???????In the settings of the function, choose C# as the language, specify the function name and set the Authorization level to Anonymous.

Azure Portal ????? Azure ?????

Azure ???????????????????????????Azure functions can be secured in a number of ways. ?????Azure AD ?????????????????????????????????? Function App ?????????????Because you want to secure the function using Azure AD, rather than securing the function itself, you will secure the underlying Function App. ??????????????????????????????????????This is why, at this stage, you set not to secure the function itself. Function App ????????????????????????????????????Authentication settings applied to the Function App, apply to all functions inside that app.

????????????????????[??] ??????????To confirm your settings and create the function, select the Create button.

??????????????????????????????Once the function is created, replace its contents with the following snippet:

using System.Net;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    log.Info("C# HTTP trigger function processed a request.");

    return req.CreateResponse(HttpStatusCode.OK, new List<object> {
        new {
            Id = 1,
            OrderDate = new DateTime(2016, 1, 6),
            Region = "east",
            Rep = "Jones",
            Item = "Pencil",
            Units = 95,
            UnitCost = 1.99,
            Total = 189.05
        },
        new {
            Id = 2,
            OrderDate = new DateTime(2016, 1, 23),
            Region = "central",
            Rep = "Kivell",
            Item = "Binder",
            Units = 50,
            UnitCost = 19.99,
            Total = 999.50
        },
        new {
            Id = 3,
            OrderDate = new DateTime(2016, 2, 9),
            Region = "central",
            Rep = "Jardine",
            Item = "Pencil",
            Units = 36,
            UnitCost = 4.99,
            Total = 179.64
        },
        new {
            Id = 4,
            OrderDate = new DateTime(2016, 2, 26),
            Region = "central",
            Rep = "Gill",
            Item = "Pen",
            Units = 27,
            UnitCost = 19.99,
            Total = 539.73
        },
        new {
            Id = 5,
            OrderDate = new DateTime(2016, 3, 15),
            Region = "west",
            Rep = "Sorvino",
            Item = "Pencil",
            Units = 56,
            UnitCost = 2.99,
            Total = 167.44
        }
    });
}

?????????????????????[???????] ??????????Verify, that the function is working correctly, by selecting the Save and run button.

Azure Portal ???????? [???????] ???

????????????????? ?????? [?????: 200 OK] ??????????????????If the function executed correctly, you should see a Status: 200 OK label and the list orders displayed in the test pane.

Azure ??????????????Secure Azure function

Azure ????????????????????????????? Azure Active Directory ??????????????????????????????????????????????????????Now that the Azure function is working, the next step is for you to secure it with Azure Active Directory so that in order to access it, you need to sign in with your organizational account.

Function App ????????????????? Function App ???????On the Function App blade, from the side panel, select the function app.

Azure Portal ? Function App ???????????????????? Function App

???????????[??????????] ??????????In the top section, switch to the Platform features tab.

Azure Portal ? Function App ???????????? [??????????] ??

???[??????] ?????? [??/??] ??????????Next, from the Networking group, select the Authentication / Authorization link.

Azure Portal ? Function App ???????????? [??/??] ???

[??/??] ??????[App Service ??] ??? ???? [??] ????App Service ??????????On the Authentication / Authorization blade, enable App Service Authentication by switching the App Service Authentication toggle button to On.

Azure Portal ? Function App ?????????????[App Service ??] ??? ???? [??] ?????

[?????????????????????] ??????????? [Azure Active Directory ??????] ???????In the Action to take when request not authenticated drop down, change the value to Login with Azure Active Directory.

Function App ??????????????????[?????????????????????] ???????? [Azure Active Directory ??????] ?????

????????API ????????????????????This setting ensures that anonymous requests to the API are not allowed.

????????????????? [Azure Active Directory] ???????Next, in the list of authentication providers select Azure Active Directory.

Function App ????????????????????? [Azure Active Directory]

[Azure Active Directory ???] ????????? [?????] ???????? [??] ???????On the Azure Active Directory Settings blade, for the first Management mode option, choose Express. 2 ??? [?????] ????????[??? AD ????????] ???????For the second Management mode option, choose Create new AD App.

Azure Portal ? Function App ???? [Azure Active Directory ???] ????

重要

???????[??????] ??????????????Before you continue, note the value in the Create App field. ?????API ??????????????????? Azure AD ????????????????????SharePoint Framework ?? API ????????????????????????????This value represents the name of the Azure AD application that you will use to secure the API, and which you will need later, to request permissions to access the API from the SharePoint Framework project.

[OK] ???????????????????Confirm your selection, by selecting the OK button.

Function App ??????????????????[??] ??????????Update Function App authentication and authorization settings, by selecting the Save button.

Azure Portal ? Function App ? [??/??] ???????????? [??] ???

API ??????????????????????????????????? ???????????? ??????? API ???????Confirm, that the API is correctly secured, by opening a new browser window in private mode and navigating to the API. ???????????????????Azure AD ????? ???????????????If the authentication settings have been applied correctly, you should be redirected to the Azure AD login page.

Azure AD ????? ???

Azure AD ?????????????????????Make the Azure AD application multi-tenant

?????Azure AD ????????????? Azure ????????????????? Azure ????????????????????????????? Azure AD ????????????????By default, when you secure an Azure Function using an Azure AD application, that Azure Function can be used only by users from the same Azure AD as where the application is located. ???????? API ??????????????Azure AD ?????????????????????????????If you would like to use the API in different tenants, you have to change the Azure AD application to multi-tenant.

?????????????????????Change the application to be multi-tenant

Function App ??[??] ?????????In the Function App, navigate to the Authentication settings.

Function App ??????????? [??] ???

???????????????[Azure Active Directory] ???????From the list of authentication providers, select Azure Active Directory.

Function App ????????????????????? [Azure Active Directory]

[Azure Active Directory ???] ??????[???????????] ??????????On the Azure Active Directory Settings blade, choose the Manage Application button.

[Azure Active Directory ???] ???????????? [???????????] ???

[Azure AD ????????] ????????????? [??] ??????????On the Azure AD application blade, from the toolbar, select the Settings button.

[Azure AD ????????] ???????????? [??] ???

[??] ??????[??] ?????? [?????] ????????????On the Settings blade, from the General group, select the Properties option.

[??] ???????????? [?????] ?????

[?????] ????? [??? ID URI] ???????Azure AD ???? ID ? https://yourtenant.onmicrosoft.com ??????????????:On the Properties blade, in the App ID URI field, change the ID of your Azure AD app, so that it begins with https://yourtenant.onmicrosoft.com, eg. https://contoso.onmicrosoft.com/contoso-api. ??????Azure AD ???????????????????? Azure Active Directory ?????????????????????This change is required, because your Azure AD app will be used by other tenants, and it will be necessary to ensure its uniqueness across all Azure Active Directories.

???[???????] ???????? [??] ???????Next, switch the value of the Multi-tenanted field to Yes

Azure AD ?????????????????????????? ID URI ??[??] ?????????????????

???????????????????????? [??] ???????Finally, confirm your changes by from the toolbar selecting the Save button.

?? Azure AD ??????????????????????Allows users from other Azure ADs to use your applications

Azure AD ?????????? API ???????????????? API ????????????????????????? Azure AD ??????????????????Because you secured your API using the Azure AD express settings, only users from the same Azure AD, as where the application is located, are allowed to use it. ???????????? API ?????????????????????????????????????Because you want the API to be used by users from other tenants as well, you have to adjust the security settings.

[??/??] ?????????????????????????????Close all open blades, until you are back on the Authentication / Authorization blade. ???????????????[Azure Active Directory] ???????From the list of authentication providers, choose Azure Active Directory.

Function App ????????????????????? [Azure Active Directory]

[Azure Active Directory ???] ??????[?????] ???????? [??] ????????On the Azure Active Directory Settings blade, switch the value of the Management mode option to Advanced.

Function App ? [Azure Active Directory ???] ?????????[?????] ? [??] ?

???[???? URL] ???????????????Next, clear the value in the Issuer Url field. ???????? Azure Active Directory ????????? API ?????????????????This will allow users from other Azure Active Directories to authenticate against your API.

Function App ? [Azure Active Directory ???] ??????? [?????] ??

????????????[?????? ID] ???????????????Before confirming your changes, copy the value from the Client ID field. ?????API ????? ????????????Web ??????????????????You will need it when building your web part, to request an access token for the API.

[OK] ???????????????????Confirm your changes using the OK button.

CORS ??????Enable CORS

Function App ??SharePoint ??????????? JavaScript ??????????The Function App will be called from JavaScript running on a SharePoint page. ?? API ? SharePoint Portal ?????????????????????API ?????????????? ???????????????????Because the API is hosted on a different domain than the SharePoint portal, cross-domain security constraints will apply to the API call. ?????Azure Function App ?????????? API ??????????????????????By default, APIs implemented using Azure Function Apps cannot be called from other domains. ?????????????????????Function App ? CORS ?????????You can change it, by adjusting the Function App's CORS settings.

Function App ??[??????????] ??????????In the Function App, switch to the Platform features tab.

[API] ???????[CORS] ??????????From the API group, select the CORS link.

Function App ? [??????????] ?????????? [CORS] ???

???????????????SharePoint ????? URL ????????:To the list of allowed origins, add the URL of your SharePoint tenant, eg. https://contoso.sharepoint.com.

Function App ? CORS ?????????????????????? SharePoint ????? URL

[??] ???????????????????Confirm your changes using the Save button.

????????????????? API ?????????????????? API ?????????????Before users in your tenant will be able to use the API from another tenant, the API has to be approved. ?? (????????) ?????????? (??) ? 2 ????????????????The approval, also known as consent, can be done on two levels: user and admin (organization). ??????????????????????????? API ??????????In this scenario, you will use the admin consent to approve the API for use by the whole organization.

注意

????API ??????????????? API ???????????????????Usually, the site exposing the API takes your through the process of consenting the API in your tenant. ?????????????????????????????????????????????In this example, you will perform the necessary steps manually to better understand how the process works.

Function App ??????????????????On the Function App blade, select your function.

Function App ??????????????????? Orders ??

??? URL ???????????????? [??? URL ???] ????????????To get the function's URL, from the toolbar, select the Get function URL option.

Function App ?????????????????? [??? URL ???] ?????

[??? URL ???] ???????[???] ??????????? URL ????????In the Get function URL dialog, copy the URL of the function using the Copy button.

[??? URL ???] ????????????? [???] ???

???????? ??????????????? URL ???????In a new browser window, navigate to the function URL you have just copied. ????????????????API ??????????? Office 365 ???????????????????????????When prompted to sign in, use the admin account from the Office 365 tenant, where you want to use the API.

??????????? API ?????????????????After signing in, you will be prompted to consent with the use of this API.

???????? API ??????????????????

?????????????????This is however the user consent. ??????????????????? API ???????????URL ???? &prompt=admin_consent ???????To switch to the admin consent and approve the API for use by the whole organization, append to the URL &prompt=admin_consent. ????????????????????????????????????????????????????????????????????????????????????????????????????Once again, you will be prompted with a consent dialog, but notice, that this time, the dialog states that the app will have access to the specified resources for all users in your organization and that no one else will be prompted.

???????? API ??????????????????????

[??] ?????????????????? API ??????????????Confirm that you want users in your organization to use the API, by selecting the Accept button.

SharePoint Framework ???Azure AD ???????????? API ?????Consume enterprise API secured with Azure AD from the SharePoint Framework

API ???????????????????????????? API ????? SharePoint Framework ?????????????????With the API configured and working, the next step is to build the SharePoint Framework solution that will consume this API.

???????????? 1.4.1 ??? SharePoint Framework Yeoman ???????????????????????????????Before you proceed, ensure that you have installed version 1.4.1 or higher of the SharePoint Framework Yeoman generator. ?????????????????????????????????? ???? npm ls -g --depth=0 ????????????????????????????????????If you have installed the generator globally, you can check the installed version by executing in the command line: npm ls -g --depth=0.

??? SharePoint Framework ???????????Create new SharePoint Framework project

??????? SharePoint Framework ?????????????Start with creating a new SharePoint Framework project. ???? ??????????????????????????????????????In the command line create new folder for your project:

md contoso-api

???? ???????????????????????????????Change the working directory by executing in the command line:

cd contoso-api

?????????????????????? SharePoint Framework Yeoman ??????????????To create new project, execute the SharePoint Framework Yeoman generator:

yo @microsoft/sharepoint

???????????????????????When prompted, use the following values:

  • ????????: contoso apicontoso-api as the solution name
  • ?????? ?????: SharePoint Online ?? (??)SharePoint Online only (latest) as the baseline packages
  • ?????????: ?????????????Use the current folder as the location to place files
  • ???????????????????: YY as the choice for enabling tenant-wide deployment
  • ??????????????: Web ???WebPart as the type of component to create
  • ???? Web ??????: OrdersOrders as the name of the web part to create
  • Web ??????: ????????Shows recent orders as the web part description
  • ???????????: JavaScript ?????????????No JavaScript framework as the framework to use

????? ??????? SharePoint Framework Yeoman ?????????????

????????????????? ??????????????????After the project is created, open it in the code editor. ????????????Visual Studio Code ???????In this tutorial you will use Visual Studio Code.

Visual Studio Code ???? SharePoint Framework ??????

???????? API ?????????????Request permissions to the enterprise API

?????SharePoint Framework ? Office 365 ??? Azure Active Directory ????????????????????? API ????????????By default, SharePoint Framework has no access to enterprise APIs, even though they are registered in the same Azure Active Directory as Office 365. ?????????????SharePoint ???????????????????????????????? API ???????????????????????????????This is by design and allows organizations to consciously choose which APIs should be exposed to scripts and client-side solutions deployed to SharePoint. ???????? API ???????????????????? SharePoint Framework ?????????????????????????????To get access to your enterprise APIs, you need to issue a permission request from the SharePoint Framework project that you're building.

??? ???????config/package-solution.json ??????????In the code editor, open the config/package-solution.json file.

Visual Studio Code ????????? ??????? ????

[solution] ???????webApiPermissionRequests ???????????????????API ???????????????????? Azure AD ???????????????????To the solution property, add a new section named webApiPermissionRequests with a reference to the Azure AD application used to secure your API:

{
  "$schema": "https://dev.office.com/json-schemas/spfx-build/package-solution.schema.json",
  "solution": {
    "name": "contoso-api-client-side-solution",
    "id": "8cbc01fb-bab6-48fc-afec-2c2053759771",
    "version": "1.0.0.0",
    "includeClientSideAssets": true,
    "skipFeatureDeployment": true,
    "webApiPermissionRequests": [
      {
        "resource": "contoso-api",
        "scope": "user_impersonation"
      }
    ]
  },
  "paths": {
    "zippedPackage": "solution/contoso-api.sppkg"
  }
}

[resource] ?????????API ???????????????????? Azure AD ?????????????? ID ???????????The value of the resource property refers to either the name or the ID of the Azure AD application used to secure the API. ?????????????????????????????????Using the name is more readable and easier to maintain over time. [scope] ????????????????? API ?????????????????????????????The value of the scope property specifies the permission scope that your solution needs in order to communicate with the API. ????????????API ?????????? Azure AD ??????????????? user_impersonation ???????In this tutorial, Azure AD is used only to secure the API, so user_impersonation is the scope that you will use.

注意

????????????? API ????????????????????????? API ???????????????????? Azure AD ?????????????????????If you want to connect to an enterprise API that has been created previously, contact your administrator to provide you with details for the Azure AD application used to secure it. ????????????????? ID???????????????????????????????????????????????????You will need information such as the application ID, permissions the application exposes and the audience it's configured to.

???????? API ?????Connect to the enterprise API

??????????????????? API ?????????????????The last part left is to implement the actual connection to the enterprise API.

??? ???????src\webparts\orders\OrdersWebPart.ts ??????????In the code editor, open the src\webparts\orders\OrdersWebPart.ts file.

Visual Studio Code ???? OrdersWebPart.ts ????

???????????????????? ???????????AadHttpClient ???? HttpClientResponse ??????????In the top section of the file, reference the AadHttpClient and HttpClientResponse classes, by adding the following code snippet:

import { AadHttpClient, HttpClientResponse } from '@microsoft/sp-http';

OrdersWebPart ?????ordersClient ?????????????????????To the OrdersWebPart class, add a new class variable named ordersClient:

export default class OrdersWebPart extends BaseClientSideWebPart<IOrdersWebPartProps> {
  private ordersClient: AadHttpClient;

  // shortened for brevity
}

???AadHttpClient ????????????????OrdersWebPart ???????? onInit ?????????????????Next, in the OrdersWebPart class, override the onInit method to create an instance of the AadHttpClient:

export default class OrdersWebPart extends BaseClientSideWebPart<IOrdersWebPartProps> {
  private ordersClient: AadHttpClient;

  protected onInit(): Promise<void> {
    this.ordersClient = new AadHttpClient(this.context.serviceScope, '594e83da-9618-438f-a40a-4a977c03bc16');

    return Promise.resolve();
  }

  // shortened for brevity
}

AadHttpClient ????????? 2 ???????????????? GUID ?????????? API ???????????????????? Azure AD ?????????????????? ID ???The GUID passed as the second parameter of the AadHttpClient constructor, is the application ID of the Azure AD application used to secure the enterprise API.

???????????? API ????????????????????? render ???????????Finally, extend the render method to load and display orders retrieved from the enterprise API:

export default class OrdersWebPart extends BaseClientSideWebPart<IOrdersWebPartProps> {
  private ordersClient: AadHttpClient;

  protected onInit(): Promise<void> {
    this.ordersClient = new AadHttpClient(this.context.serviceScope, '594e83da-9618-438f-a40a-4a977c03bc16');

    return Promise.resolve();
  }

  public render(): void {
    this.context.statusRenderer.displayLoadingIndicator(this.domElement, 'orders');

    this.ordersClient
      .get('https://contoso-apis.azurewebsites.net/api/Orders', AadHttpClient.configurations.v1)
      .then((res: HttpClientResponse): Promise<any> => {
        return res.json();
      })
      .then((orders: any): void => {
        this.context.statusRenderer.clearLoadingIndicator(this.domElement);
        this.domElement.innerHTML = `
          <div class="${ styles.orders}">
            <div class="${ styles.container}">
              <div class="${ styles.row}">
                <div class="${ styles.column}">
                  <span class="${ styles.title}">Orders</span>
                  <p class="${ styles.description}">
                    <ul>
                      ${orders.map(o => `<li>${o.Rep} $${o.Total}</li>`).join('')}
                    </ul>
                  </p>
                  <a href="https://aka.ms/spfx" class="${ styles.button}">
                    <span class="${ styles.label}">Learn more</span>
                  </a>
                </div>
              </div>
            </div>
          </div>`;
      }, (err: any): void => {
        this.context.statusRenderer.renderError(this.domElement, err);
      });
  }

  // shortened for brevity
}

???????? SharePoint ??? ?????????Deploy the solution to SharePoint app catalog

SharePoint Framework ??????????????????????????????????? SharePoint ??????????After completing the implementation of the SharePoint Framework solution, the next step is to deploy it to SharePoint.

?????????????????????????????? ?????????????????First, build and package the project, by executing in the command line:

gulp bundle --ship && gulp package-solution --ship

?????????????????? ?????????sharepoint/solution ????????????Next, in the explorer, open the project folder and navigate to the sharepoint/solution folder.

macOS Finder ???? 'sharepoint/solution' ?????? ?????

Web ???????Office 365 ????????? ??? ???????????In your web browser, navigate to the tenant app catalog in your Office 365 tenant.

Web ??????????????? ??? ????

???????? .sppkg ??????????????????? ??? ????????? ??? ????????Add the newly generated .sppkg file by dragging and dropping it from explorer to the tenant app catalog.

Web ???????????????????? ??? ????????? macOS Finder ?????

?????????????[?????????????????????????????] ???? ????????????When prompted, select the Make this solution available to all sites in the organization checkbox. ???[???? ?????? ???????????] ???????????????????????????????????????Also, take note of the remark, that you should go to the Service Principal Permissions Management Page to approve pending permission requests. [??] ??????????????????Confirm the deployment by selecting the Deploy button.

Web ????????????SharePoint Framework ??????? ???????????????????????

???????? API ???????????Grant access to the enterprise API

Web ????????????????????????Office 365 ????????? [??] ????????????In the web browser, navigate to the tenant admin site by choosing from the Office 365 app launcher, the Admin option.

Office 365 ????????????????????? [??] ?????

????? [??????] ???????[SharePoint] ???????In the menu, from the Admin centers group, choose SharePoint.

Office 365 ??????????????????? [SharePoint] ?????

SharePoint ????????[??? SharePoint ????????????????????] ???????????? SharePoint ???????????????????In the SharePoint admin center, navigating to the new SharePoint admin center preview using the Try the new SharePoint admin center preview link.

SharePoint ?????????????? [??? SharePoint ??????????????] ???

????????????????? [API ??] ????????????In the new admin center, from the menu, choose the API management option.

??? SharePoint ??????????????????? [API ??] ?????

[API ??] ???? [????] ??????contoso-api API ?????????????????????????????????On the API management page, in the Pending approval group, select the newly added permission request to access the contoso-api API.

??? SharePoint ??????? [API ??] ????????????????????????????

?????????? [?????????] ????????????Next, from the toolbar, select the Approve or reject option.

??? SharePoint ??????? [API ??] ????????????????? [?????????] ?????

???????? [??] ?????????API ?????????????In the side panel, grant the access to the API by selecting the Approve button.

??? SharePoint ??????? API ????????????????????????? [??] ???

Orders Web ????????????Add the Orders web part to the page

???????????????????????????????? Orders Web ??????????????To verify that everything is working as expected, add the previously created Orders web part to the page.

Web ???????????????????????In the web browser, navigate to a site in your tenant. ??????? [??] ????????????From the toolbar, select the Edit option.

??? ??? ????????????????? [??] ???

???????Web ????????????????????In the canvas, select a section to add the web part to.

Web ??????????????????????

???????????????????????+Select the + option to open the toolbox. Orders Web ??????????????????????? Orders ???????In the search box type Orders to quickly find the Orders web part.

????????????? 'Orders'

Orders Web ??????????????????Select the Orders web part to add it to the page. ???????? API ????????????????????????You should see the list of orders retrieved from the enterprise API.

SharePoint ?????????????????? API ????????????????