GithubHelp home page GithubHelp logo

microsoftdx / authbot Goto Github PK

View Code? Open in Web Editor NEW

This project forked from matvelloso/authbot

82.0 82.0 54.0 242 KB

General authentication/authorization Bot Framework sample

License: MIT License

C# 99.15% ASP 0.32% HTML 0.53%

authbot's People

Contributors

ejadib avatar jamachad avatar jamesmcroft avatar matvelloso avatar tiagonmas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

authbot's Issues

After connect COSMOS DB, AuthBot is not working C#

I'm trying to connect COSMOS DB. It works. But after that, Auth bot is not working. It keeps telling me "Please click to sign in". When I click, I can get the number which is used to paste it back to my chat to complete the authentication.
This is my code.

protected void Application_Start()
{

       GlobalConfiguration.Configure(WebApiConfig.Register);
       
       AuthBot.Models.AuthSettings.Mode = ConfigurationManager.AppSettings["ActiveDirectory.Mode"];
       AuthBot.Models.AuthSettings.EndpointUrl = ConfigurationManager.AppSettings["ActiveDirectory.EndpointUrl"];
       AuthBot.Models.AuthSettings.Tenant = ConfigurationManager.AppSettings["ActiveDirectory.Tenant"];
       AuthBot.Models.AuthSettings.RedirectUrl = ConfigurationManager.AppSettings["ActiveDirectory.RedirectUrl"];
       AuthBot.Models.AuthSettings.ClientId = ConfigurationManager.AppSettings["ActiveDirectory.ClientId"];
       AuthBot.Models.AuthSettings.ClientSecret = ConfigurationManager.AppSettings["ActiveDirectory.ClientSecret"];

        //CosmosDB
       var uri = new Uri(ConfigurationManager.AppSettings["DocumentDbUrl"]);
       var key = ConfigurationManager.AppSettings["DocumentDbKey"];
       var store = new DocumentDbBotDataStore(uri, key);
       
       Conversation.UpdateContainer(
                   builder =>
                   {
                       builder.Register(c => store)
                           .Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore)
                           .AsSelf()
                           .SingleInstance();
       
                       builder.Register(c => new CachingBotDataStore(store, CachingBotDataStoreConsistencyPolicy.ETagBasedConsistency))
                           .As<IBotDataStore<BotData>>()
                           .AsSelf()
                           .InstancePerLifetimeScope();
       
                   });

    }

Can the magic number be removed for single user chats

Hello,
Our bot only supports single user chats and therefore we would like to remove the pasting back of the magic number process. Found this comment in code:
//IMPORTANT: DO NOT REMOVE THE MAGIC NUMBER CHECK THAT WE DO HERE. THIS IS AN ABSOLUTE SECURITY REQUIREMENT //REMOVING THIS WILL REMOVE YOUR BOT AND YOUR USERS TO SECURITY VULNERABILITIES. //MAKE SURE YOU UNDERSTAND THE ATTACK VECTORS AND WHY THIS IS IN PLACE.

Is there a secure way to remove the magic number process for single user use?

Thank you,
Douw

Maintain multiple tokens?

Hello,
This project has been very helpful to me. I was able to use it to get the token to call MS Graph.
I have a new requirement that, in additional to calling MSGraph, I also need to call Visual Studio Online.

What would be the best way to achieve that? Since all the settings are static variables, so I guess it would require a lot of changes to this package to support that.

AD B2C

Any news on B2C support or an approximate timeframe?

Token / Secret doesn't get passed through in Edge or IE

Hi,

We have implemented AuthBot in our bot. The problem we experience now is that we get a HTTP502 error when talking to the bot in WebChat, but only in Edge and IE. In Chrome, the authentication occurs as expected and the results are returned successfully.
The full error is as follows:

HTTP502: BAD GATEWAY - The server, while acting as a gateway or proxy, received an invalid response from the upstream server it accessed in attempting to fulfill the request.
(XHR)POST - https://webchat.botframework.com/v3/directline/conversations/XXXXXXXXXXXXX/activities

