Compartir a través de


Adición del inicio de sesión único a un bot

SE APLICA A: SDK v4

En este artículo se muestra cómo usar la característica de inicio de sesión único (SSO) en un bot. Para ello, esta característica usa un bot consumidor (también conocido como bot raíz o primario) para interactuar con una capacidad o un bot secundario. En este artículo se utilizan los términos bot raíz y bot de aptitud.

Si incluye compatibilidad con SSO, un usuario puede iniciar sesión en el bot raíz mediante un proveedor de identidades y no tendrá que iniciar sesión de nuevo cuando el control pase a una capacidad.

Los bots raíz y de aptitud son independientes que se podrían ejecutan en servidores diferentes, cada uno con su propia memoria y estado independientes. Para obtener más información sobre las capacidades, consulte Información general de las capacidades e Implementación de una capacidad. Para obtener más información sobre la autenticación de usuarios, consulte Conceptos básicos de autenticación de Bot Framework, Autenticación de usuario y Adición de autenticación a un bot.

Importante

Cuando se usa la autenticación de Servicio de Bot de Azure AI con Chat en web hay algunos aspectos de seguridad importantes que debe tener en cuenta. Para más información, consulte la sección Consideraciones de seguridad del artículo de autenticación REST.

Requisitos previos

Sobre el ejemplo

En este artículo se hace referencia a dos bots: RootBot y SkillBot. RootBot reenvía actividades a SkillBot. Modelan este típico escenario de conocimientos:

  • Un bot raíz llama a uno o varios bots de aptitud.
  • Tanto el bot raíz como los bots de aptitud implementan la autenticación básica que se describe en el artículo Adición de autenticación a un bot.
  • El usuario inicia sesión en el bot raíz.
  • Debido al inicio de sesión único (SSO) y que ya está conectado al bot raíz, ha iniciado sesión en el bot de aptitud sin necesidad de que el usuario vuelva a interactuar.

Para obtener información general sobre cómo controla Bot Framework la autenticación, consulte Autenticación del usuario. Para más información sobre SSO, consulte Inicio de sesión único.

El RootBot admite SSO. Se comunica con SkillBot en nombre del usuario, sin que este tenga que autenticarse de nuevo en _SkillBot.

Para cada proyecto del ejemplo, necesita lo siguiente:

  1. Una aplicación de Microsoft Entra ID para registrar un recurso de bot en Azure.
  2. Una aplicación de proveedor de identidades de Microsoft Entra ID para la autenticación.

    Nota:

    Actualmente, solo se admite el proveedor de identidades de Microsoft Entra ID.

Creación del recurso RootBot de Azure

  1. Cree un recurso de bot de Azure en Azure Portal para RootBot. Siga los pasos descritos en Creación del recurso de bot de Azure.
  2. Copie y guarde el identificador de aplicación y el secreto de cliente del registro de bot.

Creación de la identidad de Microsoft Entra ID para RootBot

Microsoft Entra ID es un servicio de identidad en la nube que permite crear aplicaciones que inician sesión de forma segura mediante protocolos estándar del sector como OAuth 2.0.

  1. Cree una aplicación de identidad para RootBot que use Microsoft Entra ID para autenticar al usuario. Siga los pasos descritos en Creación del proveedor de identidades de Microsoft Entra ID.

  2. Seleccione Manifiesto en el panel izquierdo.

  3. Establezca accessTokenAcceptedVersion en 2.

  4. Seleccione Guardar.

  5. En el panel izquierdo, seleccione Exponer una API.

  6. En el panel derecho, seleccione Agregar un ámbito.

  7. En el extremo derecho, en la sección Agregar un ámbito, seleccione Guardar y continuar.

  8. En la ventana que aparece, en ¿Quién puede dar el consentimiento? seleccione Administradores y usuarios.

  9. Escriba la información necesaria restante.

  10. Seleccione la opción Agregar un ámbito.

  11. Copie y guarde el valor de ámbito.

