【问题标题】:How to know which user has been authenticated in Bot framework v4 using C#?如何使用 C# 在 Bot framework v4 中知道哪个用户已通过身份验证?
【发布时间】:2020-02-19 03:51:44
【问题描述】:

我有一个使用框架 v4 和 c# 制作的机器人。它已使用 azure ad 进行了身份验证。已在 azure 广告中添加用户列表。一旦用户登录,我们有什么办法知道哪个用户登录了。我们能知道机器人中用户的姓名或电子邮件ID吗?

我已按照此链接对带有广告的机器人进行身份验证。

https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-authentication?view=azure-bot-service-4.0&tabs=csharp

模拟器中显示的图片:

代码

public class MainDialog : ComponentDialog
{
private readonly IBotServices _botServices;
protected readonly ILogger _logger;
private readonly UserState _userState;

private readonly string _connectionName;

private readonly IConfiguration _configuration;
public MainDialog(IConfiguration configuration,ILogger<MainDialog> logger, IBotServices botServices)
    : base(nameof(MainDialog))
{
    _configuration = configuration;
    _logger = logger;
    _botServices = botServices ?? throw new System.ArgumentNullException(nameof(botServices));
    _connectionName = configuration["ConnectionName"];

    AddDialog(new OAuthPrompt(
      nameof(OAuthPrompt),
      new OAuthPromptSettings
      {
          ConnectionName = configuration["ConnectionName"],
          Text = "Please Sign In",
          Title = "Sign In",
          Timeout = 300000, // User has 5 minutes to login (1000 * 60 * 5)
      }));

    AddDialog(new ConfirmPrompt(nameof(ConfirmPrompt)));

    AddDialog(new ChoicePrompt(nameof(ChoicePrompt)));
    AddDialog(new luisandqnamakerDialog(_botServices,_configuration,_logger));
    AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
    {
        PromptStepAsync,
        LoginStepAsync             
    }));

    // The initial child Dialog to run.
    InitialDialogId = nameof(WaterfallDialog);
}

private async Task<DialogTurnResult> PromptStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
    return await stepContext.BeginDialogAsync(nameof(OAuthPrompt), null, cancellationToken);
}

private async Task<DialogTurnResult> LoginStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{

    // Get the token from the previous step. Note that we could also have gotten the
    // token directly from the prompt itself. There is an example of this in the next method.
    var tokenResponse = (TokenResponse)stepContext.Result;
    if (tokenResponse != null)
    {
        if (IsAuthCodeStep(stepContext.Context.Activity.Text))
        {
            await stepContext.Context.SendActivityAsync(MessageFactory.Text("You are now logged in."), cancellationToken);
            return await stepContext.NextAsync();
        }
        else
        {
             await stepContext.PromptAsync(nameof(luisandqnamakerDialog), new PromptOptions { Prompt = MessageFactory.Text("Would you like to ask your question?") }, cancellationToken);
            return await stepContext.EndDialogAsync(cancellationToken: cancellationToken);
        }
    }           

    await stepContext.Context.SendActivityAsync(MessageFactory.Text("Login was not successful please try again."), cancellationToken);

    return await stepContext.EndDialogAsync(cancellationToken: cancellationToken);
}

private bool IsAuthCodeStep(string code)
{
    if (string.IsNullOrEmpty(code) || !code.Length.Equals(6)) return false;
    if (!int.TryParse(code, out int result)) return false;
    if (result > 1) return true;                
    return false;
}

protected override async Task<DialogTurnResult> OnBeginDialogAsync(DialogContext innerDc, object options, CancellationToken cancellationToken = default(CancellationToken))
{
    var result = await InterruptAsync(innerDc, cancellationToken);
    if (result != null)
    {
        return result;
    }

    return await base.OnBeginDialogAsync(innerDc, options, cancellationToken);
}

protected override async Task<DialogTurnResult> OnContinueDialogAsync(DialogContext innerDc, CancellationToken cancellationToken = default(CancellationToken))
{
    var result = await InterruptAsync(innerDc, cancellationToken);
    if (result != null)
    {
        return result;
    }

    return await base.OnContinueDialogAsync(innerDc, cancellationToken);
}

private async Task<DialogTurnResult> InterruptAsync(DialogContext innerDc, CancellationToken cancellationToken = default(CancellationToken))
{
    if (innerDc.Context.Activity.Type == ActivityTypes.Message)
    {
        var text = innerDc.Context.Activity.Text.ToLowerInvariant();

        if (text == "logout")
        {
            // The bot adapter encapsulates the authentication processes.
            var botAdapter = (BotFrameworkAdapter)innerDc.Context.Adapter;
            await botAdapter.SignOutUserAsync(innerDc.Context, _connectionName, null, cancellationToken);
            await innerDc.Context.SendActivityAsync(MessageFactory.Text("You have been signed out."), cancellationToken);
            return await innerDc.CancelAllDialogsAsync(cancellationToken);
        }
    }

    return null;
}
}

【问题讨论】:

    标签: c# asp.net-core azure-active-directory botframework azure-language-understanding


    【解决方案1】:

    您正在遵循正确的文档。如果您查看示例 24.bot-authentication-msgraph,则 Bot Framework v4 机器人身份验证使用 MS Graph 示例。此示例使用 Graph API 来检索有关用户的数据。设置 AADv2 应用程序并添加范围后,您可以在模拟器上本地测试机器人示例。登录后,如果您输入 'me',它将返回用户名。

    下面是示例如何在模拟器中工作的示例:

    希望这会有所帮助。

    【讨论】:

    • 我正在使用 AuthenticationBot 示例,而不是您提到的。在这里我用广告验证它时得到令牌
    • 您需要使用 MS Graph 才能访问用户详细信息。样本 24 使用 MS Graph 而不是样本 18。
    猜你喜欢
    • 1970-01-01
    • 2011-05-27
    • 1970-01-01
    • 1970-01-01
    • 2017-12-06
    • 2018-03-04
    • 2018-12-17
    • 1970-01-01
    • 2015-11-08
    相关资源
    最近更新 更多