When clicking the URL provided in the error message, the following is displayed:
{ "error": { "code": "BadArgument", "message": "Missing token or secret" } }

As mentioned, we only see this when using Edge or IE, but it works fine as expected when using Chrome.

Any help would be greatly appreciated.

Thanks,
Pieter

AuthCallback throws exception only in Telegram channel

Hi!

The v1 sample works fine on Emulator/WebChat and Facebook channels but fails to callback on Telegram after a successful sign in:

An error has occurred. **Unknown botId** Microsoft.Rest.HttpOperationException at Microsoft.Bot.Connector.ErrorHandling.d__2`1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Connector.ConversationsExtensions.d__7.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Dialogs.Internals.AlwaysSendDirect_BotToUser.d__4.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Dialogs.Internals.MapToChannelData_BotToUser.d__3.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Dialogs.Internals.LogBotToUser.d__4.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Dialogs.Internals.DialogContext.d__12.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Dialogs.Extensions.d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at SampleAADV1Bot.Dialogs.ActionDialog.d__3.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Dialogs.Internals.DialogTask.ThunkResume`1.d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Internals.Fibers.Wait`2.-PollAsync>d__19.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Internals.Fibers.Frame`1.-PollAsync>d__9.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Internals.Fibers.Fiber`1.-PollAsync>d__16.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Microsoft.Bot.Builder.Internals.Fibers.Wait`2.Microsoft.Bot.Builder.Internals.Fibers.IAwaiter.GetResult() at Microsoft.Bot.Builder.Dialogs.Chain.LoopDialog`1.d__3.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Dialogs.Internals.DialogTask.ThunkResume`1.d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Internals.Fibers.Wait`2.-PollAsync>d__19.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Internals.Fibers.Frame`1.-PollAsync>d__9.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Internals.Fibers.Fiber`1.-PollAsync>d__16.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Dialogs.Internals.DialogTask.d__23.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Dialogs.Internals.ReactiveDialogTask.d__3.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Dialogs.Internals.ScoringEventLoop`1.d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Dialogs.Internals.PersistentDialogTask.d__4.MoveNext() --- End of stack trace from previous location where exception was thrown --- at Microsoft.Bot.Builder.Dialogs.Internals.PersistentDialogTask.d__4.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Dialogs.Internals.ExceptionTranslationDialogTask.d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Dialogs.Internals.SerializeByConversation.d__4.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Dialogs.Internals.SetAmbientThreadCulture.d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Dialogs.Internals.PostUnhandledExceptionToUser.d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at Microsoft.Bot.Builder.Dialogs.Internals.PostUnhandledExceptionToUser.d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Dialogs.Internals.LogPostToBot.d__3.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Dialogs.Conversation.d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Dialogs.Conversation.d__3.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at AuthBot.Controllers.OAuthCallbackController.d__3.MoveNext()

Any ideas?

Thank you

Not compatible with Bot Builder 3.5.9

After updating to Microsoft.Bot.Builder 3.5.9 I get the below error:
{
"message": "An error has occurred.",
"exceptionMessage": "Field not found: 'Microsoft.Bot.Builder.Dialogs.Conversation.Container'.",
"exceptionType": "System.MissingFieldException",
"stackTrace": " at AuthBot.Controllers.OAuthCallbackController.d__3.MoveNext()\r\n at System.Runtime.CompilerServices.AsyncTaskMethodBuilder1.Start[TStateMachine](TStateMachine& stateMachine)\r\n at AuthBot.Controllers.OAuthCallbackController.OAuthCallback(String code, String state, CancellationToken cancellationToken)\r\n at lambda_method(Closure , Object , Object[] )\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass12.<GetExecutor>b__8(Object instance, Object[] methodParameters)\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary2 arguments, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()"
}

Magic number

So the code says this about the magic number:

//IMPORTANT: DO NOT REMOVE THE MAGIC NUMBER CHECK THAT WE DO HERE. THIS IS AN ABSOLUTE SECURITY REQUIREMENT
                    //REMOVING THIS WILL REMOVE YOUR BOT AND YOUR USERS TO SECURITY VULNERABILITIES. 
                    //MAKE SURE YOU UNDERSTAND THE ATTACK VECTORS AND WHY THIS IS IN PLACE.

