1

I started implementing single sign on on my simple bot for practice. I already implemented it and can successfully authenticate the user using DirectLine with Enhanced Authentication. My problem was, every time I refresh the html where I render the webchat, the OAuth Card always appear.

enter image description here

How do I prevent this specially when the user already authenticated?

Here is how I render the webchat in a static html file

<!DOCTYPE html>
<html>
<head>
    <script src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"></script>
    <style>
        html,
        body {
            height: 100%;
        }

        body {
            margin: 0;
        }

        #webchat {
            height: 100%;
            width: 100%;
        }
    </style>
</head>
    <body>
        <div id="webchat" role="main"></div>
        <script>
            (async function () {
                // Set  the CSS rules.
                const styleSet = window.WebChat.createStyleSet({
                    bubbleBackground: '#F2F0F0',
                    bubbleBorderRadius: 10,
                    bubbleBorderStyle: 'solid',
                    bubbleBorderWidth: 1,

                    bubbleFromUserBackground: '#FDFDFD',
                    bubbleFromUserBorderRadius: 10,
                    bubbleFromUserBorderStyle: 'solid',
                    bubbleFromUserBorderWidth: 1,

                    rootHeight: '100%',
                    rootWidth: '100%',
                    backgroundColor: '#ffffff'
                });

                // After generated, you can modify the CSS rules.
                // Change font family and weight.
                styleSet.textContent = {
                    ...styleSet.textContent,
                    fontFamily: "'Arial', 'Helvetica', sans-serif",
                    fontWeight: 'regular'
                };

                const avatarOptions = {
                    botAvatarInitials: 'BO',
                    userAvatarInitials: 'UR'
                };

                const res = await fetch('https://token-service.azurewebsites.net/api/directline/token');
                const { token } = await res.json();

                window.WebChat.renderWebChat({
                    directLine: window.WebChat.createDirectLine({ token }),
                    styleSet,
                    styleOptions: avatarOptions
                }, document.getElementById('webchat'));
            })().catch(err => console.error(err));
        </script>
    </body>
</html>

This my sample code snippet on my MainDialog

public class MainDialog : ComponentDialog
{
    public MainDialog()
    {
        AddDialog(new OAuthPrompt(
            nameof(OAuthPrompt),
                new OAuthPromptSettings
                {
                    ConnectionName = configuration["ConnectionName"],
                    Text = "Please Sign In",
                    Title = "Sign In",
                    Timeout = 300000
                }));
        AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
        {
            InitialSignInStepAsync,
            SignInStepAsync,
            RepromptSignInStepAsync,
            WelcomeStepAsync
        }

        InitialDialogId = nameof(WaterfallDialog);
    }

        private async Task<DialogTurnResult> InitialSignInStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            _logger.LogInformation("MainDialog - InitialSignInStepAsync");

            return await stepContext.BeginDialogAsync(nameof(OAuthPrompt), null, cancellationToken);
        }

        private async Task<DialogTurnResult> SignInStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            _logger.LogInformation("MainDialog - SignInStepAsync");

            var tokenResponse = (TokenResponse)stepContext.Result;
            if (tokenResponse != null)
            {
                return await stepContext.NextAsync(null, cancellationToken);
            }

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

        private async Task<DialogTurnResult> RepromptSignInStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            _logger.LogInformation("MainDialog - RepromptSignInStepAsync");

            // Call the prompt again because we need the token. The reasons for this are:
            // 1. If the user is already logged in we do not need to store the token locally in the bot and worry
            // about refreshing it. We can always just call the prompt again to get the token.
            // 2. We never know how long it will take a user to respond. By the time the
            // user responds the token may have expired. The user would then be prompted to login again.
            //
            // There is no reason to store the token locally in the bot because we can always just call
            // the OAuth prompt to get the token or get a new token if needed.
            return await stepContext.BeginDialogAsync(nameof(OAuthPrompt), null, cancellationToken);
        }

        private async Task<DialogTurnResult> WelcomeStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            _logger.LogInformation("MainDialog - WelcomeStepAsync");

            if (stepContext.Result != null)
            {
                var tokenResponse = stepContext.Result as TokenResponse;

                // Use the token to get user info using MSGraph
            }
        }
}
klaydze
  • 941
  • 14
  • 36

0 Answers0