React
Azure MSAL¶
Introducción a la biblioteca de autenticación de Microsoft (MSAL)¶
MSAL permite a los desarrolladores adquirir tokens de la plataforma de identidad de Microsoft para autenticar a los usuarios y acceder a las API web seguras.
Se puede utilizar para proporcionar acceso seguro a Microsoft Graph, otras API de Microsoft, API web de terceros o su propia API web.
Adquiera y almacene tokens¶
Los tokens de acceso permiten a los clientes llamar de forma segura a las API web protegidas por Azure.
Hay varias formas de adquirir un token, algunas requieren la interacción del usuario a través de un navegador web, mientras que otros no requieren la interacción del usuario. En general, el método utilizado para adquirir un token depende de si la aplicación es una aplicación de cliente pública (como una aplicación de escritorio o móvil), o una aplicación de cliente confidencial (como una aplicación web, una API web o una aplicación daemon).
En esta ocacion vamos crear una aplicación de página única (SPA) de React que inicia la sesión de los usuarios y llama a Microsoft Graph mediante el flujo de código de autorización con PKCE. La aplicación de página única que cree usa la biblioteca de autenticación de Microsoft (MSAL) para React.
Pre requisitos:¶
- Tener Git Instalado
- Tener Node.js
- Visual Studios Code o algun otro editor de codigo
Obtención del código de ejemplo completado¶
Vamos a clonar el siguente repo con el comando:
git clone https://github.com/architecture-it/msal-browser-react.git
El cual tiene la siguiente estructura de archivos:
📁msal-browser-react
├─── 📁.github
├─── 📁.vscode
├─── 📁public
├─── 📁src
│ ├─── 📁@types
│ ├─── 📁components
│ ├─── 📁constants
│ │ └───📃AUTH.ts
│ ├─── 📁hooks
│ │ └─── 📁use-token
│ │ └───📃index.tsx
│ ├─── 📁layout
│ ├─── 📁pages
│ │ ├─── 📁Home
│ │ │ ├───📃index.tsx
│ │ │ └───📃Home.module.scss
│ │ └─── 📁User
│ │ ├───📃index.tsx
│ │ └───📃User.module.scss
│ ├─── 📁routes
│ │ ├─── 📃index.tsx
│ │ └─── 📃ProtectedRoute.tsx
│ ├─── 📁skeletons
│ │ └─── 📁Principal
│ │ ├───📃index.tsx
│ │ └───📃Principal.module.scss
│ ├─── services
│ │ └───📃ServiceBase.ts
│ ├─── 📁test-utils
│ ├─── 📃App.tsx
│ ├─── 📃msalInstance.js
│ ├─── 📃index.tsx
│ ├─── 📃react-app-env.d.ts
│ ├─── 📃sample.test
├─── .dockerignore
├─── .env
├─── 📃.eslintrc.js
├─── .gitignore
├─── 📃Dockerfile
├─── 📃package-lock.json
├─── 📃package.json
├─── 📃stylelint.config.js
└─── 📃tsconfig.json
Procedemos a correr el comando npm i, para instalar todos los paquetes de node.
Configuración de JavaScript SPA¶
En la carpeta src un archivo llamado msalInstance.js contiene la instancia de msal:
import { PublicClientApplication } from "@azure/msal-browser";
import {
addDefaultCallbacks,
addToStorageCallback,
addApmEventCallback,
} from "@architecture-it/azure-b2c/eventCallbacks";
import { msalConfig } from "@architecture-it/azure-b2c/config";
import rum from "./monitor";
/**
* Debe ser istanciado fuera del ciclo de vida de los componentes para evitar reisntanciar cuando rerenderice la app
* For more, visit: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-react/docs/getting-started.md
*/
const instance = new PublicClientApplication(msalConfig);
addDefaultCallbacks(instance);
instance.addEventCallback(addToStorageCallback());
instance.addEventCallback(addApmEventCallback(rum));
export const msalInstance = instance;
El valor de los parámetros de configuración se encuentran en el archivo .env
Nombre | Descripción |
---|---|
clientId | Identificador de la aplicación (cliente) de la aplicación que registró. |
authorityDomain | Instancia en la nube de Azure en la que se registra la aplicación. |
signUpSignIn, forgotPassword, editProfile | Flujos de inicio de sesion, recuperación de contraseña y editor de perfil. |
redirectUri | Dirección a la que volvera la el usuarios despues de cada acción |
¿Que es JWT?¶
JWT (JSON Web Token) es un estándar qué está dentro del documento RFC 7519.
En el mismo se define un mecanismo para poder propagar entre dos partes, y de forma segura, la identidad de un determinado usuario, además con una serie de claims o privilegios.
Estos privilegios están codificados en objetos de tipo JSON, que se incrustan dentro de del payload o cuerpo de un mensaje que va firmado digitalmente.
JWT no es un estándar de autenticación, sino que simplemente un estándar que nos permite hacer una comunicación entre dos partes de identidad de usuario. Con este proceso, además, podríamos implementar la autenticación de usuario de una manera que fuera segura.
Puede encontrar más sobre esto en la documentación de Microsoft - Link
Eventos de MSAL¶
Podemos añadir funcionalidades según ciertos eventos internos de la librería con addEventCallback
.
Una vez que un usuario inicia sesión, Se puede por ejemplo configurar la cuenta default y hacer algo con el token.
Todo esto ya viene integrado a la librería @architecture-it/azure-b2c
por lo que solo debemos agregar el siguiente archivo en src
import { PublicClientApplication } from "@azure/msal-browser";
import {
addDefaultCallbacks,
addToStorageCallback,
addApmEventCallback,
} from "@architecture-it/azure-b2c/eventCallbacks";
import { msalConfig } from "@architecture-it/azure-b2c/config";
//importar rum desde el archivo monitor del apm. (si se tiene configurado)
// import rum from "./monitor";
/**
* Debe ser istanciado fuera del ciclo de vida de los componentes para evitar reisntanciar cuando rerenderice la app
* For more, visit: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-react/docs/getting-started.md
*/
const instance = new PublicClientApplication(msalConfig);
addDefaultCallbacks(instance);
instance.addEventCallback(addToStorageCallback());
// Agrega el evento para setear el contexto del usuario en el apm
// instance.addEventCallback(addApmEventCallback(rum));
export const msalInstance = instance;
import { createRoot } from "react-dom/client";
import { StyleSystemProvider } from "@architecture-it/stylesystem";
import { CssBaseline } from "@mui/material";
import { BrowserRouter } from "react-router-dom";
import { Provider } from "react-redux";
import { store } from "store/store";
//descomentar si se tiene APM configurado
// import rum from "./monitor";
import App from "./App";
import { msalInstance } from "./msalInstance";
//necesario para el apm
rum.setInitialPageLoadName("Home");
const container = document.getElementById("root") as HTMLElement;
const root = createRoot(container);
root.render(
<BrowserRouter>
<Provider store={store}>
<StyleSystemProvider>
<CssBaseline />
<App msalInstance={msalInstance} />
</StyleSystemProvider>
</Provider>
</BrowserRouter>
);
Y por último agregar el clientId y el dominio a los environments, que correspondan
# B2C Configuration
REACT_APP_B2C_CLIENT_ID=<XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX>
REACT_APP_B2C_AUTH_DOMAIN=<DOMAIN>
Consumo de Token para peticiones al Back¶
En conjunto a la librería @architecture-it/core
y su serviceBase podemos consumir el token desde el sessionStorage o el localStorage
import type { IPerson } from "interfaces/Person";
import { ServiceBase } from "@architecture-it/core";
import env from "@architecture-it/react-env";
import { msalInstance } from "msalInstance";
import axios from "axios";
import { addResponseInterceptorRefreshToken } from "@architecture-it/azure-b2c";
export interface ICommonOptions {
signal?: AbortSignal;
}
const BASE_URL = env("API") + "person";
class _PersonService extends ServiceBase {
constructor() {
super(BASE_URL);
addResponseInterceptorRefreshToken(this.client, msalInstance, axios);
}
getAll = ({ signal }: ICommonOptions) => this.client.get<IPerson[]>("/", { signal });
}
const PersonService = new _PersonService();
export default PersonService;
Links usados y mas información:
- Descripción general de la biblioteca de autenticación de Microsoft (MSAL)
- Tutorial: Inicio de sesión de usuarios y llamada a Microsoft Graph API desde una aplicación de página única (SPA) de React mediante el flujo de código de autorización
- Adquiera y almacene tokens mediante la Biblioteca de autenticación de Microsoft (MSAL)
- JWT - openwebinars
- MSAL Hooks