适用于: 员工租户
外部租户(了解详细信息)
在本教程中,你将生成 React 单页应用程序(SPA),并准备使用Microsoft标识平台进行身份验证。 本教程演示如何使用 npm
React SPA 创建、创建身份验证和授权所需的文件,并将租户详细信息添加到源代码。 应用程序可用于员工租户中的员工或使用外部租户的客户。
在本教程中,你将:
- 创建新的 React 项目
- 安装身份验证所需的包
- 创建文件结构并将代码添加到服务器文件
- 将租户详细信息添加到身份验证配置文件
先决条件
- 工作人员租户。 可以使用 默认目录 或设置新租户。
- 在 Microsoft Entra 管理中心注册一个新应用,并配置为仅适用于此组织目录中的帐户。 有关更多详细信息 ,请参阅注册应用程序 。 在应用程序 概述 页中记录以下值供以后使用:
- 应用程序(客户端)ID
- 目录(租户)ID
- 使用 单页应用程序 平台配置添加以下重定向 URI。 有关更多详细信息 ,请参阅如何在应用程序中添加重定向 URI 。
- Redirect URI:
http://localhost:3000/
.
- Redirect URI:
- Node.js。
- Visual Studio Code 或其他代码编辑器。
创建新的 React 项目
打开 Visual Studio Code,选择“文件>“打开文件夹...”。导航到要在其中创建项目的位置并选中该位置。
通过选择“终端”>“新终端”打开一个新的终端。
运行以下命令以创建一个名为 reactspalocal 的新 React 项目,然后更改为新的目录并启动该 React 项目。 默认情况下,Web 浏览器将使用地址
http://localhost:3000/
打开。 浏览器保持打开状态,并重新呈现保存的每个更改。npx create-react-app reactspalocal cd reactspalocal npm start
创建其他文件夹和文件,实现以下文件夹结构:
├─── public │ └─── index.html └───src └─── styles │ └─── App.css │ └─── index.css ├─── utils │ └─── claimUtils.js ├─── components │ └─── DataDisplay.jsx │ └─── NavigationBar.jsx │ └─── PageLayout.jsx └── App.jsx └── authConfig.js └── index.js
安装标识和启动包
必须在项目中安装与身份验证相关的 npm 包才能启用用户身份验证。 对于项目样式设置,将使用 Bootstrap 。
在“终端”栏中,选择 + 图标以创建新终端。 此时会打开单独的终端窗口,上一个节点终端将继续在后台运行。
确保选择正确的目录(reactspalocal),然后在终端中输入以下内容以安装相关
msal
和bootstrap
包。npm install @azure/msal-browser @azure/msal-react npm install react-bootstrap bootstrap
将租户详细信息添加到 MSAL 配置
authConfig.js 文件包含身份验证流的配置设置,用于使用所需的身份验证设置来配置 MSAL.js。
在 src 文件夹中,打开 authConfig.js 并添加以下代码片段:
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://login.microsoftonline.com/Enter_the_Tenant_Info_Here', // Replace the placeholder with your tenant info redirectUri: 'http://localhost:3000/redirect', // Points to window.___location.origin. You must register this URI on Microsoft Entra admin center/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/en-us/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" // };
将下列值替换为 Microsoft Entra 管理中心中的值。
clientId
- 应用程序的标识符,也称为客户端。 将Enter_the_Application_Id_Here
替换为注册应用程序的概述页中先前记录的应用程序(客户端) ID 值。authority
- 它是由两个部分组成:- 实例是云提供商的终结点。 在“国家云”查看可用的不同终结点。
- “租户 ID”是在其中注册应用程序的租户的标识符。 将 Enter_the_Tenant_Info_Here 替换为已注册应用程序的概述页中先前记录的“目录(租户)ID”值。
保存文件。
添加身份验证提供商
包 msal
用于在应用程序中提供身份验证。 包 msal-browser
用于处理身份验证流,包 msal-react
用于与 React 集成 msal-browser
。 addEventCallback
用于侦听身份验证过程中发生的事件,例如当用户成功登录时。 setActiveAccount
方法用于设置应用程序的活动帐户,它将用于确定要显示的用户信息。
在 src 文件夹中,打开 index.js,将该文件的内容替换为以下代码片段以使用
msal
包和 Bootstrap 样式:import React from 'react'; import { createRoot } 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 = createRoot(document.getElementById('root')); root.render( <App instance={msalInstance}/> );
保存文件。
若要了解有关这些包的详细信息,请参阅以下文档:msal-browser
msal-react
添加主应用程序组件
需要身份验证的所有应用部分均必须包装在 MsalProvider
组件中。 设置一个 instance
变量,该变量调用 useMsal
挂钩以获取 PublicClientApplication
实例,然后将其传递给 MsalProvider
。 MsalProvider
组件通过 React 的上下文 API 在整个应用中提供 PublicClientApplication
实例。 所有MsalProvider
下的组件将通过上下文访问PublicClientApplication
实例,并且所有由msal-react
提供的挂钩和组件也可供使用。
在 src 文件夹中,打开 App.jsx 并将文件的内容替换为以下代码片段:
import { MsalProvider, AuthenticatedTemplate, useMsal, UnauthenticatedTemplate } from '@azure/msal-react'; import { Container, Button } from 'react-bootstrap'; import { PageLayout } from './components/PageLayout'; import { IdTokenData } from './components/DataDisplay'; import { loginRequest } from './authConfig'; import './styles/App.css'; /** * Most applications will need to conditionally render certain components based on whether a user is signed in or not. * msal-react provides 2 easy ways to do this. AuthenticatedTemplate and UnauthenticatedTemplate components will * only render their children if a user is authenticated or unauthenticated, respectively. For more, visit: * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-react/docs/getting-started.md */ const MainContent = () => { /** * useMsal is hook that returns the PublicClientApplication instance, * that tells you what msal is currently doing. For more, visit: * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-react/docs/hooks.md */ const { instance } = useMsal(); const activeAccount = instance.getActiveAccount(); const handleRedirect = () => { instance .loginRedirect({ ...loginRequest, prompt: 'create', }) .catch((error) => console.log(error)); }; return ( <div className="App"> <AuthenticatedTemplate> {activeAccount ? ( <Container> <IdTokenData idTokenClaims={activeAccount.idTokenClaims} /> </Container> ) : null} </AuthenticatedTemplate> <UnauthenticatedTemplate> <Button className="signInButton" onClick={handleRedirect} variant="primary"> Sign up </Button> </UnauthenticatedTemplate> </div> ); }; /** * msal-react is built on the React context API and all parts of your app that require authentication must be * wrapped in the MsalProvider component. You will first need to initialize an instance of PublicClientApplication * then pass this to MsalProvider as a prop. All components underneath MsalProvider will have access to the * PublicClientApplication instance via context as well as all hooks and components provided by msal-react. For more, visit: * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-react/docs/getting-started.md */ const App = ({ instance }) => { return ( <MsalProvider instance={instance}> <PageLayout> <MainContent /> </PageLayout> </MsalProvider> ); }; export default App;
保存文件。