教程:创建 React SPA 以在外部租户中进行身份验证

本教程是一个系列教程的第 2 部分,演示如何生成 React 单页应用程序(保护特权访问 (SPA)),并使用 Microsoft Entra 管理中心准备将其用于身份验证。 在本教程系列的第 1 部分中,你注册了一个应用程序,并在外部租户中配置了用户流。 本教程演示如何使用 npm 创建 React SPA,以及如何创建进行身份验证和授权所需的文件。

在本教程中;

  • 在 Visual Studio Code 中创建一个 React 项目
  • 安装标识和启动包
  • 配置应用程序的设置

先决条件

创建 React 项目

  1. 打开 Visual Studio Code,选择“文件>“打开文件夹...”。导航到要在其中创建项目的位置并选中该位置。

  2. 通过选择“终端”>“新终端”打开一个新的终端。

  3. 运行以下命令以创建一个名为 reactspalocal 的新 React 项目,然后更改为新的目录并启动该 React 项目。 默认情况下,Web 浏览器使用地址 http://localhost:3000/ 打开。 浏览器保持打开状态,并重新呈现保存的每个更改。

    npx create-react-app reactspalocal
    cd reactspalocal
    npm start
    
  4. 创建其他文件夹和文件,实现以下文件夹结构:

    reactspalocal
    ├─── public
    │   └─── index.html
    └───src
        ├─── components
        │   └─── DataDisplay.jsx
        │   └─── NavigationBar.jsx
        │   └─── PageLayout.jsx
        └───styles
        │   └─── App.css
        │   └─── index.css
        └─── utils
        │    └─── claimUtils.js
        └── App.jsx
        └── authConfig.js
        └── index.js
    

安装应用依赖项

必须在项目中安装与标识相关的 npm 包才能启用用户身份用作。 对于项目样式,使用 Bootstrap。

  1. 在“终端”栏中,选择 + 图标以创建新终端。 打开一个新的终端窗口,另一个终端可以在后台继续运行。

  2. 如有必要,导航到 reactspalocal 并在终端中输入以下命令,安装 msalbootstrap 包。

    npm install @azure/msal-browser @azure/msal-react
    npm install react-bootstrap bootstrap
    

创建身份验证配置文件 authConfig.js

  1. 在 src 文件夹中,打开 authConfig.js 并添加以下代码片段:

    /*
     * Copyright (c) Microsoft Corporation. All rights reserved.
     * Licensed under the MIT License.
     */
    
    import { LogLevel } from '@azure/msal-browser';
    
    /**
     * Configuration object to be passed to MSAL instance on creation.
     * For a full list of MSAL.js configuration parameters, visit:
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/configuration.md 
     */
    
    export const msalConfig = {
        auth: {
            clientId: 'Enter_the_Application_Id_Here', // This is the ONLY mandatory field that you need to supply.
            authority: 'https://Enter_the_Tenant_Subdomain_Here.ciamlogin.com/', // Replace the placeholder with your tenant subdomain 
            redirectUri: '/', // Points to window.location.origin. You must register this URI on Azure Portal/App Registration.
            postLogoutRedirectUri: '/', // Indicates the page to navigate after logout.
            navigateToLoginRequestUrl: false, // If "true", will navigate back to the original request location before processing the auth code response.
        },
        cache: {
            cacheLocation: 'sessionStorage', // Configures cache location. "sessionStorage" is more secure, but "localStorage" gives you SSO between tabs.
            storeAuthStateInCookie: false, // Set this to "true" if you are having issues on IE11 or Edge
        },
        system: {
            loggerOptions: {
                loggerCallback: (level, message, containsPii) => {
                    if (containsPii) {
                        return;
                    }
                    switch (level) {
                        case LogLevel.Error:
                            console.error(message);
                            return;
                        case LogLevel.Info:
                            console.info(message);
                            return;
                        case LogLevel.Verbose:
                            console.debug(message);
                            return;
                        case LogLevel.Warning:
                            console.warn(message);
                            return;
                        default:
                            return;
                    }
                },
            },
        },
    };
    
    /**
     * Scopes you add here will be prompted for user consent during sign-in.
     * By default, MSAL.js will add OIDC scopes (openid, profile, email) to any login request.
     * For more information about OIDC scopes, visit:
     * https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
     */
    export const loginRequest = {
        scopes: [],
    };
    
    /**
     * An optional silentRequest object can be used to achieve silent SSO
     * between applications by providing a "login_hint" property.
     */
    // export const silentRequest = {
    //     scopes: ["openid", "profile"],
    //     loginHint: "example@domain.net"
    // };
    
  2. 将以下值替换为 Azure 门户中的值:

    • 找到 Enter_the_Application_Id_Here 值并将其替换为你在 Microsoft Entra 管理中心注册的应用的应用程序 ID (clientId)
    • 在“颁发机构”中,找到 Enter_the_Tenant_Subdomain_Here 并将其替换为租户的子域。 例如,如果租户主域为 contoso.onmicrosoft.com,请使用 contoso。 如果没有租户名称,请了解如何读取租户详细信息
  3. 保存文件。

