Giter Site home page Giter Site logo

bot's Introduction

Azure Bot Framework with Multi-tenant Azure AD authentication

Azure BOT app with multi tenant Azure AD authentication.

Getting Started

These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See deployment for notes on how to deploy the project on a live system.

At first step, BOT would represent SignIn Card. Login with Azure AD user account, on sucessfully login you can access BOT functionality.

Code to show Signin card "BasicLuisDialog"

#region Login

    public async Task<string> UserInfo(string Token)
    {
        HttpClient client = new HttpClient();

        client.DefaultRequestHeaders.Add("Authorization", "Bearer " + Token);

        HttpResponseMessage response = await client.GetAsync(Constants.MicrosoftProfileUrl);

        string retResp = await response.Content.ReadAsStringAsync();
        AzureRespose data = JsonConvert.DeserializeObject<AzureRespose>(retResp);

        return data.EmailAddress;
    }

    private async Task LogIn(IDialogContext context)
    {
        string token;
        if (!context.PrivateConversationData.TryGetValue(AuthTokenKey, out token))
        {
            var conversationReference = context.Activity.ToConversationReference();

            context.PrivateConversationData.SetValue("persistedCookie", conversationReference);

            var reply = context.MakeMessage();
            reply.Type = "message";

            if (context.Activity.ChannelId == ChannelIds.Skype.ToString())
            {
                Microsoft.Bot.Connector.Attachment plAttachment = GetSkypeSigninCard(conversationReference);
                reply.Attachments.Add(plAttachment);
            }
            else
            {
                Microsoft.Bot.Connector.Attachment plAttachment = GetSigninCard(conversationReference);
                reply.Attachments.Add(plAttachment);
            }

            await context.PostAsync(reply);

            context.Wait(MessageReceivedAsync);
        }
        else
        {
            await context.PostAsync($"Your are already logged in.");
            context.Done(token);
        }
    }

    private static Microsoft.Bot.Connector.Attachment GetSkypeSigninCard(ConversationReference conversationReference)
    {
        var signinCard = new SigninCard
        {
            Text = "Please login to microsoft account",
            Buttons = new List<CardAction> { new CardAction(ActionTypes.Signin, "Authentication Required", value: SharepointHelpers.GetSharepointLoginURL(conversationReference, Constants.SharepointOauthCallback.ToString())) }
        };

        return signinCard.ToAttachment();
    }

    private static Microsoft.Bot.Connector.Attachment GetSigninCard(ConversationReference conversationReference)
    {
        List<CardAction> cardButtons = new List<CardAction>();
        CardAction plButton = new CardAction()
        {
            Value = SharepointHelpers.GetSharepointLoginURL(conversationReference, Constants.SharepointOauthCallback.ToString()),
            Type = "openUrl",
            Title = "Authentication Required"
        };
        cardButtons.Add(plButton);

        SigninCard plCard = new SigninCard("Please login to microsoft account", new List<CardAction>() { plButton });
        return plCard.ToAttachment();
    }
    #endregion
}
  1. On clicking Sign in, BOT would redirect user to sign in in azure, once authenticated user can use Time officer BOT.

authentication callback

public class OAuthCallbackController : ApiController
{
    [HttpGet]
    [Route("api/OAuthCallback")]
    public async Task<HttpResponseMessage> OAuthCallback([FromUri] string code, [FromUri] string session_state, string state, CancellationToken token)
    {

        var dict = HttpUtility.ParseQueryString(state);
        string json = JsonConvert.SerializeObject(dict.Cast<string>().ToDictionary(k => k, v => dict[v]));
        Address encodedAddress = JsonConvert.DeserializeObject<Address>(json);
        Address address = new Address(
            botId: SharepointHelpers.TokenDecoder(encodedAddress.BotId),
            channelId: SharepointHelpers.TokenDecoder(encodedAddress.ChannelId),
            conversationId: SharepointHelpers.TokenDecoder(encodedAddress.ConversationId),
            serviceUrl: SharepointHelpers.TokenDecoder(encodedAddress.ServiceUrl),
            userId: SharepointHelpers.TokenDecoder(encodedAddress.UserId)
            );

        var conversationReference = address.ToConversationReference();

        // Exchange the Sharepoint Auth code with Access token
        var accessToken = await SharepointHelpers.ExchangeCodeForAccessToken(conversationReference, code, Constants.SharepointOauthCallback.ToString());

        // Create the message that is send to conversation to resume the login flow
        var msg = conversationReference.GetPostToBotMessage();
        msg.Text = $"token:{accessToken}";

        // Resume the conversation to AuthDialog

        await Conversation.ResumeAsync(conversationReference, msg);

        using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, msg))
        {
            var dataBag = scope.Resolve<IBotData>();
            await dataBag.LoadAsync(token);
            ConversationReference pending;
            if (dataBag.PrivateConversationData.TryGetValue("persistedCookie", out pending))
            {
                // remove persisted cookie
                dataBag.PrivateConversationData.RemoveValue("persistedCookie");
                await dataBag.FlushAsync(token);
                return Request.CreateResponse("You are now logged in! Continue talking to the bot.");
            }
            else
            {
                // Callback is called with no pending message as a result the login flow cannot be resumed.
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, new InvalidOperationException("Cannot resume!"));
            }
        }
    }

}
  1. SharePointHelpers contains code for authorization callback that can be reused for office 365 authentication in other application also.

  2. Replace Constants values as per needed.

References to create Azure BOT Service, Developing, Testing, and publish on Azure.

  1. Create a bot with Bot Service - https://docs.microsoft.com/en-us/azure/bot-service/bot-service-quickstart?view=azure-bot-service-3.0
  2. Create a bot with the Bot Builder SDK for .NET - https://docs.microsoft.com/en-us/azure/bot-service/dotnet/bot-builder-dotnet-quickstart?view=azure-bot-service-3.0
  3. Call a LUIS endpoint using C# - https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-get-started-cs-get-intent

Installing

A step by step series of examples that tell you how to get a development env running

  1. Download / Clone code.
  2. Repleace web.config values as below.

You will get MicrosoftAppId and MicrosoftAppPassword on creating azure bot app. You will get LUIS api key and App id on creating LUIS app. Copy those values and replace to below code.

    <add key="MicrosoftAppId" value="" />
    <add key="MicrosoftAppPassword" value="" />
    <add key="LuisAPIKey" value=""/>
    <add key="LuisAppId" value="" />
  1. Create Azure Active Directory application https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-integrating-applications. Copy value of application id and application secret and replace values of SharepointAppId, and SharepointAppSecret respectively [ Constants.Cs class ]

Debug Code

Debug bots with the Bot Framework Emulator

Deployment

  1. Deploy your bot to Azure
  2. Publish a bot to Bot Service

Authors

License

This project is licensed under the MIT License - see the LICENSE.md file for details

  1. In case, you want to more about code, or any difficulties please contact at [email protected].

bot's People

Contributors

hiral-cloud-evangelist avatar

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.