Cree una Microsoft Teams SSO con microsoft Graph Toolkit

En este tema se describe cómo usar microsoft Graph Toolkit en una Microsoft Teams solución. Esta guía es para una aplicación de una sola página con inicio de sesión único (SSO) y requiere un back-end. Si va a implementar una pestaña de Teams con inicio de sesión interactivo, vea Build a Microsoft Teams Tab.

La creación de una pestaña sso implica los siguientes pasos:

  1. Agregue microsoft Graph Toolkit.
  2. Cree la página emergente de autenticación.
  3. Creación de un identificador de aplicación o cliente
  4. Crear el back-end
  5. Inicializar el Teams MSAL2.
  6. Agregar componentes.
  7. Prueba la aplicación.

Agregar el Graph Toolkit

Puede usar microsoft Graph Toolkit en la aplicación haciendo referencia al cargador directamente (a través de unpkg) o instalando los paquetes npm. Para usar el Toolkit, también necesitará el SDK Microsoft Teams.

Para usar el Toolkit y el SDK de Teams a través de los cargadores, agregue la referencia en un script al código:

<!-- Microsoft Teams sdk must be referenced before the toolkit -->
<script src="https://unpkg.com/@microsoft/teams-js/dist/MicrosoftTeams.min.js" crossorigin="anonymous"></script>
<script src="https://unpkg.com/@microsoft/mgt/dist/bundle/mgt-loader.js"></script>

Crear la página emergente de autenticación

