/// <summary>
        /// Authenticates the specified user name and password and returns the set of authorization policies for <see cref="T:System.IdentityModel.Tokens.UserNameSecurityToken"/> security tokens.
        /// </summary>
        /// <param name="userName">The user name associated with the security token.</param>
        /// <param name="password">The password associated with the security token.</param>
        /// <returns>
        /// A <see cref="T:System.Collections.ObjectModel.ReadOnlyCollection`1"/> of type <see cref="T:System.IdentityModel.Policy.IAuthorizationPolicy"/> that contains the set of authorization policies in effect for this application.
        /// </returns>
        /// <exception cref="T:System.ArgumentNullException">
        ///   <paramref name="userName"/> is null.</exception>
        ///
        /// <exception cref="T:System.IdentityModel.Tokens.SecurityTokenValidationException">
        ///   <paramref name="userName"/> and <paramref name="password"/> combination are not valid.</exception>
        protected override ReadOnlyCollection <IAuthorizationPolicy> ValidateUserNamePasswordCore(string userName, string password)
        {
            ReadOnlyCollection <IAuthorizationPolicy> currentPolicies = base.ValidateUserNamePasswordCore(userName, password);

            List <IAuthorizationPolicy> newPolicies = new List <IAuthorizationPolicy>(currentPolicies);

            string tenant = string.Empty;

            // Split the tenant and username fields
            string[] credentials = userName.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);
            if (credentials.Length > 1)
            {
                tenant   = credentials[0];
                userName = credentials[1];
            }

            // Validate the user name and password
            RequestContextData contextData = UserAccountCache.GetRequestContext(userName, password, tenant);

            if (contextData == null)
            {
                throw new SecurityTokenValidationException("Invalid username and/or password.");
            }

            // Extend the original context with culture information
            newPolicies.Add(new IdentityTenantAuthorizationPolicy(contextData.Identity, contextData.Tenant));

            return(newPolicies.AsReadOnly());
        }
        public void UserAccountCacheTest( )
        {
            const string username = "******";
            const string password = "******";

            UserAccount account = null;

            try
            {
                UserAccount existingAccount = Entity.GetByName <UserAccount>(username, true).FirstOrDefault( );

                if (existingAccount != null)
                {
                    existingAccount.Delete( );
                }

                account = new UserAccount
                {
                    Name               = username,
                    Password           = password,
                    AccountStatus_Enum = UserAccountStatusEnum_Enumeration.Active
                };

                account.Save( );

                Assert.AreEqual(0, GetUserAccountCacheCount( ));
                Assert.AreEqual(0, GetUserAccountCacheTenantCount(RunAsDefaultTenant.DefaultTenantName));

                UserAccountCache.GetRequestContext(username, password, RunAsDefaultTenant.DefaultTenantName);

                Assert.AreEqual(1, GetUserAccountCacheCount( ));
                Assert.AreEqual(1, GetUserAccountCacheTenantCount(RunAsDefaultTenant.DefaultTenantName));

                using (var domain = new TestAppDomain( ))
                {
                    Func <MessageEventArgs <TestMessage>, bool> predicate = m => m.Message.Action == "EDC" && m.Message.Items.Contains(username);

                    var instance = domain.InjectType <SubscriberRefObject <TestMessage> >(UserAccountCache.CacheName, RunAsDefaultTenant.DefaultTenantName, predicate);

                    UserAccountCache.Invalidate(username, RunAsDefaultTenant.DefaultTenantName);

                    bool waitOne = instance.MessageReceived.WaitOne(DefaultTimeout);

                    Assert.IsTrue(waitOne, "No message received in " + DefaultTimeout + "ms.");

                    Assert.GreaterOrEqual(instance.ReceivedMessages.Count, 1);

                    MessageEventArgs <TestMessage> message = instance.ReceivedMessages.FirstOrDefault(predicate);

                    Assert.IsNotNull(message, "Received message is invalid");
                }
            }
            finally
            {
                if (account != null)
                {
                    account.Delete( );
                }
            }
        }