So why is this so? Is there any other way to get rid of the security vulnerabilities? Of course it still needs to be secure.
What I'm trying to do is authenticate a user to MS graph and then have them perform queries.
If the user didnt need to paste something from the webpage, then they could get right back to the conversation with the S4B bot using a SIP link Return to bot (i think). Sadly you cannot add an initial message to the SIP link.

How to get Username

I'm using Authbot simply for Authentication. How do I get the username from AuthBot once they log in?
username

Port To Asp .Net Core 2.0?

When will this be available to ASP Net Core 2.0?
To get it working on ASP .NET Core 2.0 I've made a copy of Callbak controller with a few changes.
Changes I've made are HttpResponseMessage changed to IActionResult , modified routing to Microsoft.AspNetCore.Mvc.Route.
Then I used Dependecy Injection to get MicrosoftAppCredentials and created new ConnectorClient
ConnectorClient client = new ConnectorClient(new Uri(message.ServiceUrl), credentials);
insted of using this await Conversation.ResumeAsync(conversationRef, message);, and returned
new ContentResult(); Example:

[Microsoft.AspNetCore.Mvc.Route("[controller]")]
    public class CallbackController : Controller
    {
        private static RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
        private static readonly uint MaxWriteAttempts = 5;
        private readonly MicrosoftAppCredentials credentials;

        public CallbackController(MicrosoftAppCredentials credentials)
        {
            this.credentials = credentials;
        }

        [Microsoft.AspNetCore.Mvc.HttpGet]
        public async Task<IActionResult> Callback([FromQuery] string code, [FromQuery] string state, CancellationToken cancellationToken)
        {
            try
            {
                // Use the state parameter to get correct IAuthProvider and ResumptionCookie
                var decoded = Encoding.UTF8.GetString(HttpServerUtility.UrlTokenDecode(state));
                var queryString = HttpUtility.ParseQueryString(decoded);
                var assembly = Assembly.Load(queryString["providerassembly"]);
                var type = assembly.GetType(queryString["providertype"]);
                var providername = queryString["providername"];
                IAuthProvider authProvider;
                if (type.GetConstructor(new Type[] { typeof(string) }) != null)
                    authProvider = (IAuthProvider)Activator.CreateInstance(type, providername);
                else
                    authProvider = (IAuthProvider)Activator.CreateInstance(type);

                var conversationRef = UrlToken.Decode<ConversationReference>(queryString["conversationRef"]);

                Activity message = conversationRef.GetPostToBotMessage();
                using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
                {
                    // Get the UserData from the original conversation
                    IBotDataStore<BotData> stateStore = scope.Resolve<IBotDataStore<BotData>>();
                    var key = Address.FromActivity(message);
                    var userData = await stateStore.LoadAsync(key, BotStoreType.BotUserData, CancellationToken.None);                   
                    // Get Access Token using authorization code
                    var authOptions = userData.GetProperty<AuthenticationOptions>($"{authProvider.Name}{ContextConstants.AuthOptions}");
                    var token = await authProvider.GetTokenByAuthCodeAsync(authOptions, code);

                    // Generate magic number and attempt to write to userdata
                    int magicNumber = GenerateRandomNumber();
                    bool writeSuccessful = false;
                    uint writeAttempts = 0;
                    while (!writeSuccessful && writeAttempts++ < MaxWriteAttempts)
                    {
                        try
                        {
                            userData.SetProperty($"{authProvider.Name}{ContextConstants.AuthResultKey}", token);
                            if (authOptions.UseMagicNumber)
                            {
                                userData.SetProperty($"{authProvider.Name}{ContextConstants.MagicNumberKey}", magicNumber);
                                userData.SetProperty($"{authProvider.Name}{ContextConstants.MagicNumberValidated}", "false");
                            }
                            await stateStore.SaveAsync(key, BotStoreType.BotUserData, userData, CancellationToken.None);
                            await stateStore.FlushAsync(key, CancellationToken.None);
                            writeSuccessful = true;
                        }
                        catch (Exception)
                        {
                            writeSuccessful = false;
                        }
                    }
                    var resp = new ContentResult();
                    if (!writeSuccessful)
                    {
                        message.Text = String.Empty; // fail the login process if we can't write UserData
                     ConnectorClient client = new ConnectorClient(new Uri(message.ServiceUrl), credentials);
                        await client.Conversations.SendToConversationAsync(message);
                        resp.ContentType = @"text/html";
                        resp.Content = "<html><body>Could not log you in at this time, please try again later</body></html>";
                    }
                    else
                    {
                        message.Text = String.Empty;
                        ConnectorClient client = new ConnectorClient(new Uri(message.ServiceUrl), credentials);
                        await client.Conversations.SendToConversationAsync(message);
                        resp.ContentType = @"text/html";
                        resp.Content = $"<html><body>Almost done! Please copy this number and paste it back to your chat so your authentication can complete:<br/> <h1>{magicNumber}</h1>.</body></html>";

                    }
                    return resp;
                }
            }
            catch (Exception ex)
            {
                // Callback is called with no pending message as a result the login flow cannot be resumed.             
                return BadRequest();
            }
        }
        private int GenerateRandomNumber()
        {
            int number = 0;
            byte[] randomNumber = new byte[1];
            do
            {
                rngCsp.GetBytes(randomNumber);
                var digit = randomNumber[0] % 10;
                number = number * 10 + digit;
            } while (number.ToString().Length < 6);
            return number;
        }

    }