A menos que un administrador consinta previamente la aplicación, es posible que los usuarios deban dar su consentimiento a los permisos. Para habilitar esto, deberás proporcionar una página que la aplicación Teams se abrirá en un elemento emergente para seguir el flujo de autenticación. Puedes hacer que la ruta de acceso a la página sea cualquier cosa siempre que esté en el mismo dominio que la aplicación (por ejemplo, https://yourdomain.com/tabauth) . El único requisito de esta página es llamar al método, pero puede agregar el contenido o el progreso de carga TeamsMsal2Provider.handleAuth() que desee.

A continuación se muestra un ejemplo de una página básica que controla el flujo de autenticación en el elemento emergente.

<!DOCTYPE html>
<html>
  <head>
    <script src="https://unpkg.com/@microsoft/teams-js/dist/MicrosoftTeams.min.js" crossorigin="anonymous"></script>
    <script src="https://unpkg.com/@microsoft/mgt/dist/bundle/mgt-loader.js"></script>
  </head>

  <body>
    <script>
      mgt.TeamsMsal2Provider.handleAuth();
    </script>
  </body>
</html>

Creación de un identificador de aplicación o cliente

La pestaña debe ejecutarse como una aplicación de Azure AD registrada para obtener un token de acceso de Azure AD. Registra la aplicación en el espacio empresarial y Microsoft Teams permiso para obtener tokens de acceso en su nombre:

  1. Abra un explorador y vaya al Centro Azure Active Directory administración. Inicie sesión con una cuenta personal (cuenta microsoft) o una cuenta laboral o educativa.

  2. En el panel izquierdo, seleccione Azure Active Directory y, a continuación, seleccione Registros de aplicaciones en Administrar.

  3. Seleccione Nuevo registro. En la página Registrar una aplicación, establezca los valores siguientes:

    • Establezca Name en Node.js Teams SSO (o un nombre de su elección).
    • Establezca Tipos de cuenta admitidos en Cuentas en cualquier directorio de organización y cuentas personales de Microsoft.
    • En URI de redireccionamiento, establezca el primer desplegable en y establezca el valor en la dirección URL de la página de autenticación que creó en el paso Single Page Application anterior; por ejemplo, https://myapp.ngrok.io/tabauth .
  4. En la página introducción a la aplicación, copie el valor del identificador de aplicación (cliente) para más adelante. Necesitará este valor al crear un nuevo proveedor y en el back-end.

  5. En Administrar, vaya a Certificados & secretos. Seleccione el botón Nuevo secreto de cliente. Escriba un valor en Descripción, y seleccione una de las opciones para Expira, y después, Agregar.

  6. Copie el valor del secreto del cliente antes de salir de esta página. Necesitará esto para el servicio back-end.

    Importante

    El secreto de cliente no se vuelve a mostrar, así que asegúrese de copiarlo en este momento.

  7. En Administrar, vaya a Permisos de API. Seleccione Agregar un permiso Microsoft > Graph > permisos delegados y, a email offline_access openid profile User.Read continuación, agregue los siguientes permisos: , , , , . Seleccione Agregar permisos.

  8. (OPCIONAL) Si desea dar su consentimiento previo a otros ámbitos, puede agregar más permisos. Si usa diferentes componentes o planea usar otras API de Microsoft Graph, es posible que necesite permisos adicionales. Para obtener información detallada sobre los permisos necesarios, consulte la documentación de cada componente.

    • Para dar su consentimiento previo como administrador, seleccione Conceder consentimiento de administrador y, a continuación, seleccione .
  9. En Administrar, vaya a Exponer una API. En la parte superior de la página, junto a Application ID URI , seleccione Establecer. Esto genera una API en forma de: api://{AppID} . Actualízclalo para agregar el subdominio; por ejemplo, api://myapp.ngrok.io/{appID} .

  10. En la misma página, seleccione Agregar un ámbito. Rellene los campos de la siguiente manera y seleccione Agregar ámbito:

    • Nombre del ámbito: access_as_user
    • Quién¿puede dar su consentimiento?: Administradores y usuarios
    • Nombre para mostrar del consentimiento de administrador: Teams can access the user’s profile
    • Descripción del consentimiento de administrador: Allows Teams to call the app’s web APIs as the current user
    • Nombre para mostrar del consentimiento del usuario: Teams can access the user profile and make requests on the user's behalf
    • Descripción del consentimiento del usuario: Enable Teams to call this app’s APIs with the same rights as the user.
    • Estado: habilitado

    La dirección URL de la API debe tener este aspecto: api://myapp.ngrok.io/{appID}/access_as_user .

  11. A continuación, agregue dos aplicaciones cliente. Esto es para el Teams de escritorio/móvil y el cliente web. En la sección Aplicaciones cliente autorizadas, seleccione Agregar una aplicación cliente. Rellene el identificador de cliente y seleccione el ámbito que creó. A continuación, seleccione Agregar aplicación. Haga esto para los siguientes IDs:

    • 5e3ce6c0-2b1f-4285-8d4b-75ee78787346
    • 1fec8e78-bce4-4aaf-ab1b-5451cc387264

Crear el back-end

El back-end puede ser cualquier back-endque permita intercambiar el token de autenticación de Microsoft Teams con un token que se puede usar para llamar a Microsoft Graph a través del flujo en nombre de .

Para obtener referencia, consulte Teams ejemplo de nodo de SSO.

A continuación se muestra una implementación de referencia de un servidor de nodo express:

import dotenv from 'dotenv';
import express from 'express';
import path from 'path';
import * as msal from '@azure/msal-node';
import { NextFunction, Request, Response } from 'express';
import jwt, { JwtHeader, SigningKeyCallback } from 'jsonwebtoken';
import jwksClient from 'jwks-rsa';
import jwt_decode from 'jwt-decode';

// Load .env file
dotenv.config();

/**
 * Validates a JWT
 * @param {Request} req - The incoming request
 * @param {Response} res - The outgoing response
 * @returns {Promise<string | null>} - Returns the token if valid, returns null if invalid
 */
function validateJwt(req: Request, res: Response, next: NextFunction): void {
  const authHeader = req.headers.authorization!;
  const ssoToken = authHeader.split(' ')[1];
  if (ssoToken) {
    const validationOptions = {
      audience: process.env.CLIENT_ID,
    };
    jwt.verify(ssoToken, getSigningKey, validationOptions, (err, payload) => {
      if (err) {
        return res.sendStatus(403);
      }
      next();
    });
  } else {
    res.sendStatus(401);
  }
}

/**
 * Parses the JWT header and retrieves the appropriate public key
 * @param {JwtHeader} header - The JWT header
 * @param {SigningKeyCallback} callback - Callback function
 */
function getSigningKey(header: JwtHeader, callback: SigningKeyCallback): void {
  const client = jwksClient({
    jwksUri: 'https://login.microsoftonline.com/common/discovery/keys'
  });
  client.getSigningKey(header.kid!, (err, key) => {
    if (err) {
      callback(err, undefined);
    } else {
      callback(null, key.getPublicKey());
    }
  });
}

/**
 * Gets an access token for the user using the on-behalf-of flow
 * @param authHeader - The Authorization header value containing a JWT bearer token
 * @returns {Promise<string | null>} - Returns the access token if successful, null if not
 */
async function getAccessTokenOnBehalfOf(req: Request, res: Response): Promise<void> {
  // The token has already been validated, just grab it
  const authHeader = req.headers.authorization!;
  const ssoToken = authHeader.split(' ')[1];

  // Create an MSAL client
  const msalClient = new msal.ConfidentialClientApplication({
    auth: {
      clientId: req.body.clientid,
      clientSecret: process.env.APP_SECRET
    }
  });

  try {
    const result = await msalClient.acquireTokenOnBehalfOf({
      authority: `https://login.microsoftonline.com/${jwt_decode<any>(ssoToken).tid}`,
      oboAssertion: ssoToken,
      scopes: req.body.scopes,
      skipCache: true
    });
    res.json({ access_token: result?.accessToken });
  } catch (error) {
    if (error.errorCode === 'invalid_grant' || error.errorCode === 'interaction_required') {
      // This is expected if it's the user's first time running the app ( user must consent ) or the admin requires MFA
      res.status(403).json({ error: 'consent_required' }); // This error triggers the consent flow in the client.
    } else {
      // Unknown error
      res.status(500).json({ error: error.message });
    }
  }
}

////////////////////////
// create and run server
////////////////////////

const app = express();
const PORT = process.env.port || process.env.PORT || 8000;

// Support JSON payloads
app.use(express.json());
app.use(express.static(path.join(__dirname, 'client')));

// An example for using POST and with token validation using middleware
app.post('/api/token', validateJwt, async (req, res) => {
  await getAccessTokenOnBehalfOf(req, res);
});

app.listen(PORT, () => {
  console.log(`⚡️[server]: Server is running at http://localhost:${PORT}`);
});

Inicializar el Teams MSAL2

Los proveedores de Graph Toolkit microsoft habilitan la autenticación y el acceso a Microsoft Graph. Para más información, vea Usar los proveedores. El Teams MSAL2 controla toda la lógica y las interacciones que deben implementarse con el SDK de Teams para autenticar al usuario.

Para el modo SSO, asegúrese de proporcionar y sso-url / ssoUrl hacer que apunte a la API de back-end.

Agregue el mgt-teams-msal2-provider código HTML.

<mgt-teams-msal2-provider 
  client-id="<YOUR_CLIENT_ID>"
  auth-popup-url="/tabauth"
  scopes="User.Read,Mail.ReadBasic"
  sso-url="http://localhost:8000/api/token"
  http-method="POST"
  ></mgt-teams-msal2-provider>

Reemplace por el identificador de cliente de la aplicación, reemplace la ruta de acceso completa o relativa a la página de autenticación y reemplace por la ruta de acceso completa o relativa al <YOUR_CLIENT_ID> auth-popup-url servicio sso-url back-end.

Agregar componentes

Ahora, ya está listo para agregar cualquiera de los componentes Graph Toolkit Microsoft.

Puede agregar componentes al HTML como lo haría normalmente. Por ejemplo, para agregar el Person componente, agregue el siguiente código al HTML.

<mgt-person person-query="me"></mgt-person>

Si está usando React, se recomienda usar los componentes React en su lugar desde la mgt-react biblioteca. Para obtener más información, vea Using Microsoft Graph Toolkit with React.

Probar el ejemplo

Para obtener la implementación completa, vea Teams ejemplo de nodo de SSO.

Si todo se ha configurado correctamente, verá el componente representado Person sin necesidad de iniciar sesión.

Importante

Si no ha dado su consentimiento previo, es posible que tenga que dar su consentimiento a través de un mensaje.

Siguientes pasos