教程:创建 React SPA 以在外部租户中进行身份验证
本教程是一个系列教程的第 2 部分,演示如何生成 React 单页应用程序(保护特权访问 (SPA)),并使用 Microsoft Entra 管理中心准备将其用于身份验证。 在本教程系列的第 1 部分中,你注册了一个应用程序,并在外部租户中配置了用户流。 本教程演示如何使用 npm
创建 React SPA,以及如何创建进行身份验证和授权所需的文件。
在本教程中;
- 在 Visual Studio Code 中创建一个 React 项目
- 安装标识和启动包
- 配置应用程序的设置
先决条件
- 教程:准备外部租户以对 React SPA 中的用户进行身份验证。
- 本教程使用了 Visual Studio Code,但可以使用任何支持 React 应用程序的集成开发环境 (IDE)。
- Node.js。
创建 React 项目
打开 Visual Studio Code,选择“文件>“打开文件夹...”。导航到要在其中创建项目的位置并选中该位置。
通过选择“终端”>“新终端”打开一个新的终端。
运行以下命令以创建一个名为 reactspalocal 的新 React 项目,然后更改为新的目录并启动该 React 项目。 默认情况下,Web 浏览器使用地址
http://localhost:3000/
打开。 浏览器保持打开状态,并重新呈现保存的每个更改。npx create-react-app reactspalocal cd reactspalocal npm start
创建其他文件夹和文件,实现以下文件夹结构:
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。
在“终端”栏中,选择 + 图标以创建新终端。 打开一个新的终端窗口,另一个终端可以在后台继续运行。
如有必要,导航到 reactspalocal 并在终端中输入以下命令,安装
msal
和bootstrap
包。npm install @azure/msal-browser @azure/msal-react npm install react-bootstrap bootstrap
创建身份验证配置文件 authConfig.js
在 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" // };
将以下值替换为 Azure 门户中的值:
- 找到
Enter_the_Application_Id_Here
值并将其替换为你在 Microsoft Entra 管理中心注册的应用的应用程序 ID (clientId)。 - 在“颁发机构”中,找到
Enter_the_Tenant_Subdomain_Here
并将其替换为租户的子域。 例如,如果租户主域为contoso.onmicrosoft.com
,请使用contoso
。 如果没有租户名称,请了解如何读取租户详细信息。
- 找到
保存文件。
使用自定义 URL 域(可选)
使用自定义域可完全标记身份验证 URL。 从用户的角度来看,用户在身份验证过程中仍留在你的域中,而不是重定向到 ciamlogin.com 域名。
通过以下步骤使用自定义域:
使用为外部租户中的应用启用自定义 URL 域中的步骤为外部租户启用自定义 URL 域。
在 authConfig.js 文件中,找到
auth
对象,然后执行以下操作:- 将
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,请了解如何读取租户详细信息。 - 添加值为 [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
。
在 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}/> );