0
votes

I have a bot made using framework v4 with c#. It has been authenticated using azure ad. List of user has been added in azure ad. once a user has been login, do we have any way to know which used has login.Can we know the name or email id of the user in bot.

I have followed this link for the authentication of bot with ad.

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

The image shown in emulator:

enter image description here The code

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;
}
}
1

1 Answers

1
votes

You are following the correct documentation. If you take a look at the sample 24.bot-authentication-msgraph, the Bot Framework v4 bot authentication is using MS Graph sample. This sample utilizes the Graph API to retrieve the data about the user.Once you set up an AADv2 application and add the scopes, you can test the bot sample locally on the Emulator. Once you are logged in, if you type 'me', it will return back the user name.

Here is an example of how the sample works in the Emulator: enter image description here

Hope this helps.