Callback url apps.dev.microsoft.com ?

I have create an app on https://apps.dev.microsoft.com/ for MS graph access and getting users authenticated to AADv2. I have a bot running on node.js where I'm configuring following
const AZUREAD_APP_ID = "xx"
const AZUREAD_APP_PASSWORD = "xx"
const AZUREAD_APP_REALM = "common"

using passport-azure-ad, to configure rest if the things. I would like to know what will be value of Redirect URL on apps.dev.microsoft.com.
Azure Bot app service endpoint ? or something else ?

Auth Bot not storing/retaining the token

Hi,

I've copied the code word for word and have followed the procedure mentioned in the video:
Office-Dev-Show-Episode-34-Getting-Started-with-Bots-and-the-Microsoft-Graph

And it works, the bot asks me for the magic number which i copy paste and give to the bot, after which it says "Thanks Kanishk Mehta. You are now logged in." which is great. But after that whatever I type, I get the message "Your credentials expired and could not be renewed automatically!" and then "In order to finish the sign out, please click at this link." and then it asks me to authenticate again...

Please help. Below is a snapshot of my conversation with the bot. if any further details are required on my part, please let me know. @matvelloso @msftgits

image

Token expiry

Does the bot ever checks if the token is expired so that we could ask user to log in again? Or is there a helper method which checks for token expiry?

Potential Security Gap

Hello,
I might be wrong here, but after doing more testing on magic number auth flow I found a potential security gap.
@matvelloso I'm adding you to this discussion as you wrote this logic and would be the best source of truth.

Auth Flow

Here is a summary of the current auth flow how I understand it:

  1. On a message to the bot, the bot checks if a token is available in the bot user data for the specific user id.
  2. If no token is available, a auth link is built and posted to the user.
    IMPORTANT: The auth link contains all the data relative to the conversation including the user id and therefore the magic number is required to ensure no one highjacks the conversation.

Assume a hacker intercepts the request and now have the user's conversation data.

  1. The user clicks the auth link opening a browser session where they enter their user detail and the AD token and conversation data is redirected to the bot (not the chat client.)
  2. When the bot receives the token and conversation data it performs two tasks:
    a. The token is saved against the user id in the bot data store marked as validated = false and a magic number is provided on the web request.
    b. The conversation data is used to find the existing conversation and send a message to the user's chat client asking for the magic number.

