Adicionar logon único a um bot
APLICA-SE A: SDK v4
Este artigo mostra como usar o recurso SSO (logon único) em um bot. Para tal, esse recurso usa um bot de consumidor (também conhecido como bot raiz ou pai) para interagir com uma habilidade ou bot criança. Este artigo usa os termos bot raiz e bot de habilidade.
Se você incluir suporte a SSO, um usuário poderá iniciar uma sessão no bot raiz usando um provedor de identidade e não precisará fazê-lo novamente quando o controle passar para uma habilidade.
Os bots raiz e de habilidade são bots separados, sendo executados em servidores potencialmente diferentes, cada um com suas memórias e estados separados. Para obter mais informações, confira a Visão geral de habilidades e Implementação de habilidades. Para obter mais informações sobre autenticação de usuário, confira Noções básicas de autenticação do Bot Framework, Autenticação de usuário e Adicionar autenticação a um bot.
Importante
Quando você usa a autenticação do Serviço de Bot de IA do Azure com o Webchat, há algumas considerações importantes sobre segurança que precisam ser levadas em consideração. Para obter mais informações, confira a seção considerações sobre segurança no artigo de autenticação REST.
Pré-requisitos
- Conhecimento sobre Noções básicas de bot, Gerenciamento de estado e Sobre logon único.
- Conhecimento sobre A biblioteca de caixas de diálogo e como implementar um fluxo de conversa sequencial e reutilizar caixas de diálogo
- Conhecimento do desenvolvimento do Azure e do OAuth 2.0.
- Visual Studio 2019 ou posterior para .NET.
- SSO com consumidor de habilidade simples e habilidade no C#.
Sobre o exemplo
Este artigo faz referência a dois bots: o RootBot e o SkillBot. O RootBot encaminha as atividades para o SkillBot. Eles modelam o seguinte cenário típico de skill:
- Um bot raiz chama um ou mais bots de skill.
- Os bots raiz e de skill implementam a autenticação básica descrita no artigo Adicionar autenticação a um bot.
- O usuário faz logon no bot raiz.
- Como o SSO já está conectado ao bot raiz, eles também estão conectados ao bot de habilidade sem precisar de uma nova interação do usuário.
Para obter uma visão geral de como o Bot Framework lida com a autenticação, confira Autenticação de usuário. Para obter mais informações de contexto sobre o SSO, confira Logon único.
O RootBot dá suporte ao SSO. Ele se comunica com o SkillBot em nome do usuário, sem que o usuário precise se autenticar novamente no _SkillBot.
Para cada projeto no exemplo, você precisa do seguinte:
- Um aplicativo do Microsoft Entra ID para registrar um recurso de bot no Azure.
- Um aplicativo provedor de identidade do Microsoft Entra ID para autenticação.
Observação
No momento, há suporte apenas para o provedor de identidade do Microsoft Entra ID.
Criar o recurso RootBot do Azure
- Crie um recurso de bot do Azure no portal do Azure para o
RootBot
. Siga as etapas descritas em Criar um recurso de bot no Azure. - Copie e salve a ID do aplicativo e o segredo do cliente do registro do bot.
Criar a identidade do Microsoft Entra ID para o RootBot
O Microsoft Entra ID é um serviço de identidade de nuvem que permite criar aplicativos que conectam usuários com segurança usando protocolos padrão do setor, como o OAuth2.0.
Crie um aplicativo de identidade para o
RootBot
que usa o Microsoft Entra ID para autenticar o usuário. Siga as etapas descritas em Criar provedor de identidade do Microsoft Entra ID.No painel esquerdo, escolha Manifesto.
Defina
accessTokenAcceptedVersion
como 2.Selecione Salvar.
No painel esquerdo, escolha Expor uma API.
No painel direito, escolha Adicionar um escopo.
No lado mais à direita da seção Adicionar um escopo, escolha Salvar e continuar.
Na janela exibida, em Quem pode consentir?, escolha Administradores e usuários.
Insira as outras informações necessárias.
Selecione Adicionar escopo.
Copie e salve o valor do escopo.
Definir configuração de conexão do OAuth para RootBot
Crie uma conexão do Microsoft Entra ID no registro de bot
RootBot
e insira os valores conforme descritos em Microsoft Entra ID e o valor descrito abaixo.Deixe vazia a URL de troca de token.
Na caixa Escopos, insira o valor de escopo
RootBot
que você salvou nas etapas anteriores.Observação
A caixa Escopos contém a URL que o usuário inicialmente entra no bot raiz, enquanto a URL de troca de token é deixada vazia.
Como exemplo, vamos supor que o appid do bot raiz seja rootAppId e o appid do bot de habilidade seja skillAppId. Os escopos do bot raiz serão como api://rootAppId/customScope, que é usado para logon do usuário. Os escopos desse bot raiz serão então trocados com api://skillAppId/customscope durante o SSO.
Copie e salve o nome da conexão.
Criar o recurso SkillBot do Azure
- Crie um recurso de bot do Azure no portal do Azure para o
SkillBot
. Siga as etapas descritas em Criar um recurso de bot no Azure. - Copie e salve a ID do aplicativo e o segredo do cliente do registro do bot.
Criar identidade no Microsoft Entra ID para o SkillBot
O Microsoft Entra ID é um serviço de identidade de nuvem que permite criar aplicativos que conectam usuários com segurança usando protocolos padrão do setor, como o OAuth2.0.
Crie um aplicativo de identidade para o
SkillBot
que utiliza o Microsoft Entra ID para autenticar o bot. Siga as etapas descritas em Criar provedor de identidade do Microsoft Entra ID.No painel esquerdo, escolha Manifesto.
Defina
accessTokenAcceptedVersion
como 2.Selecione Salvar.
No painel esquerdo, escolha Expor uma API.
No painel direito, escolha Adicionar um escopo.
No lado mais à direita da seção Adicionar um escopo, escolha Salvar e continuar.
Na janela exibida, em Quem pode consentir?, selecione Administradores e usuários.
Insira as outras informações necessárias.
Selecione Adicionar escopo.
Copie e salve o valor do escopo.
Selecione Adicionar um aplicativo cliente. Na seção na extrema direita, na caixa ID do cliente, insira a ID do aplicativo da Identidade do RootBot que você salvou anteriormente. Certifique-se de usar a identidade do RootBot, e não a ID do aplicativo de registro.
Observação
Para aplicativos cliente, o Serviço de Bot de IA do Azure não oferece suporte a um único início de sessão com o provedor de identidade B2C do Microsoft Entra ID.
Em Escopo autorizado, marque a caixa pelo valor de escopo.
Escolha Adicionar aplicativo.
Selecione Permissões de API no painel de navegação esquerdo. A melhor prática é definir explicitamente as permissões de API para o aplicativo.
No painel direito, escolha Adicionar uma permissão.
Selecione as APIs da Microsoft e do Microsoft Graph.
Escolha Permissões delegadas e verifique se as permissões necessárias estão selecionadas. Este exemplo requer as permissões relacionadas abaixo.
Observação
As permissões marcadas como CONSENTIMENTO DO ADMINISTRADOR NECESSÁRIO exigirão que um usuário e um administrador de locatário façam logon.
- openid
- profile
- User.Read
- User.ReadBasic.All
Selecione Adicionar Permissões.
Criar uma configuração de conexão OAuth para o SkillBot
Crie uma conexão do Microsoft Entra ID no registro de bot
SkillBot
e insira os valores conforme descritos em Microsoft Entra ID e os valores descritos abaixo.Na caixa URL de Troca de Token, insira o valor de escopo
SkillBot
que você salvou nas etapas anteriores.Na caixa Escopos, insira os seguintes valores separados por espaço em branco:
openid
profile
User.Read
User.ReadBasic.All
.Copie e salve o nome da conexão em um arquivo.
Testar a conexão
- Escolha a entrada de conexão para abrir a conexão que você criou.
- Escolha Testar Conectividade na parte superior do painel Configuração da Conexão do Provedor de Serviços.
- Na primeira vez, deve abrir uma nova guia do navegador listando as permissões que seu aplicativo está solicitando e solicitará que você aceite.
- Selecione Aceitar.
- Essa ação deve redirecionar você para uma página de Teste de Conectividade para <nome-da-sua-conexão> bem-sucedida.
Para obter mais informações, confira Visão geral do Microsoft Entra ID para desenvolvedores (v1.0) e Visão geral da plataforma de identidade da Microsoft (v2.0). Para obter informações sobre as diferenças entre os pontos de extremidade v1 e v2, confira Por que atualizar para a plataforma de identidade da Microsoft (v2.0)?. Para obter informações completas, confira a Plataforma de identidade da Microsoft (anteriormente, Microsoft Entra ID para desenvolvedores).
Preparar os exemplos de códigos
Você deve atualizar o arquivo appsettings.json
nos dois exemplos, como descrito abaixo.
No repositório do GitHub, clone o exemplo SSO com Consumidor de Habilidade Simples e Habilidade.
Abra o arquivo
appsettings.json
do projetoSkillBot
. No arquivo salvo, atribua os seguintes valores:{ "MicrosoftAppId": "<SkillBot registration app ID>", "MicrosoftAppPassword": "<SkillBot registration password>", "ConnectionName": "<SkillBot connection name>", "AllowedCallers": [ "<RootBot registration app ID>" ] }
Abra o arquivo
appsettings.json
do projetoRootBot
. No arquivo salvo, atribua os seguintes valores:{ "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" } ] }
Testar os exemplos
Use o seguinte para testar:
Comandos de
RootBot
- O
login
permite que o usuário entre no registro do Microsoft Entra ID usando oRootBot
. Depois de conectado, o SSO também entra noSkillBot
. O usuário não precisa entrar novamente. token
exibe o token do usuário.logout
desconecta o usuário doRootBot
.
- O
Comandos de
SkillBot
skill login
permite que oRootBot
entre noSkillBot
em nome do usuário. O usuário não será exibido no cartão de entrada, se já tiver se conectado, a menos que o SSO falhe.skill token
exibe o token do usuário deSkillBot
.skill logout
desconecta o usuário doSkillBot
Observação
Na primeira vez que os usuários tentarem o SSO em um skill, eles poderão receber um cartão OAuth para fazer logon. Isso ocorre porque eles ainda não deram consentimento para o aplicativo do Microsoft Entra ID da habilidade. Para evitar isso, eles podem conceder consentimento do administrador para qualquer permissão de gráfico solicitada pelo aplicativo Microsoft Entra ID.
Caso ainda não tenha feito isso, instale o Bot Framework Emulator. Confira também Depurar com o Emulator.
Você precisará configurar o Emulator para que o logon de exemplo do bot funcione. Siga as etapas abaixo, conforme mostrado em Configurar o Emulator para autenticação.
Após configurar o mecanismo de autenticação, é possível executar o teste real do exemplo do bot.
No Visual Studio, abra a solução
SSOWithSkills.sln
e configure-a para iniciar a depuração com vários processos.Execute o bot em seu computador local. Observe que, no arquivo
appsettings.json
do projetoRootBot
, você tem as seguintes configurações:"SkillHostEndpoint": "http://localhost:3978/api/skills/" "SkillEndpoint": "http://localhost:39783/api/messages"
Observação
Essas configurações implicam que
RootBot
eSkillBot
estão em execução no computador local. O Emulator se comunica comRootBot
na porta 3978 eRootBot
se comunica comSkillBot
na porta 39783. Assim que você inicia a depuração, duas janelas de navegador padrão são abertas. Uma na porta 3978 e a outra na porta 39783.Inicie o Emulator.
É necessário fornecer a ID e a senha do aplicativo de registro do
RootBot
ao se conectar ao bot.Digite
hi
para iniciar a conversa.Digite login. O
RootBot
exibirá o cartão de autenticação para Entrar no AAD.Selecione Entrar. A caixa de diálogo pop-up Confirmar Abertura de URL é exibida.
Selecione Confirmar. Você será conectado, e o token
RootBot
será exibido.Digite token para exibir o token novamente.
Agora você está pronto para se comunicar com o
SkillBot
. Ao entrar usando oRootBot
, você não precisará fornecer suas credenciais novamente até sair. Isso demonstra que o SSO está funcionando.Digite skill login na caixa do Emulator. O logon não será solicitado novamente. Em vez disso, o token do SkillBot é exibido.
Digite skill token para exibir o token novamente.
Agora você pode digitar skill logout para se desconectar do
SkillBot
. Em seguida, digite logout para sair doSimpleRootBoot
.
Informações adicionais
O diagrama de sequência de tempo a seguir aplica-se aos exemplos usados no artigo e mostra a interação entre os vários componentes envolvidos. ABS significa Serviço de Bot de IA do Azure.
- Na primeira vez, o usuário digita o comando
login
para o RootBot. - O RootBot envia um OAuthCard solicitando que o usuário entre.
- O usuário digita as credenciais de autenticação, que são enviadas para o ABS (Serviço de Bot de IA do Azure).
- O ABS envia o token de autenticação, gerado com base nas credenciais do usuário, para o RootBot.
- O RootBot exibe o token da raiz para o usuário.
- O usuário digita o comando
skill login
para o SkillBot. - O SkillBot envia um OAuthCard para o RootBot.
- O RootBot solicita um token intercambiável do ABS.
- O SSO envia o token de habilidade do SkillBot para o RootBot.
- O RootBot exibe o token do skill para o usuário. Observe que o token do skill foi gerado sem que o usuário precisasse entrar no SKillBot. Isso acontece por causa do SSO.
O exemplo a seguir mostra como a troca de token acontece. O código é do arquivo 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;
}