예제 #1
0
        internal static TokenCache From(OriginalTokenCache cache)
        {
            var result = new TokenCache();

            result.Initialize(cache);
            return(result);
        }
        public static async Task <AuthResult> GetToken(string userUniqueId, Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache tokenCache, string resourceId)
        {
            Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext context = new Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext(AuthSettings.EndpointUrl + "/" + AuthSettings.Tenant, tokenCache);
            var result = await context.AcquireTokenSilentAsync(resourceId, new Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential(AuthSettings.ClientId, AuthSettings.ClientSecret), new Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifier(userUniqueId, Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifierType.UniqueId));

            AuthResult authResult = AuthResult.FromADALAuthenticationResult(result, tokenCache);

            return(authResult);
        }
예제 #3
0
        //static Microsoft.Identity.Client.TokenCache _msalTokenCache;

        public static Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache GetADALTokenCache()
        {
            if (_adalTokenCache == null)
            {
                _adalTokenCache = new Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache();
            }

            return(_adalTokenCache);
        }
예제 #4
0
        private static Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache GetTokenCache(string path)
        {
            var tokenCache = new Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache();

            tokenCache.BeforeAccess += notificationArgs =>
            {
                if (File.Exists(path))
                {
                    var bytes = File.ReadAllBytes(path);
                    notificationArgs.TokenCache.Deserialize(bytes);
                }
            };

            tokenCache.AfterAccess += notificationArgs =>
            {
                var bytes = notificationArgs.TokenCache.Serialize();
                File.WriteAllBytes(path, bytes);
            };
            return(tokenCache);
        }
예제 #5
0
        public static AuthResult FromADALAuthenticationResult(Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationResult authResult, Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache tokenCache)
        {
            var result = new AuthResult
            {
                AccessToken       = authResult.AccessToken,
                UserName          = $"{authResult.UserInfo.GivenName} {authResult.UserInfo.FamilyName}",
                UserUniqueId      = authResult.UserInfo.UniqueId,
                ExpiresOnUtcTicks = authResult.ExpiresOn.UtcTicks,
                TokenCache        = tokenCache.Serialize(),
                Email             = authResult.UserInfo.DisplayableId
            };

            return(result);
        }
예제 #6
0
        public async Task <HttpResponseMessage> OAuthCallback(
            [FromUri] string code,
            [FromUri] string state,
            CancellationToken cancellationToken)
        {
            try
            {
                var    queryParams = state;
                object tokenCache  = null;
                if (string.Equals(AuthSettings.Mode, "v1", StringComparison.OrdinalIgnoreCase))
                {
                    tokenCache = new Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache();
                }
                else if (string.Equals(AuthSettings.Mode, "v2", StringComparison.OrdinalIgnoreCase))
                {
                    tokenCache = new Microsoft.Identity.Client.TokenCache();
                }
                else if (string.Equals(AuthSettings.Mode, "b2c", StringComparison.OrdinalIgnoreCase))
                {
                }

                var resumptionCookie = UrlToken.Decode <ResumptionCookie>(queryParams);
                // Create the message that is send to conversation to resume the login flow
                var message = resumptionCookie.GetMessage();

                using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
                {
                    var        client     = scope.Resolve <IConnectorClient>();
                    AuthResult authResult = null;
                    if (string.Equals(AuthSettings.Mode, "v1", StringComparison.OrdinalIgnoreCase))
                    {
                        // Exchange the Auth code with Access token
                        var token = await AzureActiveDirectoryHelper.GetTokenByAuthCodeAsync(code, (Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache) tokenCache);

                        authResult = token;
                    }
                    else if (string.Equals(AuthSettings.Mode, "v2", StringComparison.OrdinalIgnoreCase))
                    {
                        // Exchange the Auth code with Access token
                        var token = await AzureActiveDirectoryHelper.GetTokenByAuthCodeAsync(code, (Microsoft.Identity.Client.TokenCache) tokenCache, Models.AuthSettings.Scopes);

                        authResult = token;
                    }
                    else if (string.Equals(AuthSettings.Mode, "b2c", StringComparison.OrdinalIgnoreCase))
                    {
                    }

                    IStateClient sc = scope.Resolve <IStateClient>();

                    //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.
                    int  magicNumber     = GenerateRandomNumber();
                    bool writeSuccessful = false;
                    uint writeAttempts   = 0;
                    while (!writeSuccessful && writeAttempts++ < MaxWriteAttempts)
                    {
                        try
                        {
                            BotData userData = sc.BotState.GetUserData(message.ChannelId, message.From.Id);
                            userData.SetProperty(ContextConstants.AuthResultKey, authResult);
                            userData.SetProperty(ContextConstants.MagicNumberKey, magicNumber);
                            userData.SetProperty(ContextConstants.MagicNumberValidated, "false");
                            sc.BotState.SetUserData(message.ChannelId, message.From.Id, userData);
                            writeSuccessful = true;
                        }
                        catch (HttpOperationException)
                        {
                            writeSuccessful = false;
                        }
                    }
                    var resp = new HttpResponseMessage(HttpStatusCode.OK);
                    if (!writeSuccessful)
                    {
                        message.Text = String.Empty; // fail the login process if we can't write UserData
                        await Conversation.ResumeAsync(resumptionCookie, message);

                        resp.Content = new StringContent("<html><body>Could not log you in at this time, please try again later</body></html>", System.Text.Encoding.UTF8, @"text/html");
                    }
                    else
                    {
                        await Conversation.ResumeAsync(resumptionCookie, message);

                        resp.Content = new StringContent($"<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>", System.Text.Encoding.UTF8, @"text/html");
                    }
                    return(resp);
                }
            }
            catch (Exception ex)
            {
                // Callback is called with no pending message as a result the login flow cannot be resumed.
                return(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex));
            }
        }