At this point the hacker can talk to the bot as the user, but is rejected because the token has not been validated yet and is therefore rejected. The hacker do not have the magic number and therefore cannot validate the token. All good thus far.

  1. The user copies the magic number and sends it to the bot on the same conversation.
  2. The bot receives the magic number from the user, checks that it's the same and marks the token saved against the user id as validated.
  3. The user can now talk to the bot and use the token saved in the bot user data against their user id.

Problem / Assumption

The token saved against a specific user id is now validated and can be used by anyone who talks to the bot with the same user id.

The hacker still has the user id and can now use the validated token to do malicious shit.

In summary

The magic number flow ensures the token first has to be validated by the user who made the auth request, but once the token has been validated a security gap is opened.

This gap could be closed by validating the magic number on each message, instead of just once. Not sure how this would be implemented as each channel will have to persist and send the magic number on each message.

Is my understanding of the flow correct? Is there a gap or am I missing something?

I found this issue by using the DirectLine channel.

Cheers,

Douw

Authorization only with tenant users

Hi,
I'm using the Authorization with the v2 endpoint. In the web.config file i put the GUID of my tenant to the ActiveDirectory.Tenant key. I thought this would then result to the fact that only users in this tenant can authorize to the bot. Isn't this true? I can authorize with any user, even with my private Microsoft account. Do I have to change other things to guarantee that only users from the azure tenant can authorize?
Thanks for your answer!

Link that redirects user to Azure AD login page fails

The AD page that user redirects to says <We received a bad request - The request body must contain the following parameter: 'client_id'>. This happens in the new Bot emulator released a couple of days back and also in the iFrame WebChat Channel. It continues to work on Skype and also in the old bot emulator.

How to direct the control flow to LuisDialog after authenticating?

Hello all, Here is my MessageRecievedAsync method as per my understanding I have written lamda Expression in 'else' Block is this correct?
or Do I need to write the lamda Expression part in ResumeAfter Method?

if (string.IsNullOrEmpty(await context.GetAccessToken(ConfigurationManager.AppSettings["ActiveDirectory.ResourceId"])))
{
await context.Forward(new AzureAuthDialog(ConfigurationManager.AppSettings["ActiveDirectory.ResourceId"]), this.ProcessAuthResultAsync, message, System.Threading.CancellationToken.None);
}
else if (message.Text == "logout")
{
await context.Logout();
context.Wait(this.ProcessMessageAsync);
}
else
{
await Conversation.SendAsync(message, () => new RHDLuisDialog());
// RHDLuisDialog is my LuisDialogClass
}

Facebook messenger issue when sign in

Hi,

When I tested my bots on facebook messenger, it displays the full login url in 3 different messages.

Skype does render it in sign-in button so it looks fine there.

Are there any ways to get this issue fixed?

Regards,

Jay

InvalidOperationException: Operation is not valid due to the current state of the object

Hello , Everyone I am stuck into this issue.

  1. First i send message to Bot, Bot replies with sign-in card.
    2.I sign-in successfully and paste magic number.
    3.I wish to logout, I am successfully logged out.
    4.Here start's the problem, I then go to my previous sign-in card and click on sign in card button (instead of sending hi/hello so that i could go to my AuthDialogHelper:IDialogContext(object) class.).
    5.I get a login page but after loggin in , It crashes with an Error.