Creación de una configuración de conexión OAuth para RootBot

  1. Cree una conexión de Microsoft Entra ID en el registro de bot RootBot y especifique los valores tal y como se describe en Microsoft Entra ID, y los valores que se describen a continuación.

  2. Deje vacío el campo Dirección URL de intercambio de tokens.

  3. En el cuadro Ámbitos, escriba el valor de ámbito RootBot que guardó en los pasos anteriores.

    Nota:

    Los ámbitos contienen la dirección URL con la que el usuario inicia sesión inicialmente en el bot raíz, mientras que la dirección URL de intercambio de tokens se deja vacía.

    Por ejemplo, supongamos que el appid del bot raíz es rootAppId y que el appid del bot de capacidad es skillAppId. Los ámbitos del bot raíz tendrán un aspecto similar a api://rootAppId/customScope, que se usa para iniciar la sesión del usuario. A continuación, los ámbitos de este bot raíz se intercambian con api://skillAppId/customscope durante el inicio de sesión único.

  4. Copie y guarde el nombre de la conexión.

Creación del recurso SkillBot de Azure

  1. Cree un recurso de bot de Azure en Azure Portal para SkillBot. Siga los pasos descritos en Creación del recurso de bot de Azure.
  2. Copie y guarde el identificador de aplicación y el secreto de cliente del registro de bot.

Creación de la identidad de Microsoft Entra ID para SkillBot

Microsoft Entra ID es un servicio de identidad en la nube que permite crear aplicaciones que inician sesión de forma segura mediante protocolos estándar del sector como OAuth 2.0.

  1. Cree una aplicación de identidad para SkillBot que use Microsoft Entra ID para autenticar al bot. Siga los pasos descritos en Creación del proveedor de identidades de Microsoft Entra ID.

  2. Seleccione Manifiesto en el panel izquierdo.

  3. Establezca accessTokenAcceptedVersion en 2.

  4. Seleccione Guardar.

  5. En el panel izquierdo, seleccione Exponer una API.

  6. En el panel derecho, seleccione Agregar un ámbito.

  7. Al extremo derecho, en la sección Agregar un ámbito, seleccione Guardar y continuar.

  8. En la ventana que aparece, en ¿Quién puede dar el consentimiento?, seleccione Administradores y usuarios.

  9. Escriba la información necesaria restante.

  10. Seleccione la opción Agregar un ámbito.

  11. Copie y guarde el valor de ámbito.

  12. Seleccione Agregar una aplicación cliente. En la sección de la derecha, en el cuadro Id. de cliente, escriba el identificador de aplicación de la identidad de RootBot que guardó anteriormente. Asegúrese de usar la identidad de RootBot y no el identificador de la aplicación de registro.

    Nota:

    En el caso de las aplicaciones cliente, Servicio de Bot de Azure AI no admite el inicio de sesión único con el proveedor de identidades B2C de Microsoft Entra ID.

  13. En Ámbito autorizado, active la casilla por el valor del ámbito.

  14. Seleccione Agregar aplicación.

  15. Seleccione Permisos de API en el panel de navegación izquierdo. Es un procedimiento recomendado establecer explícitamente los permisos de API de la aplicación.

    1. En el panel de la derecha, seleccione Agregar un permiso.

    2. Seleccione API de Microsoft y, luego, Microsoft Graph.

    3. Elija Permisos delegados y asegúrese de que se seleccionan los permisos que necesita. Este ejemplo requiere los permisos que se enumeran a continuación.

      Nota:

      Los permisos marcados como SE NECESITA EL CONSENTIMIENTO DEL ADMINISTRADOR requerirán un usuario y un administrador de inquilinos para iniciar sesión.

      • openid
      • profile
      • User.Read
      • User.ReadBasic.All
    4. Seleccione Agregar permisos.

Creación de una configuración de conexión OAuth para SkillBot

  1. Cree una conexión de Microsoft Entra ID en el registro del bot SkillBot y especifique los valores tal y como se describe en Microsoft Entra ID, y los valores que se describen a continuación.

  2. En el cuadro Dirección URL de intercambio de tokens, escriba el valor de ámbito SkillBot que guardó en los pasos anteriores.

  3. En el cuadro Ámbitos, escriba los valores siguientes separados por espacio en blanco: profile User.Read User.ReadBasic.All openid.

  4. Copie y guarde el nombre de la conexión en un archivo.

Comprobación de la conexión

  1. Seleccione la entrada de la conexión para abrir la conexión que ha creado.
  2. Seleccione Probar conexión en la parte superior del panel Configuración de conexión del proveedor de servicios.
  3. La primera vez, se debería abrir una pestaña del explorador nueva con los permisos que solicita la aplicación y en la que se le pide que acepte.
  4. Seleccione Aceptar.
  5. Esto debería redirigirle a la página Test Connection to <your-connection-name> Succeeded (Resultado satisfactorio de la prueba de conexión a "").