예제 #7
0
        public static AuthResult FromADALAuthenticationResult(Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationResult authResult, Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache tokenCache)
        {
            var TokenClaim = new System.IdentityModel.Tokens.JwtSecurityToken(authResult.IdToken);
            var alias = TokenClaim.Claims.FirstOrDefault(m => m.Type == "upn").Value;
            var result = new AuthResult
            {
                AccessToken = authResult.AccessToken,
                IdToken = authResult.IdToken,
                UserName = $"{authResult.UserInfo.GivenName} {authResult.UserInfo.FamilyName}",
                UserUniqueId = authResult.UserInfo.UniqueId,
                ExpiresOnUtcTicks = authResult.ExpiresOn.UtcTicks,
                TokenCache = tokenCache.Serialize(),
                Alias = alias
            };

            return result;
        }
        public static async Task <AuthResult> GetTokenByAuthCodeAsync(string authorizationCode, Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache tokenCache)
        {
            Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext context = new Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext(AuthSettings.EndpointUrl + "/" + AuthSettings.Tenant, tokenCache);
            Uri redirectUri = new Uri(AuthSettings.RedirectUrl);
            var result      = await context.AcquireTokenByAuthorizationCodeAsync(authorizationCode, redirectUri, new Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential(AuthSettings.ClientId, AuthSettings.ClientSecret));

            AuthResult authResult = AuthResult.FromADALAuthenticationResult(result, tokenCache);

            return(authResult);
        }
예제 #9
0
 internal static Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache SetADALTokenCache(byte[] tokenCache)
 {
     _adalTokenCache = new ADALTokenCache(tokenCache);
     return(_adalTokenCache);
 }
예제 #10
0
 internal void Initialize(OriginalTokenCache tokenCache)
 {
     _cache = tokenCache;
 }
예제 #11
0
        public async Task <HttpResponseMessage> OAuthCallback([FromUri] string code, [FromUri] string state)
        {
            try
            {
                object tokenCache = null;
                if (string.Equals(AuthSettings.Mode, "v1", StringComparison.OrdinalIgnoreCase))
                {
                    tokenCache = new Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache();
                }
                else if (string.Equals(AuthSettings.Mode, "v2", StringComparison.OrdinalIgnoreCase))
                {
                    tokenCache = new Microsoft.Identity.Client.TokenCache();
                }
                else if (string.Equals(AuthSettings.Mode, "b2c", StringComparison.OrdinalIgnoreCase))
                {
                }

                // Get the resumption cookie
                var resumptionCookie = UrlToken.Decode <ResumptionCookie>(state);
                // Create the message that is send to conversation to resume the login flow
                var message = resumptionCookie.GetMessage();

                using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
                {
                    var client = scope.Resolve <IConnectorClient>();

                    AuthResult authResult = null;

                    if (string.Equals(AuthSettings.Mode, "v1", StringComparison.OrdinalIgnoreCase))
                    {
                        // Exchange the Auth code with Access token
                        var token = await AzureActiveDirectoryHelper.GetTokenByAuthCodeAsync(code, (Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache) tokenCache);

                        authResult = token;
                    }
                    else if (string.Equals(AuthSettings.Mode, "v2", StringComparison.OrdinalIgnoreCase))
                    {
                        //TODO: Scopes definition here
                        // Exchange the Auth code with Access token
                        var token = await AzureActiveDirectoryHelper.GetTokenByAuthCodeAsync(code, (Microsoft.Identity.Client.TokenCache) tokenCache, new string[] { "User.Read" });

                        authResult = token;
                    }
                    else if (string.Equals(AuthSettings.Mode, "b2c", StringComparison.OrdinalIgnoreCase))
                    {
                    }

                    var reply = await Conversation.ResumeAsync(resumptionCookie, message);

                    var data = await client.Bots.GetPerUserConversationDataAsync(resumptionCookie.BotId, resumptionCookie.ConversationId, resumptionCookie.UserId);

                    reply.SetBotUserData(ContextConstants.AuthResultKey, authResult);
                    int magicNumber = GenerateRandomNumber();
                    reply.SetBotUserData(ContextConstants.MagicNumberKey, magicNumber);
                    reply.SetBotUserData(ContextConstants.MagicNumberValidated, "false");

                    //data.SetProperty(ContextConstants.AuthResultKey, authResult);
                    //data.SetProperty(ContextConstants.MagicNumberKey, magicNumber);
                    //data.SetProperty(ContextConstants.MagicNumberValidated, "false");

                    //await client.Bots.SetUserDataAsync(resumptionCookie.BotId, resumptionCookie.UserId, data);



                    reply.To   = message.From;
                    reply.From = message.To;

                    await client.Messages.SendMessageAsync(reply);

                    var resp = new HttpResponseMessage(HttpStatusCode.OK);
                    resp.Content = new StringContent($"<html><body>Almost done! Please copy this number and paste it back to your chat so your authentication can complete: {magicNumber}.</body></html>", System.Text.Encoding.UTF8, @"text/html");
                    return(resp);
                }
            }
            catch (Exception ex)
            {
                // 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!")));
            }
        }
