Adición de un botón de inicio de sesión de autenticación de Microsoft a una aplicación de página única
Agregue la autenticación de Microsoft en este tutorial de TypeScript para proporcionar un botón de inicio y cierre de sesión. Desarrolle la aplicación con el SDK del lado cliente de Azure, @azure/msal-browser, para proporcionar funcionalidad de autenticación.
Arquitectura y funcionalidad de la aplicación
La SPA creada en este tutorial es una aplicación de React (create-react-app) con las siguientes tareas:
- Inicio de sesión con un inicio de sesión compatible con Microsoft, como Office 365 u Outlook.com
- Cierre de sesión de la aplicación
Para proporcionar una aplicación de página única rápida y sencilla, el ejemplo usa create-react-app con TypeScript. Este marco de front-end proporciona varios accesos directos en el desarrollo de cliente típico con los SDK de Azure:
- Agrupación, necesaria para los SDK de Azure utilizados en una aplicación cliente
- Variables de entorno en el archivo
.env
1. Configuración del entorno de desarrollo
Compruebe que el software siguiente está instalado en el equipo local.
- Una cuenta de usuario de Azure con una suscripción activa. cree una de forma gratuita.
- Node.js y npm: instalados en la máquina local.
- Visual Studio Code o un IDE equivalente con el shell de bash o el terminal instalado en el equipo local.
2. Tomar nota del valor de la variable de entorno
Prepare un lugar para copiar el valor del id. de cliente del registro de la aplicación, por ejemplo, en un archivo de texto. Obtendrá el id. de cliente en el paso 5 de la siguiente sección. El valor se utilizará como una variable de entorno para la aplicación web.
3. Creación del registro de aplicación para la autenticación
Inicie sesión en Azure Portal y vaya a la opción Registros de aplicaciones del directorio predeterminado.
Seleccione + Nuevo registro.
Escriba los datos de registro de la aplicación según la tabla siguiente:
Campo Valor Descripción Nombre Simple Auth TutorialEste es el nombre de la aplicación que el usuario verá en el formulario de permisos cuando inicie sesión en la aplicación. Tipos de cuenta admitidos Cuentas en cualquier directorio organizativo (cualquier directorio de Azure AD: multiinquilino) y cuentas Microsoft personales Esto incluye la mayoría de los tipos de cuenta. Tipo de identificador URI de redirección Aplicación de una sola página (SPA) Valor del identificador URI de redirección http://localhost:3000Dirección URL a la que se va a volver después de que la autenticación se realice correctamente o produzca un error.
Seleccione Registrar. Espere a que se complete el proceso de registro de la aplicación.
Copie el identificador de la aplicación (cliente) de la sección Información general del registro de la aplicación. Agregará este valor a la variable de entorno para la aplicación cliente más adelante.
4. Creación de una aplicación de página única de React para TypeScript
En un shell de Bash, cree una aplicación create-react-app con TypeScript como lenguaje:
npx create-react-app tutorial-demo-login-button --template typescriptCambie al nuevo directorio e instale el paquete de autenticación
@azure/msal-browser:cd tutorial-demo-login-button && npm install @azure/msal-browserCree un archivo
.enven el nivel raíz y agregue la línea siguiente:REACT_APP_AZURE_ACTIVE_DIRECTORY_APP_CLIENT_ID=El archivo
.envse lee como parte del marco create-react-app. En este archivo puede almacenar el identificador de cliente para el desarrollo local.Copie el identificador de la aplicación (cliente) en el valor.
5. Adición de los botones de inicio y cierre de sesión
Para los archivos específicos de Azure, cree una subcarpeta llamada
azuredentro de la carpeta./src.Cree un nuevo archivo para la configuración de la autenticación en la carpeta
azurellamadoazure-authentication-config.tsy copie en él el código siguiente:import { Configuration, LogLevel } from "@azure/msal-browser"; const AzureActiveDirectoryAppClientId: any = process.env.REACT_APP_AZURE_ACTIVE_DIRECTORY_APP_CLIENT_ID; export const MSAL_CONFIG: Configuration = { auth: { clientId: AzureActiveDirectoryAppClientId, }, cache: { cacheLocation: "sessionStorage", storeAuthStateInCookie: false, }, 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; } }, }, }, };Este archivo lee el identificador de la aplicación desde el archivo
.env, establece la sesión como almacenamiento del explorador en lugar de cookies y proporciona un registro que se considera información personal.Cree un nuevo archivo para el middleware de autenticación de Azure en la carpeta
azurellamadoazure-authentication-context.tsy copie en él el código siguiente:import { PublicClientApplication, AuthenticationResult, AccountInfo, EndSessionRequest, RedirectRequest, PopupRequest, } from "@azure/msal-browser"; import { MSAL_CONFIG } from "./azure-authentication-config"; export class AzureAuthenticationContext { private myMSALObj: PublicClientApplication = new PublicClientApplication( MSAL_CONFIG ); private account?: AccountInfo; private loginRedirectRequest?: RedirectRequest; private loginRequest?: PopupRequest; public isAuthenticationConfigured = false; constructor() { // @ts-ignore this.account = null; this.setRequestObjects(); if (MSAL_CONFIG?.auth?.clientId) { this.isAuthenticationConfigured = true; } } private setRequestObjects(): void { this.loginRequest = { scopes: [], prompt: "select_account", }; this.loginRedirectRequest = { ...this.loginRequest, redirectStartPage: window.location.href, }; } login(signInType: string, setUser: any): void { if (signInType === "loginPopup") { this.myMSALObj .loginPopup(this.loginRequest) .then((resp: AuthenticationResult) => { this.handleResponse(resp, setUser); }) .catch((err) => { console.error(err); }); } else if (signInType === "loginRedirect") { this.myMSALObj.loginRedirect(this.loginRedirectRequest); } } logout(account: AccountInfo): void { const logOutRequest: EndSessionRequest = { account, }; this.myMSALObj.logout(logOutRequest); } handleResponse(response: AuthenticationResult, incomingFunction: any) { if(response !==null && response.account !==null) { this.account = response.account; } else { this.account = this.getAccount(); } if (this.account) { incomingFunction(this.account); } } private getAccount(): AccountInfo | undefined { console.log(`loadAuthModule`); const currentAccounts = this.myMSALObj.getAllAccounts(); if (currentAccounts === null) { // @ts-ignore console.log("No accounts detected"); return undefined; } if (currentAccounts.length > 1) { // TBD: Add choose account code here // @ts-ignore console.log( "Multiple accounts detected, need to add choose account code." ); return currentAccounts[0]; } else if (currentAccounts.length === 1) { return currentAccounts[0]; } } } export default AzureAuthenticationContext;Este archivo proporciona la autenticación en Azure para un usuario con las funciones
loginylogout.Cree un nuevo archivo para el archivo del componente del botón de la interfaz de usuario en la carpeta
azurellamadoazure-authentication-component.tsxy copie en él el código siguiente:import React, { useState } from "react"; import AzureAuthenticationContext from "./azure-authentication-context"; import { AccountInfo } from "@azure/msal-browser"; const ua = window.navigator.userAgent; const msie = ua.indexOf("MSIE "); const msie11 = ua.indexOf("Trident/"); const isIE = msie > 0 || msie11 > 0; // Log In, Log Out button const AzureAuthenticationButton = ({ onAuthenticated }: any): JSX.Element => { // Azure client context const authenticationModule: AzureAuthenticationContext = new AzureAuthenticationContext(); const [authenticated, setAuthenticated] = useState<Boolean>(false); const [user, setUser] = useState<AccountInfo>(); const logIn = (method: string): any => { const typeName = "loginPopup"; const logInType = isIE ? "loginRedirect" : typeName; // Azure Login authenticationModule.login(logInType, returnedAccountInfo); }; const logOut = (): any => { if (user) { onAuthenticated(undefined); // Azure Logout authenticationModule.logout(user); } }; const returnedAccountInfo = (user: AccountInfo) => { // set state setAuthenticated(user?.name ? true : false); onAuthenticated(user); setUser(user); }; const showLogInButton = (): any => { return ( <button id="authenticationButton" onClick={() => logIn("loginPopup")}> Log in </button> ); }; const showLogOutButton = (): any => { return ( <div id="authenticationButtonDiv"> <div id="authentication"> <button id="authenticationButton" onClick={() => logOut()}> Log out </button> </div> </div> ); }; const showButton = (): any => { return authenticated ? showLogOutButton() : showLogInButton(); }; return ( <div id="authentication"> {authenticationModule.isAuthenticationConfigured ? ( showButton() ) : ( <div>Authentication Client ID is not configured.</div> )} </div> ); }; export default AzureAuthenticationButton;Este componente del botón inicia la sesión de un usuario y devuelve la cuenta de usuario al componente autor de la llamada o primario.
El texto y la funcionalidad del botón se alternan en función de si el usuario tiene sesión iniciada actualmente, lo que se captura con la función
onAuthenticatedcomo una propiedad que se pasa al componente.Cuando un usuario inicia sesión, el botón llama al método
authenticationModule.loginde la biblioteca de autenticación de Azure conreturnedAccountInfocomo la función de devolución de llamada. A continuación, la cuenta de usuario devuelta se vuelve a pasar al componente primario con la funciónonAuthenticated.Abra el archivo
./src/App.tsxy reemplace todo el código por el código siguiente para incorporar el componente del botón de inicio de sesión y cierre de sesión:import React, { useState } from "react"; import AzureAuthenticationButton from "./azure/azure-authentication-component"; import { AccountInfo } from "@azure/msal-browser"; function App() { // current authenticated user const [currentUser, setCurrentUser] = useState<AccountInfo>(); // authentication callback const onAuthenticated = async (userAccountInfo: AccountInfo) => { setCurrentUser(userAccountInfo); }; // Render JSON data in readable format const PrettyPrintJson = ({ data }: any) => { return ( <div> <pre>{JSON.stringify(data, null, 2)}</pre> </div> ); }; // Quick link - user revokes app's permission const ShowPermissionRevokeLinks = () => { return ( <div> <div><a href="https://myapps.microsoft.com" target="_blank" rel="noopener">Revoke AAD permission</a></div> <div><a href="https://account.live.com/consent/manage" target="_blank" rel="noopener">Revoke Consumer permission</a></div> </div> ); }; return ( <div id="App"> <h2>Microsoft Login Button application</h2> <AzureAuthenticationButton onAuthenticated={onAuthenticated} /> {currentUser && ( <div> <PrettyPrintJson data={currentUser} /> <ShowPermissionRevokeLinks /> </div> )} </div> ); } export default App;Después de que un usuario inicia sesión y la autenticación redirige de vuelta a esta aplicación, se muestra el objeto currentUser.
6. Ejecución de la aplicación de página única de React con el botón de inicio de sesión
Inicie la aplicación en el terminal de Visual Studio Code:
npm run startObserve VSCode integrado para ver que la aplicación está completamente iniciada.
Compiled successfully! You can now view js-e2e-client-azure-login-button in the browser. Local: http://localhost:3000 On Your Network: http://x.x.x.x:3000 Note that the development build is not optimized. To create a production build, use yarn build.Abra la aplicación web en un explorador,
http://localhost:3000.Seleccione el botón de inicio de sesión en el explorador web.
Seleccione una cuenta de usuario. No tiene que ser la misma cuenta que usó para acceder a Azure Portal, pero debe ser una cuenta que proporcione autenticación de Microsoft.
Revise el elemento emergente que muestra 1) nombre de usuario, 2) nombre de aplicación, 3) permisos que va a aceptar y, a continuación, seleccione Sí.
Revise la información de la cuenta de usuario.
Seleccione el botón de cierre de sesión de la aplicación. La aplicación también proporciona vínculos cómodos a las aplicaciones de usuario de Microsoft para revocar los permisos.
7. Almacenamiento de la información de usuario específica de la aplicación
Opcionalmente, puede almacenar el identificador de usuario en su propia base de datos de aplicación para poner en correlación la identidad del proveedor de Microsoft y los datos del usuario necesarios en su propia aplicación. La notificación de token contiene dos identificadores de los que puede que desee realizar un seguimiento:
- sub: el identificador que es específico del usuario, para el identificador de aplicación de Active Directory específico. Este es el identificador que debe almacenar en su propia base de datos de aplicación, si necesita poner en correlación los datos de la aplicación personalizada con el usuario del proveedor de identidades de Microsoft.
- oid: se trata del identificador de usuario universal en todas las aplicaciones del proveedor de identidades de Microsoft. Almacene este valor si necesita realizar un seguimiento del usuario en varias aplicaciones del proveedor de identidades.
8. Limpieza de recursos
Cuando haya terminado de usar este tutorial, elimine la aplicación de la lista de registros de aplicaciones de Azure Portal.
Si quiere mantener la aplicación pero desea revocar el permiso dado a la aplicación por su cuenta de usuario específica, use uno de los siguientes vínculos:
Pasos siguientes
- Inicio de sesión único con MASL.js
- MSAL.js
- Ejemplos de MSAL.js
- Todos los ejemplos de MSAL
- Continúe con la biblioteca MSAL para obtener el perfil de usuario y proporcionar un inicio de sesión silencioso.
- Agregue Microsoft Graph para acceder a las cuentas de usuario en Microsoft 365, incluidos el correo electrónico y las citas del calendario.
- Azure Static Web Apps
- Azure Web Apps