Geeks With Blogs

News
Joe Mayo

One of the places you can use a Microsoft Bot Framework bot is on your own Web page. There is a Chat control you can use and this post discusses this and shows an example.

Note: If you had trouble with the chat control earlier, there was a bug, but that is now fixed and the Chat control documentation is updated.

This post shows an implementation with the MVC Web API. Essentially, there are two techniques: insecure and secure, but let’s look at the HTML page setup first.

Setting up the HTML Page

The Bot Framework template includes a default.htm page and this is where I load the Chat control. I’m building on the Pig Latin Bot and the following shows the default.htm implementation:

<!DOCTYPE html>
<html>
<head>
    <title>Pig Latin Bot</title>
    <meta charset="utf-8" />
</head>
<body style="font-family:'Segoe UI'">
    <img src="images/PigLatinBot.png" alt="Pig Latin Bot"/>
    <h1>Pig Latin Bot</h1>
    <p>Translates your text to Pig Latin.</p>

    <div id="webChatControl">

    </div>

    <script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
    <script type="text/javascript">
        $("#webChatControl").load("api/WebChat");
    </script>
</body>
</html>

The location of the Chat control is in the div with the webChatControl id. After loading the script from MaxCDN, the next script block loads the chat control via jQuery. Notice the call to the relative api/WebChat endpoint. I’ll explain that next.

Using a Secret Key

The endpoint, the page calls, addresses an MVC Web API. It handles GET requests and returns the <iframe/> HTML for injection into the page. Here’s the implementation:

    public class WebChatController : ApiController
    {
        public async Task<string> Get()
        {
            string webChatSecret = ConfigurationManager.AppSettings["WebChatSecret"];

            return $"<iframe width='400px' height='400px' src='https://webchat.botframework.com/embed/PigLatinBotJoeMayo?s={webChatSecret}'></iframe>";
        }
    }

The WebChatSecret is a key in Web.config appSettings that contains a value for the secret key of the Chat control. You can get this key from your Bot Framework My bots page, edit the Web Chat channel, and generate keys. In the <iframe/> HTML string, replace PigLatinBotJoeMayo with the App ID of your bot. Notice that the parameter is s and it holds your bot’s secret key.

Rather than all of the ceremony for calling the Web API, reading secret key configuration, and injecting the result into the page, I could have coded the HTML directly into the page and been done with it. However, I have a point to make. Earlier, I mentioned that there were two techniques: insecure and secure. This was the insecure technique because whether you paste the HTML into the page or return HTML via a Web API call, the secret key is still part of the page that the user can see, which is insecure.

That said, security is relative. In this case, it depends on whether you intend for anyone in the world to load the Chat control onto their own page and use your key. In that case, this practice isn’t insecure at all. However, if this isn’t your intention, the next section explains a more secure way to handle keys.

Using a Token

If you don’t want to share your secret key with the world, another option is to use a token. It works like this:

  1. Add your secret key as a header value in an HTTP GET request
  2. Send the request and receive a token as a response
  3. Use that token as a parameter in the <iframe/> src URL

Here’s an updated WebChatController that shows how to do this:

    public class WebChatController : ApiController
    {
        public async Task<string> Get()
        {
            string webChatSecret = ConfigurationManager.AppSettings["WebChatSecret"];

            var request = new HttpRequestMessage(HttpMethod.Get, "https://webchat.botframework.com/api/tokens");
            request.Headers.Add("Authorization", "BOTCONNECTOR " + webChatSecret);

            HttpResponseMessage response = await new HttpClient().SendAsync(request);
            string token = await response.Content.ReadAsStringAsync();
            token = token.Replace("\"", "");

            return $"<iframe width='400px' height='400px' src='https://webchat.botframework.com/embed/PigLatinBotJoeMayo?t={token}'></iframe>";
        }
    }

Instantiating an HttpRequestMessage sets up the GET request to the Bot Framework api/tokens endpoint. Set the Authorization with BOTCONNECTOR and your secret key. In this scenario, the only time you’ll use your secret key is to request a token.

The SendAsync method uses that request, makes the call and returns the token. In previous versions, the documentation called for doing a POST that returned JSON. Now, the response contains just a token as a string. In the current implementation, the Bot Framework is returning a quoted token. e.g. “\”<token>\”” That’s the reason for the Replace call, to strip those quotes out. I’m not sure if the token will have those quotes in the future because they feel unnecessary, but you can hit a breakpoint and look at the value  of token in case it changes in the future and you might not need the Replace.

Finally use the token in the <iframe/> src query string parameter. Notice that the parameter is not s, as it was in the previous example for using the secret key, but is now t because you are using a token.

You might say that now anyone can read the token, and that would be true. The reason this is more secure is because that token will expire and can’t be used across sessions.

Summary

The Bot Framework Chat control is a convenient way to add a Bot to your Web site. You have a couple ways to use it via a secret key alone or by exchanging the secret key for a token. The implementation described in this blog post was to use jQuery to call an MVC Web API, return the HTML for the Web Chat control, and inject that control into the page. That is more secure by not exposing your secret key to the world.

@JoeMayo

Posted on Saturday, April 9, 2016 6:22 PM botframework , bot | Back to top

Related Posts on Geeks With Blogs Matching Categories
Copyright © Joe Mayo | Powered by: GeeksWithBlogs.net | Join free