{
"message": "An error has occurred.",
"exceptionMessage": "Operation is not valid due to the current state of the object.",
"exceptionType": "System.InvalidOperationException",
"stackTrace": " at Microsoft.Bot.Builder.Dialogs.Conversation.<>c__31.<ResumeAsync>b__3_0()\r\n at Microsoft.Bot.Builder.Dialogs.Internals.ReactiveDialogTask.<Microsoft-Bot-Builder-Dialogs-Internals-IPostToBot-PostAsync>d__31.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Bot.Builder.Dialogs.Internals.ScoringDialogTask1.<Microsoft-Bot-Builder-Dialogs-Internals-IPostToBot-PostAsync>d__31.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Bot.Builder.Dialogs.Internals.PersistentDialogTask.d__31.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at Microsoft.Bot.Builder.Dialogs.Internals.PersistentDialogTask.<Microsoft-Bot-Builder-Dialogs-Internals-IPostToBot-PostAsync>d__31.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Bot.Builder.Dialogs.Internals.SerializingDialogTask.d__41.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Bot.Builder.Dialogs.Internals.ExceptionTranslationDialogTask.<Microsoft-Bot-Builder-Dialogs-Internals-IPostToBot-PostAsync>d__21.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Bot.Builder.Dialogs.Internals.LocalizedDialogTask.d__21.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Bot.Builder.Dialogs.Internals.PostUnhandledExceptionToUserTask.<Microsoft-Bot-Builder-Dialogs-Internals-IPostToBot-PostAsync>d__51.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at Microsoft.Bot.Builder.Dialogs.Internals.PostUnhandledExceptionToUserTask.d__51.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Bot.Builder.Dialogs.Internals.LogPostToBot.<Microsoft-Bot-Builder-Dialogs-Internals-IPostToBot-PostAsync>d__31.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Bot.Builder.Dialogs.Conversation.d__51.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Bot.Builder.Dialogs.Conversation.<ResumeAsync>d__31.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)\r\n at AuthBot.Controllers.OAuthCallbackController.d__3.MoveNext()"
}

Message Controller Code :

public async Task Post([FromBody]Activity activity)
{
if (activity.Type == ActivityTypes.Message)
{
RHDLuisDialog.Activity = activity;
await Conversation.SendAsync(activity,() => new AuthDialogHelper()); // AuthDialogHelper is my Authentication Dialog Class.
}
else
{
HandleSystemMessage(activity);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}

AuthDialogHelper Class Code:

[Serializable]
public class AuthDialogHelper : IDialog
{
public async Task StartAsync(IDialogContext context)
{
context.Wait(ProcessMessageAsync);
}

    public async Task ProcessMessageAsync(IDialogContext context, IAwaitable<IMessageActivity> item)
    {
        var message = await item;

            if (string.IsNullOrEmpty(await context.GetAccessToken(ConfigurationManager.AppSettings["ActiveDirectory.ResourceId"])))
            {
                //Don't have an Access token then get it...
                await context.Forward(new AzureAuthDialog(ConfigurationManager.AppSettings["ActiveDirectory.ResourceId"]), this.ProcessAuthResultAsync, message, System.Threading.CancellationToken.None);
            }
            else
            {
                await context.Forward(new RHDLuisDialog(), ResumeAfterAsync, message, CancellationToken.None);
            } 
    }

    public async Task ProcessAuthResultAsync(IDialogContext context, IAwaitable<string> result)
    {
        //Get the result from AzureAuthDialog
      
        var message = await result;
        context.Wait(this.ProcessMessageAsync);
       
    }

    public async Task ResumeAfterAsync(IDialogContext context, IAwaitable<Object> result)
    {
        var message = await result;
        context.Wait(this.ProcessMessageAsync);
    }
}

The problem is when i send "hi" for secound time and get sign-in card it works perfectly because hi->messagesController->AuthDialogHelper and it works perfectly.
But when I directly go and tap on pervious sign-in card without sending any "Hi/Hello" it crashes into the above error after authentication but gets access token.

Kindly, provide your valuable suggestions.

Thanks.

Unexpected behavior after implementing TableBotDataStore

Install Azure Storage Emulator and check operation

Steps to reproduce using SampleAADv2Bot:

  1. Install NuGet Package Autofac.WebApi2
  2. Install NuGet package Microsoft.BotBuilder.Azure

in Global.asax.cs

  1. Add the following after the Application Start method
    private void ConfigureBotTableStorage()
    {
    string tableName = "UserStateDev";

         TableBotDataStore store = new TableBotDataStore(CloudStorageAccount.DevelopmentStorageAccount, tableName);
         
    
         var builder = new ContainerBuilder();
    
         builder.Register(c => store)
             .Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore)
             .AsSelf()
             .SingleInstance();
    
         builder
             .Register(c =>
             {
                 return new CachingBotDataStore(store, CachingBotDataStoreConsistencyPolicy.ETagBasedConsistency);
             })
             .As<IBotDataStore<BotData>>()
             .AsSelf()
             .InstancePerLifetimeScope();
    
         // Get your HttpConfiguration.
         var config = GlobalConfiguration.Configuration;
    
         // Register your Web API controllers.
         builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
    
         // OPTIONAL: Register the Autofac filter provider.
         builder.RegisterWebApiFilterProvider(config);
    
         // Set the dependency resolver to be Autofac.
         //var container = builder.Build();
         builder.Update(Conversation.Container);
         config.DependencyResolver = new AutofacWebApiDependencyResolver(Conversation.Container);
       @@}
    
  2. Before the line
    GlobalConfiguration.Configure(WebApiConfig.Register);
    insert the line
    ConfigureBotTableStorage();

  3. Save and compile

  4. Connect to the bot on http://localhost:3978/api/messages with the Bot Framework Channel Emulator

  5. Send logon to the bot inthe emulator

  6. Click the Authentication Required link in the emulator

  7. Log in using a Microsoft account in the browser window that opens

  8. Copy the magic number to send back to the bot

