Reputation: 1150
I am following the SampleAADv2Bot example from the AuthBot tutorial. I want to authenticate my bot using an Azure Active Directory that is already configured. I set up my Web.Config with what is pictured below. I have the same code in my dialog class as listed here except my class' name is LoginDialog.cs. I see this exception in the emulator however:
The error happens when I make this call in my code (in LoginDialog.cs):
await context.Forward(new AzureAuthDialog(AuthSettings.Scopes), this.ResumeAfterAuth, message, CancellationToken.None);
Here is my LoginDialog Class. ResumeAfterAuth() is implemented.
LoginDialog.cs:
// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT
license. See full license at the bottom of this file.
namespace Bot.Dialogs
{
using System;
using System.Threading;
using System.Threading.Tasks;
using AuthBot;
using AuthBot.Dialogs;
using AuthBot.Models;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;
[Serializable]
public class LoginDialog : IDialog<string>
{
public async Task StartAsync(IDialogContext context)
{
context.Wait(MessageReceivedAsync);
}
public async Task TokenSample(IDialogContext context)
{
//endpoint v2
var accessToken = await context.GetAccessToken(AuthSettings.Scopes);
if (string.IsNullOrEmpty(accessToken))
{
return;
}
await context.PostAsync($"Your access token is: {accessToken}");
context.Wait(MessageReceivedAsync);
}
public virtual async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> item)
{
var message = await item;
if (message.Text == "logon")
{
//endpoint v2
if (string.IsNullOrEmpty(await context.GetAccessToken(AuthSettings.Scopes)))
{
await context.Forward(new AzureAuthDialog(AuthSettings.Scopes), this.ResumeAfterAuth, message, CancellationToken.None);
}
else
{
context.Wait(MessageReceivedAsync);
}
}
else if (message.Text == "echo")
{
await context.PostAsync("echo");
context.Wait(this.MessageReceivedAsync);
}
else if (message.Text == "token")
{
await TokenSample(context);
}
else if (message.Text == "logout")
{
await context.Logout();
context.Wait(this.MessageReceivedAsync);
}
else
{
context.Wait(MessageReceivedAsync);
}
}
private async Task ResumeAfterAuth(IDialogContext context, IAwaitable<string> result)
{
var message = await result;
await context.PostAsync(message);
context.Wait(MessageReceivedAsync);
}
}
}
Here is my MessagesController.cs:
namespace Bot
{
//[BotAuthentication]
public class MessagesController : ApiController
{
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
if (activity.Type == ActivityTypes.ConversationUpdate)
{
}
else if (activity.Type == ActivityTypes.Message)
{
if (activity.Text.Contains("logon") || activity.Text.Contains("login"))
{
await Conversation.SendAsync(activity, () => new Dialogs.LoginDialog());
}
else
{
// Sends user's Id and Name to RootDialog Class
StateClient stateClient = activity.GetStateClient();
BotData userData = await stateClient.BotState.GetUserDataAsync(activity.ChannelId, activity.From.Id);
userData.SetProperty<string>("UserId", activity.From.Id);
userData.SetProperty<string>("Name", activity.From.Name);
// send these values in the Context
await stateClient.BotState.SetUserDataAsync(activity.ChannelId, activity.From.Id, userData);
await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());
}
}
else if (activity.Type == ActivityTypes.Invoke)
{
//...
}
else
{
HandleSystemMessage(activity);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
private Activity HandleSystemMessage(Activity activity)
{
//...
}
}
EDIT #1: After setting breakpoints in my code it looks like the error is happening in the WebApiConfig.cs file here:
JsonConvert.DefaultSettings = () => new JsonSerializerSettings()
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Formatting = Newtonsoft.Json.Formatting.Indented,
NullValueHandling = NullValueHandling.Ignore,
};
EDIT #2: The error happens after reaching the line shown in this picture:
When this line is reached message is null. It immediately leaves this function and goes back to the line:
await context.Forward(new AzureAuthDialog(AuthSettings.Scopes), this.ResumeAfterAuth, message, CancellationToken.None);
and then goes back to the JSON lines in WebApiConfig shown in EDIT #1, runs the function JsonSerializerSettings()
twice and then the exception is thrown.
Here is the Output view of the Exception:
Upvotes: 1
Views: 408
Reputation: 1150
I discovered the issue. I needed to add these lines under the line GlobalConfiguration.Configure(WebApiConfig.Register);
in my Global.asax.cs file:
AuthSettings.Mode = ConfigurationManager.AppSettings["ActiveDirectory.Mode"];
AuthSettings.EndpointUrl = ConfigurationManager.AppSettings["ActiveDirectory.EndpointUrl"];
AuthSettings.Tenant = ConfigurationManager.AppSettings["ActiveDirectory.Tenant"];
AuthSettings.RedirectUrl = ConfigurationManager.AppSettings["ActiveDirectory.RedirectUrl"];
AuthSettings.ClientId = ConfigurationManager.AppSettings["ActiveDirectory.ClientId"];
AuthSettings.ClientSecret = ConfigurationManager.AppSettings["ActiveDirectory.ClientSecret"];
Upvotes: 1