Para más información, consulte Introducción a Microsoft Entra ID para desarrolladores (v1.0) y Introducción a la Plataforma de identidad de Microsoft (versión 2.0). Para obtener información sobre las diferencias entre los puntos de conexión v1 y v2, consulte Motivos para actualizar a la Plataforma de identidad de Microsoft (v2.0). Para obtener información más completa, consulte Plataforma de identidad de Microsoft (anteriormente Microsoft Entra ID para desarrolladores).

Preparación del código de ejemplo

Debe actualizar el archivo de appsettings.json en ambos ejemplos, como se describe a continuación.

  1. En el repositorio de GitHub, clone el ejemplo de SSO con aptitud y bot consumidor de aptitud simple en CSharp.

  2. Abra el proyecto SkillBot, archivo appsettings.json. Asigne los valores siguientes del archivo guardado:

    {
        "MicrosoftAppId": "<SkillBot registration app ID>",
        "MicrosoftAppPassword": "<SkillBot registration password>",
        "ConnectionName": "<SkillBot connection name>",
        "AllowedCallers": [ "<RootBot registration app ID>" ]
    }
    
    
  3. Abra el proyecto RootBot, archivo appsettings.json. Asigne los valores siguientes del archivo guardado:

    {
        "MicrosoftAppId": "<RootBot registration app ID>",
        "MicrosoftAppPassword": "<RootBot registration password>",
        "ConnectionName": "<RootBot connection name>",
        "SkillHostEndpoint": "http://localhost:3978/api/skills/",
        "BotFrameworkSkills": [
                {
                "Id": "SkillBot",
                "AppId": "<SkillBot registration app ID>",
                "SkillEndpoint": "http://localhost:39783/api/messages"
                }
            ]
    }
    

Prueba de los ejemplos

Use lo siguiente para las pruebas:

  • Comandos de RootBot

    • login permite al usuario iniciar sesión en el registro de Microsoft Entra ID mediante RootBot. Una vez iniciada la sesión, SSO se encarga también del inicio de sesión en SkillBot. El usuario no tiene que iniciar sesión de nuevo.
    • token muestra el token del usuario.
    • logout cierra la sesión del usuario en RootBot.
  • Comandos de SkillBot

    • skill login permite que RootBot inicie sesión en SkillBot en nombre del usuario. Si el usuario ya ha iniciado sesión, no se le muestra una tarjeta de inicio de sesión, a menos que se produzca un error de SSO.
    • skill token muestra el token del usuario de SkillBot.
    • skill logout cierra la sesión del usuario en SkillBot.

Nota:

La primera vez que los usuarios prueben el inicio de sesión único en una aptitud, es posible que se les muestre una tarjeta de OAuth para iniciar sesión. Esto se debe a que aún no ha dado su consentimiento a la aplicación de Microsoft Entra ID de la aptitud. Para evitar esto, pueden dar su consentimiento de administrador a todos los permisos de Graph solicitados por la aplicación de Microsoft Entra ID.

Si aún no lo ha hecho, instale Bot Framework Emulator. Consulte también Depuración con el emulador.

Deberá configurar el emulador para que el inicio de sesión de ejemplo del bot funcione. Siga estos pasos: como se muestran en Configuración del emulador para la autenticación.