Expected behavior

Bot prompts for the magic number

Actual behavior

Bot displays sign-in card again.

Exception: Stack is empty?

I am following the v2 example. 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:

err

My Web.config looks like the following:

config

I know I'm doing something wrong but I'm not sure what?

Issue with authentification

Hello,

In my Bot project. i need to check that the user is connected in every task related to an intent.

i am using LUIS, and AuthBot V2

my problem is that the login message fire only in one task. when i say HELLO.

by in another intent "HELP", the login message doesn't fire.

here is my code & result :

 public class RootDialog : LuisDialog<object>
    {
        [LuisIntent("Help")]
        public async Task Help(IDialogContext context, IAwaitable<IMessageActivity> activity, LuisResult result)
        {
            var message = await activity;
            //CheckLogin
            if (string.IsNullOrEmpty(await context.GetAccessToken(AuthSettings.Scopes)))
            {
                await context.Forward(new AzureAuthDialog(AuthSettings.Scopes), this.ResumeAfterAuth, message, CancellationToken.None);
            }
            else
            {
                await context.PostAsync($"hi " + getUser(context).UserName);
                context.Wait(this.MessageReceived);
            }
        }

        [LuisIntent("Welcome")]
        public async Task Welcome(IDialogContext context, IAwaitable<IMessageActivity> activity, LuisResult result)
        {
            var message = await activity;
            //CheckLogin
            if (string.IsNullOrEmpty(await context.GetAccessToken(AuthSettings.Scopes)))
            {
                await context.Forward(new AzureAuthDialog(AuthSettings.Scopes), this.ResumeAfterAuth, message, CancellationToken.None);
            }
            else
            {
                await context.PostAsync($"Hi " + getUser(context).UserName);
                context.Wait(this.MessageReceived);
            }
        }
}

And here is the result :

image

Can you please help me getting this work.

thank you!

Extension methods not available in Scorable

I want to use AuthBot in a Scorable. The Scorable will act as middleware and make sure the user is authenticated before allowing Dialogs to take over.

Now this works quite fine. The problem is that I don't have access to IBotContext in Scorable. Autofac will throw error if you try to get it from constructor. This means that I can't use any of the extensions to get token.

If I re-implement the extensions on IBotData instead, everything works. In fact IBotContext derives from IBotData. But this approach just leads to code duplication. I had literally copy pasted the entire code and just modified it to extend on IBotData. The only drawback is that we can't use context.PostAsync to send reply back to user.

Any thoughts on moving the extension methods to IBotData?

Skype for business

I have created a test bot and authenitcaton works fine in the bot emulator but if i attempt to use it in skype for business i recieve the following message "Please click to sign in:" with no hyperlink or "Authentication Required" button like i do when using the bot emulator.

No reply address is registered for the application

Hi,

I have managed to configure my bot on azure and bot framework. When I use this on Skype it did promted me to login. Upon login am getting "AADSTS50011: No reply address is registered for the application" error.
capture

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.