使用自定义 URL 域(可选)

使用自定义域可完全标记身份验证 URL。 从用户的角度来看,用户在身份验证过程中仍留在你的域中,而不是重定向到 ciamlogin.com 域名

通过以下步骤使用自定义域:

  1. 使用为外部租户中的应用启用自定义 URL 域中的步骤为外部租户启用自定义 URL 域。

  2. 在 authConfig.js 文件中,找到 auth 对象,然后执行以下操作

    1. authority 属性的值更新为 https://Enter_the_Custom_Domain_Here/Enter_the_Tenant_ID_Here。 将 Enter_the_Custom_Domain_Here 替换为你的自定义 URL 域,并将 Enter_the_Tenant_ID_Here 替换为你的租户 ID。 如果没有租户 ID,请了解如何读取租户详细信息
    2. 添加值为 [Enter_the_Custom_Domain_Here] 的 knownAuthorities 属性

对 authConfig.js 文件进行更改后,如果自定义 URL 域为 login.contoso.com 且租户 ID 为 aaaabbbb-0000-cccc-1111-dddd2222eeee,则文件应类似于以下代码片段

//...
const msalConfig = {
    auth: {
        authority: process.env.AUTHORITY || 'https://login.contoso.com/aaaabbbb-0000-cccc-1111-dddd2222eeee', 
        knownAuthorities: ["login.contoso.com"],
        //Other properties
    },
    //...
};

修改 index.js 以包含身份验证提供程序

需要身份验证的所有应用部分均必须包装在 MsalProvider 组件中。 实例化 PublicClientApplication,然后将其传递至 MsalProvider

  1. 在 src 文件夹中,打开 index.js,将该文件的内容替换为以下代码片段以使用 msal 包和启动样式设置:

    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import App from './App';
    import { PublicClientApplication, EventType } from '@azure/msal-browser';
    import { msalConfig } from './authConfig';
    
    import 'bootstrap/dist/css/bootstrap.min.css';
    import './styles/index.css';
    
    /**
     * MSAL should be instantiated outside of the component tree to prevent it from being re-instantiated on re-renders.
     * For more, visit: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-react/docs/getting-started.md
     */
    const msalInstance = new PublicClientApplication(msalConfig);
    
    // Default to using the first account if no account is active on page load
    if (!msalInstance.getActiveAccount() && msalInstance.getAllAccounts().length > 0) {
        // Account selection logic is app dependent. Adjust as needed for different use cases.
        msalInstance.setActiveAccount(msalInstance.getActiveAccount()[0]);
    }
    
    // Listen for sign-in event and set active account
    msalInstance.addEventCallback((event) => {
        if (event.eventType === EventType.LOGIN_SUCCESS && event.payload.account) {
            const account = event.payload.account;
            msalInstance.setActiveAccount(account);
        }
    });
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
        <App instance={msalInstance}/>
    );
    

下一步