예제 #12
0
        public async Task <HttpResponseMessage> OAuthCallback([FromUri] string code, [FromUri] string state, CancellationToken cancellationToken)
        {
            try
            {
                object tokenCache = null;
                if (string.Equals(AuthSettings.Mode, "v1", StringComparison.OrdinalIgnoreCase))
                {
                    tokenCache = new Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache();
                }
                else if (string.Equals(AuthSettings.Mode, "v2", StringComparison.OrdinalIgnoreCase))
                {
                    tokenCache = new Microsoft.Identity.Client.TokenCache();
                }
                else if (string.Equals(AuthSettings.Mode, "b2c", StringComparison.OrdinalIgnoreCase))
                {
                }

                // Get the resumption cookie
                var resumptionCookie = UrlToken.Decode <ResumptionCookie>(state);
                // Create the message that is send to conversation to resume the login flow
                var message = resumptionCookie.GetMessage();

                using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
                {
                    var        client     = scope.Resolve <IConnectorClient>();
                    AuthResult authResult = null;
                    if (string.Equals(AuthSettings.Mode, "v1", StringComparison.OrdinalIgnoreCase))
                    {
                        // Exchange the Auth code with Access token
                        var token = await AzureActiveDirectoryHelper.GetTokenByAuthCodeAsync(code, (Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache) tokenCache);

                        authResult = token;
                    }
                    else if (string.Equals(AuthSettings.Mode, "v2", StringComparison.OrdinalIgnoreCase))
                    {
                        // Exchange the Auth code with Access token
                        var token = await AzureActiveDirectoryHelper.GetTokenByAuthCodeAsync(code, (Microsoft.Identity.Client.TokenCache) tokenCache, Models.AuthSettings.Scopes);

                        authResult = token;
                    }
                    else if (string.Equals(AuthSettings.Mode, "b2c", StringComparison.OrdinalIgnoreCase))
                    {
                    }

                    IStateClient sc = scope.Resolve <IStateClient>();

                    //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.
                    var dataBag = scope.Resolve <IBotData>();
                    await dataBag.LoadAsync(cancellationToken);

                    int magicNumber = GenerateRandomNumber();
                    dataBag.UserData.SetValue(ContextConstants.AuthResultKey, authResult);
                    dataBag.UserData.SetValue(ContextConstants.MagicNumberKey, magicNumber);
                    dataBag.UserData.SetValue(ContextConstants.MagicNumberValidated, "false");
                    await dataBag.FlushAsync(cancellationToken);

                    await Conversation.ResumeAsync(resumptionCookie, message);

                    var resp = new HttpResponseMessage(HttpStatusCode.OK);
                    resp.Content = new StringContent($"<html><body>Almost done! Please copy this number and paste it back to your chat so your authentication can complete: {magicNumber}.</body></html>", System.Text.Encoding.UTF8, @"text/html");
                    return(resp);
                }
            }
            catch (Exception ex)
            {
                // Callback is called with no pending message as a result the login flow cannot be resumed.
                return(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex));
            }
        }