public async Task MessageReceivedAsync(IDialogContext context, IAwaitable <IMessageActivity> argument)
        {
            string accessToken = null;

            if (!_ignoreCache && !_requireConsent)
            {
                var lastUniqueId = context.GetLastUniqueId();
                if (!string.IsNullOrEmpty(lastUniqueId))
                {
                    var authenticationContext = context.GetAuthenticationContext();
                    try
                    {
                        Log($"RATD: Making silent token call for {lastUniqueId} @ {_resource}");
                        var authResult = await authenticationContext.AcquireTokenSilentAsync(_resource,
                                                                                             context.GetClientCredential(),
                                                                                             new UserIdentifier(lastUniqueId, UserIdentifierType.UniqueId));

                        accessToken = authResult?.AccessToken;
                    }
                    catch (Exception ex)
                    {
                        Log($"RATD: Ignoring silent token call error: {ex.Message}");
                    }
                }
                if (!string.IsNullOrEmpty(accessToken))
                {
                    Log($"RATD: using {accessToken}");
                    context.Done(accessToken);
                    return;
                }
            }

            Log($"RATD: prompting for token");
            await context.Forward(CreateAppAuthTokenDialog(_ignoreCache, _requireConsent), RecieveAppAuthTokenAsync, context.Activity, new CancellationToken());
        }
Ejemplo n.º 2
0
        public async Task ReceiveTokenAsync(IDialogContext context, IAwaitable <object> awaitableArgument)
        {
            var argument = await awaitableArgument;
            var model    = argument as AuthenticationResultActivity;

            if (!string.IsNullOrEmpty(model.Error))
            {
                Log($"LD: {model.Error}: {model.ErrorDescription}");
                await context.PostAsync($"{model.Error}: {model.ErrorDescription}");

                context.Done(string.Empty);
                return;
            }

            // Get access token
            var authContext = context.GetAuthenticationContext();
            var authResult  = await authContext.AcquireTokenByAuthorizationCodeAsync(
                model.Code,
                new Uri(model.RequestUri.GetLeftPart(UriPartial.Path)),
                context.GetClientCredential());

            var uniqueId = authResult?.UserInfo.UniqueId;
            var result   = new SimpleAuthenticationResultModel()
            {
                AccessToken = authResult.IdToken,
                Upn         = authResult?.UserInfo?.DisplayableId,
                GivenName   = authResult?.UserInfo?.GivenName,
                FamilyName  = authResult?.UserInfo?.FamilyName,
                UniqueId    = uniqueId,
            };

            var lastUniqueId = context.GetLastUniqueId();

            if (uniqueId == model.State.State.User.Id || uniqueId == lastUniqueId)
            {
                model.Done(null);
            }
            else
            {
                var rnd = new Random();
                result.SecurityKey = string.Join("", Enumerable.Range(0, 6).Select(i => rnd.Next(10).ToString()));
                model.Done(result.SecurityKey);
            }

            if (argument is IMessageActivity)
            {
                await context.PostAsync("Cancelled");

                context.Done(string.Empty);
                return;
            }
            else if (null != result)
            {
                if (string.IsNullOrEmpty(result.SecurityKey))
                {
                    Log($"LD: got token, no key needed");
                    await context.PostAsync("Got your token, no security key is required");
                    await SaveSettings(context, result);

                    context.Done(result.AccessToken);
                }
                else
                {
                    Log($"LD: got token, waiting for key");
                    _authResult = result;
                    if (_promptForKey)
                    {
                        await context.PostAsync("Please enter your security key");
                    }
                    context.Wait(ReceiveSecurityKeyAsync);
                }
                return;
            }

            await context.PostAsync("Got unknown thing: " + argument?.GetType()?.Name);

            context.Wait <object>(ReceiveTokenAsync);
        }
        public async Task RecieveAppAuthTokenAsync(IDialogContext context, IAwaitable <string> awaitableArgument)
        {
            var appAccessToken = await awaitableArgument;

            var idaClientId     = Config.GetAppSetting("ClientId");
            var idaClientSecret = Config.GetAppSetting("ClientSecret");

            var clientCredential      = new ClientCredential(idaClientId, idaClientSecret);
            var userAssertion         = new UserAssertion(appAccessToken);
            var authenticationContext = new AuthenticationContext(Config.GetAppSetting("Authority"), new UserTokenCache(context.UserData));

            // try silent again - we may have pre-loaded it as we completed auth - no harm in trying
            var lastUniqueId = context.GetLastUniqueId();

            if (!string.IsNullOrEmpty(lastUniqueId))
            {
                try
                {
                    Log($"RATD: Making silent token call for {lastUniqueId} @ {_resource}");
                    var authResult = await authenticationContext.AcquireTokenSilentAsync(_resource,
                                                                                         context.GetClientCredential(),
                                                                                         new UserIdentifier(lastUniqueId, UserIdentifierType.UniqueId));

                    var accessToken = authResult?.AccessToken;
                    if (!string.IsNullOrEmpty(accessToken))
                    {
                        context.Done(accessToken);
                        return;
                    }
                }
                catch (Exception ex)
                {
                    Log($"RATD: Ignoring silent token call error: {ex.Message}");
                }
            }

            var sw = Stopwatch.StartNew();

            try
            {
                Log($"RATD: redeeming for token");
                var newToken = await authenticationContext.AcquireTokenAsync(_resource, clientCredential, userAssertion);

                TokenRequestComplete(sw.Elapsed, null);

                context.Done(newToken.AccessToken);
            }
            catch (Exception ex)
            {
                TokenRequestComplete(sw.Elapsed, ex);
                if (ex.Message.Contains("AADSTS65001"))
                {
                    // consent required
                    Log($"RATD: need consent");
                    await context.PostAsync("Looks like we haven't asked your consent for this, doing that now....");

                    await context.Forward(CreateAppAuthTokenDialog(true, true), RecieveAppAuthTokenAsync, context.Activity, new CancellationToken());

                    return;
                }
                if (ex.Message.Contains("AADSTS50013"))
                {
                    // invalid app access token
                    Log($"RATD: token expired");
                    await context.PostAsync("Looks like your application token is expired - need a new one....");

                    await context.Forward(CreateAppAuthTokenDialog(true, false), RecieveAppAuthTokenAsync, context.Activity, new CancellationToken());

                    return;
                }
                throw;
            }
        }