Después de haber configurado el mecanismo de autenticación, puede realizar las pruebas del bot de ejemplo.

  1. En Visual Studio, abra la solución SSOWithSkills.sln y configúrela para iniciar la depuración con varios procesos.

  2. Inicie la depuración localmente en el equipo. Tenga en cuenta que, en el archivo appsettings.json del proyecto RootBot tiene la siguiente configuración:

    "SkillHostEndpoint": "http://localhost:3978/api/skills/"
    "SkillEndpoint": "http://localhost:39783/api/messages"
    

    Nota:

    Esta configuración implica que RootBot y SkillBot están en ejecución en el equipo local. El emulador se comunica con RootBot en el puerto 3978 y RootBot se comunica con SkillBot en el puerto 39783. En cuanto se inicia la depuración, se abren dos ventanas del explorador predeterminado. Una en el puerto 3978 y otra en el puerto 39783.

  3. Inicie el emulador.

  4. Tendrá que proporcionar el identificador de aplicación y la contraseña del registro de RootBot al conectarse al bot.

  5. Escriba hi para iniciar la conversación.

  6. Escriba login (inicio de sesión). RootBot mostrará un tarjeta de autenticación Sign In to AAD (Inicio de sesión en AAD).

    Ejemplo de una tarjeta de inicio de sesión.

  7. Seleccione Iniciar sesión. Se muestra el diálogo emergente Confirm Open URL (Confirmar apertura de URL).

    Captura de pantalla del mensaje de confirmación

  8. Seleccione Confirmar. Iniciará sesión y se mostrará el token de RootBot.

  9. Escriba token para volver a mostrar el token.

    Ejemplo de un mensaje que muestra el token raíz.

    Ahora está listo para comunicarse con SkillBot. Una vez que haya iniciado sesión con RootBot, no es necesario que vuelva a proporcionar las credenciales hasta que cierre la sesión. Esto demuestra que el SSO funciona.

  10. Escriba skill login (inicio de sesión de aptitudes) en el cuadro del emulador. No se le pedirá que vuelva a iniciar sesión. En su lugar, se muestra el token de SkillBot.

  11. Escriba skill token para volver a mostrar el token.

  12. Ahora puede escribir skill logout (cierre de sesión de aptitud) para cerrar la sesión de SkillBot. Después, escriba logout (cierre de sesión) para cerrar la sesión de SimpleRootBoot.

Información adicional

El siguiente diagrama temporal se aplica a los ejemplos que se usan en el artículo y muestra la interacción entre los distintos componentes implicados. ABS es Servicio de Bot de Azure AI.

Diagrama de secuencia que ilustra el flujo del token de aptitud.

  1. La primera vez, el usuario escribe el comando login para RootBot.
  2. RootBot envía una OAuthCard para pedir al usuario que inicie sesión.
  3. El usuario especifica las credenciales de autenticación que se envían a ABS (Servicio de Bot de Azure AI).
  4. ABS envía el token de autenticación, generado según las credenciales del usuario, a RootBot.
  5. RootBot muestra el token raíz que el usuario debe ver.
  6. El usuario especifica el comando skill login para SkillBot.
  7. SkillBot envía OAuthCard a RootBot.
  8. RootBot solicita token intercambiable de ABS.
  9. SSO envía el token de aptitud skillBot a RootBot.
  10. RootBot muestra el token de aptitud que el usuario debe ver. Tenga en cuenta que el token de aptitud se generó sin que el usuario tenga que iniciar sesión en SKillBot. Esto se debe al inicio de sesión único.

En el ejemplo siguiente se muestra cómo se produce el intercambio de tokens. El código procede del archivo TokenExchangeSkillHandler.cs.

private async Task<bool> InterceptOAuthCards(ClaimsIdentity claimsIdentity, Activity activity)
{
    var oauthCardAttachment = activity.Attachments?.FirstOrDefault(a => a?.ContentType == OAuthCard.ContentType);
    if (oauthCardAttachment != null)
    {
        var targetSkill = GetCallingSkill(claimsIdentity);
        if (targetSkill != null)
        {
            var oauthCard = ((JObject)oauthCardAttachment.Content).ToObject<OAuthCard>();

            if (!string.IsNullOrWhiteSpace(oauthCard?.TokenExchangeResource?.Uri))
            {
                using (var context = new TurnContext(_adapter, activity))
                {
                    context.TurnState.Add<IIdentity>("BotIdentity", claimsIdentity);

                    // AAD token exchange
                    try
                    {
                        var result = await _tokenExchangeProvider.ExchangeTokenAsync(
                            context,
                            _connectionName,
                            activity.Recipient.Id,
                            new TokenExchangeRequest() { Uri = oauthCard.TokenExchangeResource.Uri }).ConfigureAwait(false);

                        if (!string.IsNullOrEmpty(result?.Token))
                        {
                            // If token above is null, then SSO has failed and hence we return false.
                            // If not, send an invoke to the skill with the token. 
                            return await SendTokenExchangeInvokeToSkill(activity, oauthCard.TokenExchangeResource.Id, result.Token, oauthCard.ConnectionName, targetSkill, default).ConfigureAwait(false);
                        }
                    }
                    catch
                    {
                        // Show oauth card if token exchange fails.
                        return false;
                    }

                    return false;
                }
            }
        }
    }
    return false;
}