ClientFormsAuthenticationMembershipProvider.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / Extensions / ClientServices / Providers / ClientFormsAuthenticationMembershipProvider.cs / 1305376 / ClientFormsAuthenticationMembershipProvider.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.ClientServices.Providers 
{ 
    using System;
    using System.Security.Principal; 
    using System.Data;
    using System.Data.OleDb;
    using System.IO;
    using System.Windows.Forms; 
    using System.Web;
    using System.Web.Resources; 
    using System.Web.Security; 
    using System.Threading;
    using System.Security.Cryptography; 
    using System.Globalization;
    using System.Text;
    using System.Runtime.InteropServices;
    using System.Collections.Specialized; 
    using System.Net;
    using System.Web.ClientServices; 
    using System.Configuration; 
    using System.Collections;
    using System.Data.Common; 
    using System.Security;
    using System.Security.Permissions;
    using System.Security.AccessControl;
    using System.Diagnostics.CodeAnalysis; 

    ///////////////////////////////////////////////////////////////////////////////// 
    ///////////////////////////////////////////////////////////////////////////////// 
    /////////////////////////////////////////////////////////////////////////////////
    public class ClientFormsAuthenticationMembershipProvider : MembershipProvider 
    {
        private string  _GetCredentialsTypeName     = null;
        private string  _ConnectionString           = null;
        private string  _ConnectionStringProvider   = null; 
        private string  _ServiceUri                 = null;
        private Type    _GetCredentialsType         = null; 
        private bool    _SavePasswordHash           = true; 
        private bool    _UsingFileSystemStore       = false;
        private bool    _UsingIsolatedStore         = false; 
        private bool    _UsingWFCService            = false;


        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
 
        [ SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId="2#", Justification="Reviewed and approved by feature crew"),
          SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId="username", Justification="consistent with Whidbey") 
        ]
        public static bool ValidateUser(string username, string password, string serviceUri)
        {
            CookieContainer cookies = null; 
            bool useWFCService = serviceUri.EndsWith(".svc", StringComparison.OrdinalIgnoreCase);
            bool validated = ValidateUserByCallingLogin(username, password, 
                                                        false, serviceUri, useWFCService, 
                                                        ref cookies, null, null);
            if (validated){ 
                Thread.CurrentPrincipal = new ClientRolePrincipal(new ClientFormsIdentity(username, password,
                                                                                          new ClientFormsAuthenticationMembershipProvider(),
                                                                                          "ClientForms", true, cookies));
            } 
            return validated;
        } 
 

        [SuppressMessage("Microsoft.Security", "CA2116:AptcaMethodsShouldOnlyCallAptcaMethods", Justification="Reviewed and approved by feature crew")] 
        private static bool ValidateUserByCallingLogin(string username, string password, bool rememberMe, string serviceUri,
                                                bool useWFCService, ref CookieContainer cookies,
                                                string connectionString, string connectionStringProvider)
        { 
            if (useWFCService) {
                throw new NotImplementedException(); 
 
//                 CustomBinding binding = ProxyHelper.GetBinding();
//                 ChannelFactory channelFactory = new ChannelFactory(binding, new EndpointAddress(serviceUri)); //(@"http://localhost/AuthSvc/service.svc")); 
//                 LoginService clientService = channelFactory.CreateChannel();
//                 using (new OperationContextScope((IContextChannel)clientService)) {
//                     ProxyHelper.AddCookiesToWCF(cookies, serviceUri, username, connectionString, connectionStringProvider);
//                     bool validated = clientService.Login(username, password, string.Empty, rememberMe); 
//                     ProxyHelper.GetCookiesFromWCF(cookies, serviceUri, username, connectionString, connectionStringProvider);
//                     return validated; 
//                 } 
            } else {
                serviceUri = serviceUri + "/Login"; 
                string [] paramNames = new string [] { "userName", "password", "createPersistentCookie"};
                object [] paramValues = new object [] {username, password, rememberMe};
                object o = ProxyHelper.CreateWebRequestAndGetResponse(serviceUri,
                                                                      ref cookies, 
                                                                      username,
                                                                      connectionString, 
                                                                      connectionStringProvider, 
                                                                      paramNames,
                                                                      paramValues, 
                                                                      typeof(bool));
                return ((o != null) && (o is bool) && ((bool)o) == true);
            }
        } 

        public override void Initialize(string name, NameValueCollection config) 
        { 
            if (config == null)
                throw new ArgumentNullException("config"); 
            base.Initialize(name, config);
            _GetCredentialsTypeName = config["credentialsProvider"];
            _ConnectionString = config["connectionStringName"];
            ServiceUri = config["serviceUri"]; 

            if (string.IsNullOrEmpty(_ConnectionString)) { 
                _ConnectionString = SqlHelper.GetDefaultConnectionString(); 
            } else {
                if (ConfigurationManager.ConnectionStrings[_ConnectionString] != null) { 
                    _ConnectionStringProvider = ConfigurationManager.ConnectionStrings[_ConnectionString].ProviderName;
                    _ConnectionString = ConfigurationManager.ConnectionStrings[_ConnectionString].ConnectionString;
                }
            } 

            switch(SqlHelper.IsSpecialConnectionString(_ConnectionString)) 
            { 
            case 1:
                _UsingFileSystemStore = true; 
                break;
            case 2:
                _UsingIsolatedStore = true;
                break; 
            default:
                break; 
            } 

            string temp = config["savePasswordHashLocally"]; 
            if (!string.IsNullOrEmpty(temp))
                _SavePasswordHash = (string.Compare(temp, "true", StringComparison.OrdinalIgnoreCase) == 0);

            config.Remove("savePasswordHashLocally"); 
            config.Remove("name");
            config.Remove("description"); 
            config.Remove("credentialsProvider"); 
            config.Remove("connectionStringName");
            config.Remove("serviceUri"); 
            foreach (string attribUnrecognized in config.Keys)
                if (!String.IsNullOrEmpty(attribUnrecognized))
                    throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, AtlasWeb.AttributeNotRecognized, attribUnrecognized));
        } 

        ///////////////////////////////////////////////////////////////////////////////// 
        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId="username", Justification="consistent with Whidbey")] 
        public override bool ValidateUser(string username, string password)
        {
            return ValidateUserCore(username, password, 2);
        } 

        ///////////////////////////////////////////////////////////////////////////////// 
        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId="username", Justification="consistent with Whidbey")] 
        public bool ValidateUser(string username, string password, bool rememberMe)
        {
            return ValidateUserCore(username, password, rememberMe ? 1 : 0);
        } 
        private bool ValidateUserCore(string username, string password, int rememberMeInt)
        { 
            lock (this) { 
                int promptCount = string.IsNullOrEmpty(username) ? 0 : 3;
 
                if (ValidateUserCore(username, password, rememberMeInt, ref promptCount, true)) {
                    if (UserValidated != null)
                        UserValidated(this, new UserValidatedEventArgs(Thread.CurrentPrincipal.Identity.Name));
                    return true; 
                }
 
                if (!string.IsNullOrEmpty(_GetCredentialsTypeName)) { 
                    while (promptCount < 3) {
                        if (ValidateUserCore(null, password, rememberMeInt, ref promptCount, false)) { 
                            if (UserValidated != null)
                                UserValidated(this, new UserValidatedEventArgs(Thread.CurrentPrincipal.Identity.Name));
                            return true;
                        } 
                    }
                } 
                return false; 
            }
        } 
        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        [SuppressMessage("Microsoft.Security", "CA2116:AptcaMethodsShouldOnlyCallAptcaMethods", Justification="Reviewed and approved by feature crew")] 
        public void Logout()
        { 
            IPrincipal p = Thread.CurrentPrincipal; 
            if (p == null || !(p.Identity is ClientFormsIdentity))
                return; 
            lock (this) {
                if (!ConnectivityStatus.IsOffline) {
                    CookieContainer cookies = ((ClientFormsIdentity)p.Identity).AuthenticationCookies;
 
                    if (_UsingWFCService) {
                        throw new NotImplementedException(); 
 
//                         CustomBinding binding = ProxyHelper.GetBinding();
//                         ChannelFactory channelFactory = new ChannelFactory(binding, new EndpointAddress(GetServiceUri())); 
//                         LoginService clientService = channelFactory.CreateChannel();
//                         using (new OperationContextScope((IContextChannel)clientService)) {
//                             ProxyHelper.AddCookiesToWCF(cookies, GetServiceUri(), p.Identity.Name, _ConnectionString, _ConnectionStringProvider);
//                             clientService.Logout(); 
//                             ProxyHelper.GetCookiesFromWCF(cookies, GetServiceUri(), p.Identity.Name, _ConnectionString, _ConnectionStringProvider);
//                         } 
                    } else { 
                        ProxyHelper.CreateWebRequestAndGetResponse(GetServiceUri() + "/Logout",
                                                                   ref cookies, 
                                                                   p.Identity.Name,
                                                                   _ConnectionString,
                                                                   _ConnectionStringProvider,
                                                                   null, 
                                                                   null,
                                                                   null); 
 
                    }
                } 
                SqlHelper.DeleteAllCookies(p.Identity.Name, _ConnectionString, _ConnectionStringProvider);
                Thread.CurrentPrincipal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
            }
            StoreLastUserNameInOffileStore(null); 
            if (UserValidated != null)
                UserValidated(this, new UserValidatedEventArgs("")); 
        } 

 
        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        private string GetServiceUri() 
        {
            if (string.IsNullOrEmpty(_ServiceUri)) 
                throw new ArgumentException(AtlasWeb.ServiceUriNotFound); 
            return _ServiceUri;
        } 

        [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification="Reviewed and approved by feature crew")]
        public string ServiceUri
        { 
            [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId="2#", Justification="Reviewed and approved by feature crew")]
            get { 
                return _ServiceUri; 
            }
            [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId="2#", Justification="Reviewed and approved by feature crew")] 
            set {
                _ServiceUri = value;
                if (string.IsNullOrEmpty(_ServiceUri)) {
                    _UsingWFCService = false; 
                } else {
                    _UsingWFCService = _ServiceUri.EndsWith(".svc", StringComparison.OrdinalIgnoreCase); 
                } 
            }
        } 

        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
        public event EventHandler UserValidated ; /*{
            add { _UserValidated += value; } 
            remove { _UserValidated -= value; } 
        }
        private event EventHandler _UserValidated; */ 
        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        // Private methods 
        private bool ValidateUserCore(string username, string password, int rememberMeInt, ref int promptCount, bool tryToUseLastLoggedInUser)
        { 
            // (new PermissionSet(PermissionState.Unrestricted)).Assert(); // 

            string              currentUser         = null; 
            bool                validated           = false;
            string              lastLoggedInUser    = (tryToUseLastLoggedInUser ? GetLastUserNameFromOffileStore() : null);
            bool                usernameNotSupplied = string.IsNullOrEmpty(username);
            CookieContainer     cookies             = null; 
            bool                sameAsLastLoggedInUser = false;
            bool                rememberMe          = (rememberMeInt == 1); 
            bool                rememberMeExplicitlySet = (rememberMeInt != 2); 

            if (Thread.CurrentPrincipal != null && Thread.CurrentPrincipal.Identity is ClientFormsIdentity) 
                currentUser = Thread.CurrentPrincipal.Identity.Name;
            if (string.IsNullOrEmpty(lastLoggedInUser) && currentUser != null)
                lastLoggedInUser = currentUser;
 
            ///////////////////////////////////////////////////////////////
            // Step 1: If username not supplied, use the last remembered user 
            if (usernameNotSupplied) 
                username = lastLoggedInUser;
 
            if ((Thread.CurrentPrincipal is ClientRolePrincipal) && (Thread.CurrentPrincipal.Identity is ClientFormsIdentity) && Thread.CurrentPrincipal.Identity.Name == username)
            {
                cookies = ((ClientFormsIdentity)Thread.CurrentPrincipal.Identity).AuthenticationCookies;
            } 

            /////////////////////////////////////////////////////////////// 
            // Step 2: If username is same as the last remembered user, 
            //         try authenticating by looking in the cookie store and calling the
            //          WebService if we are on-line 
            if (!string.IsNullOrEmpty(lastLoggedInUser) && string.Compare(lastLoggedInUser, username, StringComparison.OrdinalIgnoreCase) == 0) {
                if (!ConnectivityStatus.IsOffline) {
                    validated = ValidateByCallingIsLoggedIn(lastLoggedInUser, ref cookies);
                } else { 
                    validated = ProxyHelper.DoAnyCookiesExist(GetServiceUri(), lastLoggedInUser, _ConnectionString, _ConnectionStringProvider);
                } 
                sameAsLastLoggedInUser = true; 
            }
 

            if (!validated) {
                ///////////////////////////////////////////////////////////////
                // Step 3: If username is not supplied, then prompt for it 
                if(usernameNotSupplied) {
                    promptCount++; 
                    if (!GetCredsFromUI(ref username, ref password, ref rememberMe)) { 
                        promptCount += 100; // don't prompt again
                        return false; 
                    }
                    rememberMeExplicitlySet = true;
                }
 
                if (!ConnectivityStatus.IsOffline) {
                    /////////////////////////////////////////////////////////////// 
                    // Step 4: If app is online, connect to the server 
                    if (!ValidateUserByCallingLogin(username, password, rememberMe, GetServiceUri(),
                                                    _UsingWFCService, ref cookies, 
                                                    _ConnectionString, _ConnectionStringProvider))
                        return false;
                    // Store hash of password
                    StoreHashedPasswordInDB(username, password); 
                } else {
                    /////////////////////////////////////////////////////////////// 
                    // Step 5: If app is offline, validate with offline store 
                    if (!ValidateUserWithOfflineStore(username, password))
                        return false; 
                }
            }

            /////////////////////////////////////////////////////////////// 
            // Step 6: Store last logged in user
            if (!sameAsLastLoggedInUser || rememberMeExplicitlySet) 
                StoreLastUserNameInOffileStore(rememberMe ? username : null); 

            /////////////////////////////////////////////////////////////// 
            // Step 7: Save principal
            if ( !(Thread.CurrentPrincipal is ClientRolePrincipal) || !(Thread.CurrentPrincipal.Identity is ClientFormsIdentity) || Thread.CurrentPrincipal.Identity.Name != username)
            {
                if (cookies == null) 
                    cookies = ProxyHelper.ConstructCookieContainer(GetServiceUri(), username, _ConnectionString, _ConnectionStringProvider);
                Thread.CurrentPrincipal = new ClientRolePrincipal(new ClientFormsIdentity(username, password, this, "ClientForms", true, cookies)); 
            } 
            if (currentUser != null && string.Compare(username, currentUser, StringComparison.OrdinalIgnoreCase) != 0)
                SqlHelper.DeleteAllCookies(currentUser, _ConnectionString, _ConnectionStringProvider); 

            return true;
        }
 
        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
        ///////////////////////////////////////////////////////////////////////////////// 
        private string GetLastUserNameFromOffileStore()
        { 
            //if (MustAssertForSql)
            //  (new PermissionSet(PermissionState.Unrestricted)).Assert();
            if (_UsingFileSystemStore || _UsingIsolatedStore) {
                return ClientDataManager.GetAppClientData(_UsingIsolatedStore).LastLoggedInUserName; 
            }
 
            using (DbConnection conn = SqlHelper.GetConnection(null, _ConnectionString, _ConnectionStringProvider)) { 
                DbTransaction trans = null;
                try 
                {
                    trans = conn.BeginTransaction();
                    DbCommand cmd = conn.CreateCommand();
                    cmd.Transaction = trans; 
                    cmd.CommandText = "SELECT PropertyValue FROM ApplicationProperties WHERE PropertyName = N'LastLoggedInUserName'";
                    object o = cmd.ExecuteScalar(); 
                    return ((o!=null) ?  o.ToString() : null); 
                } catch {
                    if (trans != null) { 
                        trans.Rollback();
                        trans = null;
                    }
                    throw; 
                } finally {
                    if (trans != null) 
                        trans.Commit(); 
                }
            } 
        }

        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        private void StoreLastUserNameInOffileStore(string username) 
        { 
            if (_UsingFileSystemStore || _UsingIsolatedStore) {
                ClientData cd = ClientDataManager.GetAppClientData(_UsingIsolatedStore); 
                cd.LastLoggedInUserName = username;
                cd.LastLoggedInDateUtc = DateTime.UtcNow;
                cd.Save();
                return; 
            }
 
            //if (MustAssertForSql) 
            //    (new PermissionSet(PermissionState.Unrestricted)).Assert();
            using (DbConnection conn = SqlHelper.GetConnection(null, _ConnectionString, _ConnectionStringProvider)) { 
                DbTransaction trans = null;
                try
                {
                    trans = conn.BeginTransaction(); 
                    DbCommand cmd = conn.CreateCommand();
                    cmd.Transaction = trans; 
                    cmd.CommandText = "DELETE FROM ApplicationProperties WHERE PropertyName = N'LastLoggedInUserName'"; 
                    cmd.ExecuteNonQuery();
                    if (!string.IsNullOrEmpty(username)) { 
                        cmd = conn.CreateCommand();
                        cmd.Transaction = trans;
                        cmd.CommandText = "INSERT INTO ApplicationProperties(PropertyName, PropertyValue) VALUES (N'LastLoggedInUserName', @UserName)";
                        SqlHelper.AddParameter(conn, cmd, "@UserName", username); 
                        cmd.ExecuteNonQuery();
 
                        cmd = conn.CreateCommand(); 
                        cmd.Transaction = trans;
                        cmd.CommandText = "INSERT INTO ApplicationProperties(PropertyName, PropertyValue) VALUES (N'LastLoggedInDate', @Date)"; 
                        SqlHelper.AddParameter(conn, cmd, "@Date", DateTime.Now.ToFileTimeUtc().ToString(CultureInfo.InvariantCulture));
                        cmd.Transaction = trans;
                        cmd.ExecuteNonQuery();
                    } 
                } catch {
                    if (trans != null) { 
                        trans.Rollback(); 
                        trans = null;
                    } 
                    throw;
                } finally {
                    if (trans != null)
                        trans.Commit(); 
                }
            } 
        } 

        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        private bool GetCredsFromUI(ref string username, ref string password, ref bool rememberMe)
        { 
            if (_GetCredentialsType == null) {
                if (string.IsNullOrEmpty(_GetCredentialsTypeName)) 
                    return false; 
                _GetCredentialsType = Type.GetType(_GetCredentialsTypeName, true, true);
            } 


            ClientFormsAuthenticationCredentials creds =  ((IClientFormsAuthenticationCredentialsProvider)Activator.CreateInstance(_GetCredentialsType)).GetCredentials();
            if (creds == null) 
                return false;
            username = creds.UserName; 
            password = creds.Password; 
            rememberMe = creds.RememberMe;
            return true; 
        }


        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
        private void StoreHashedPasswordInDB(string username, string password) 
        {
            if (!_SavePasswordHash) 
                return;

            // if (MustAssertForSql)
            //    (new PermissionSet(PermissionState.Unrestricted)).Assert(); 
            byte[] buf = new byte[16];
            (new RNGCryptoServiceProvider()).GetBytes(buf); 
 
            string passwordSalt = Convert.ToBase64String(buf);
            string passwordHash = EncodePassword(password, buf); 

            if (_UsingFileSystemStore || _UsingIsolatedStore) {
                ClientData cd = ClientDataManager.GetUserClientData(username, _UsingIsolatedStore);
                cd.PasswordHash = passwordHash; 
                cd.PasswordSalt = passwordSalt;
                cd.Save(); 
                return; 
            }
 

            using (DbConnection conn = SqlHelper.GetConnection(username, _ConnectionString, _ConnectionStringProvider)) {
                DbTransaction trans = null;
                DbCommand cmd = null; 
                try {
 
                    trans = conn.BeginTransaction(); 

                    cmd = conn.CreateCommand(); 
                    cmd.CommandText = "DELETE FROM UserProperties WHERE PropertyName = @PasswordHashName";
                    SqlHelper.AddParameter(conn, cmd, "@PasswordHashName", "PasswordHash_" + username);
                    cmd.Transaction = trans;
                    cmd.ExecuteNonQuery(); 

                    cmd = conn.CreateCommand(); 
                    cmd.CommandText = "DELETE FROM UserProperties WHERE PropertyName = @PasswordSaltName"; 
                    SqlHelper.AddParameter(conn, cmd, "@PasswordSaltName", "PasswordSalt_" + username);
                    cmd.Transaction = trans; 
                    cmd.ExecuteNonQuery();


                    cmd = conn.CreateCommand(); 
                    cmd.CommandText = "INSERT INTO UserProperties(PropertyName, PropertyValue) VALUES (@PasswordHashName, @PasswordHashValue)";
                    SqlHelper.AddParameter(conn, cmd, "@PasswordHashName", "PasswordHash_" + username); 
                    SqlHelper.AddParameter(conn, cmd, "@PasswordHashValue", passwordHash); 
                    cmd.Transaction = trans;
                    cmd.ExecuteNonQuery(); 

                    cmd = conn.CreateCommand();
                    cmd.CommandText = "INSERT INTO UserProperties(PropertyName, PropertyValue) VALUES (@PasswordSaltName, @PasswordSaltValue)";
                    SqlHelper.AddParameter(conn, cmd, "@PasswordSaltName", "PasswordSalt_" + username); 
                    SqlHelper.AddParameter(conn, cmd, "@PasswordSaltValue", passwordSalt);
                    cmd.Transaction = trans; 
                    cmd.ExecuteNonQuery(); 
                } catch {
                    if (trans != null) { 
                        trans.Rollback();
                        trans = null;
                    }
                    throw; 
                } finally {
                    if (trans != null) 
                        trans.Commit(); 
                }
            } 
        }


        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
        private static string EncodePassword(string password, byte[] salt) 
        {
            byte [] bufPass = Encoding.Unicode.GetBytes(password); 
            byte [] bufAll = new byte[salt.Length + bufPass.Length];
            salt.CopyTo(bufAll, 0);
            bufPass.CopyTo(bufAll, salt.Length);
 
            byte[] buffer = null;
            using(SHA1 s = SHA1.Create()) 
                buffer = s.ComputeHash(bufAll); 
            return Convert.ToBase64String(buffer);
        } 


        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        [SuppressMessage("Microsoft.Security", "CA2116:AptcaMethodsShouldOnlyCallAptcaMethods", Justification="Reviewed and approved by feature crew")] 
        private bool ValidateByCallingIsLoggedIn(string username, ref CookieContainer cookies) 
        {
            if (_UsingWFCService) { 
                throw new NotImplementedException();

//                 CustomBinding binding = ProxyHelper.GetBinding();
//                 ChannelFactory channelFactory = new ChannelFactory(binding, new EndpointAddress(GetServiceUri())); 
//                 LoginService clientService = channelFactory.CreateChannel();
//                 using (new OperationContextScope((IContextChannel)clientService)) { 
//                     ProxyHelper.AddCookiesToWCF(cookies, GetServiceUri(), username, _ConnectionString, _ConnectionStringProvider); 
//                     bool validated = clientService.IsLoggedIn();
//                     ProxyHelper.GetCookiesFromWCF(cookies, GetServiceUri(), username, _ConnectionString, _ConnectionStringProvider); 
//                     return validated;
//                 }
            } else {
                object o = ProxyHelper.CreateWebRequestAndGetResponse(GetServiceUri() + "/IsLoggedIn", 
                                                                      ref cookies,
                                                                      username, 
                                                                      _ConnectionString, 
                                                                      _ConnectionStringProvider,
                                                                      null, null, 
                                                                      typeof(bool));
                return ((o != null) && (o is bool) && ((bool)o) == true);
            }
 
        }
 
        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
        private bool ValidateUserWithOfflineStore(string username, string password)
        {
            if (!_SavePasswordHash)
                return false; 

            string passwordHash = null; 
            string passwordSalt = null; 

            if (_UsingFileSystemStore || _UsingIsolatedStore) { 
                ClientData cd = ClientDataManager.GetUserClientData(username, _UsingIsolatedStore);
                passwordHash = cd.PasswordHash;
                passwordSalt = cd.PasswordSalt;
            } else { 

                // if (MustAssertForSql) 
                //     (new PermissionSet(PermissionState.Unrestricted)).Assert(); 
                DbTransaction trans = null;
                using (DbConnection conn = SqlHelper.GetConnection(username, _ConnectionString, _ConnectionStringProvider)) { 
                    try {
                        DbCommand cmd = conn.CreateCommand();
                        cmd.Transaction = trans;
                        cmd.CommandText = "SELECT PropertyValue FROM UserProperties WHERE PropertyName = @PasswordHashName"; 
                        SqlHelper.AddParameter(conn, cmd, "@PasswordHashName", "PasswordHash_" + username);
                        passwordHash = cmd.ExecuteScalar() as string; 
 
                        cmd = conn.CreateCommand();
                        cmd.Transaction = trans; 
                        cmd.CommandText = "SELECT PropertyValue FROM UserProperties WHERE PropertyName = @PasswordSaltName";
                        SqlHelper.AddParameter(conn, cmd, "@PasswordSaltName", "PasswordSalt_" + username);
                        passwordSalt = cmd.ExecuteScalar() as string;
                    } catch { 
                        if (trans != null) {
                            trans.Rollback(); 
                            trans = null; 
                        }
                        throw; 
                    } finally {
                        if (trans != null)
                            trans.Commit();
                    } 
                }
            } 
 
            if (string.IsNullOrEmpty(passwordHash) || string.IsNullOrEmpty(passwordSalt))
                return false; 

            byte [] buf = Convert.FromBase64String(passwordSalt);
            return passwordHash == EncodePassword(password, buf);
        } 
        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
        ///////////////////////////////////////////////////////////////////////////////// 
//         private bool _MustAssertForSqlDecided = false;
//         private bool _MustAssertForSql        = false; 
//         private bool MustAssertForSql {
//            get {
//                if (!_MustAssertForSqlDecided) {
//                    _MustAssertForSql = (_ConnectionString == "Data Source = |SQL\\CE|"); 
//                    _MustAssertForSqlDecided = true;
//                } 
//                return _MustAssertForSql; 
//            }
//         } 
        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        // Non-implemented public properties 
        public override bool EnablePasswordRetrieval { get { return false; } }
        public override bool EnablePasswordReset { get { return false; } } 
        public override bool RequiresQuestionAndAnswer { get { return false; } } 
        public override string ApplicationName { get { return ""; } set { } }
        public override int MaxInvalidPasswordAttempts { get { return int.MaxValue; } } 
        public override int PasswordAttemptWindow { get { return int.MaxValue; } }
        public override bool RequiresUniqueEmail { get { return false; } }
        public override MembershipPasswordFormat PasswordFormat { get { return MembershipPasswordFormat.Hashed; } }
        public override int MinRequiredPasswordLength { get { return 1; } } 
        public override int MinRequiredNonAlphanumericCharacters { get { return 0; } }
        public override string PasswordStrengthRegularExpression { get { return "*"; } } 
 

        public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, 
                                                   bool isApproved, object providerUserKey, out MembershipCreateStatus status)
        {
            throw new NotSupportedException();
        } 

        public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer) 
        { 
            throw new NotSupportedException();
        } 

        public override string GetPassword(string username, string answer)
        {
            throw new NotSupportedException(); 
        }
 
        public override bool ChangePassword(string username, string oldPassword, string newPassword) 
        {
            throw new NotSupportedException(); 
        }


        public override string ResetPassword(string username, string answer) 
        {
            throw new NotSupportedException(); 
        } 

        public override void UpdateUser(MembershipUser user) 
        {
            throw new NotSupportedException();
        }
 

        public override bool UnlockUser(string username) 
        { 
            throw new NotSupportedException();
        } 

        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {
            throw new NotSupportedException(); 
        }
 
        public override MembershipUser GetUser(string username, bool userIsOnline) 
        {
            throw new NotSupportedException(); 
        }

        public override string GetUserNameByEmail(string email)
        { 
            throw new NotSupportedException();
        } 
 
        public override bool DeleteUser(string username, bool deleteAllRelatedData)
        { 
            throw new NotSupportedException();
        }

 
        public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
        { 
            throw new NotSupportedException(); 
        }
 

        public override int GetNumberOfUsersOnline()
        {
            throw new NotSupportedException(); 
        }
 
 
        public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
        { 
            throw new NotSupportedException();
        }

        public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords) 
        {
            throw new NotSupportedException(); 
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.ClientServices.Providers 
{ 
    using System;
    using System.Security.Principal; 
    using System.Data;
    using System.Data.OleDb;
    using System.IO;
    using System.Windows.Forms; 
    using System.Web;
    using System.Web.Resources; 
    using System.Web.Security; 
    using System.Threading;
    using System.Security.Cryptography; 
    using System.Globalization;
    using System.Text;
    using System.Runtime.InteropServices;
    using System.Collections.Specialized; 
    using System.Net;
    using System.Web.ClientServices; 
    using System.Configuration; 
    using System.Collections;
    using System.Data.Common; 
    using System.Security;
    using System.Security.Permissions;
    using System.Security.AccessControl;
    using System.Diagnostics.CodeAnalysis; 

    ///////////////////////////////////////////////////////////////////////////////// 
    ///////////////////////////////////////////////////////////////////////////////// 
    /////////////////////////////////////////////////////////////////////////////////
    public class ClientFormsAuthenticationMembershipProvider : MembershipProvider 
    {
        private string  _GetCredentialsTypeName     = null;
        private string  _ConnectionString           = null;
        private string  _ConnectionStringProvider   = null; 
        private string  _ServiceUri                 = null;
        private Type    _GetCredentialsType         = null; 
        private bool    _SavePasswordHash           = true; 
        private bool    _UsingFileSystemStore       = false;
        private bool    _UsingIsolatedStore         = false; 
        private bool    _UsingWFCService            = false;


        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
 
        [ SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId="2#", Justification="Reviewed and approved by feature crew"),
          SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId="username", Justification="consistent with Whidbey") 
        ]
        public static bool ValidateUser(string username, string password, string serviceUri)
        {
            CookieContainer cookies = null; 
            bool useWFCService = serviceUri.EndsWith(".svc", StringComparison.OrdinalIgnoreCase);
            bool validated = ValidateUserByCallingLogin(username, password, 
                                                        false, serviceUri, useWFCService, 
                                                        ref cookies, null, null);
            if (validated){ 
                Thread.CurrentPrincipal = new ClientRolePrincipal(new ClientFormsIdentity(username, password,
                                                                                          new ClientFormsAuthenticationMembershipProvider(),
                                                                                          "ClientForms", true, cookies));
            } 
            return validated;
        } 
 

        [SuppressMessage("Microsoft.Security", "CA2116:AptcaMethodsShouldOnlyCallAptcaMethods", Justification="Reviewed and approved by feature crew")] 
        private static bool ValidateUserByCallingLogin(string username, string password, bool rememberMe, string serviceUri,
                                                bool useWFCService, ref CookieContainer cookies,
                                                string connectionString, string connectionStringProvider)
        { 
            if (useWFCService) {
                throw new NotImplementedException(); 
 
//                 CustomBinding binding = ProxyHelper.GetBinding();
//                 ChannelFactory channelFactory = new ChannelFactory(binding, new EndpointAddress(serviceUri)); //(@"http://localhost/AuthSvc/service.svc")); 
//                 LoginService clientService = channelFactory.CreateChannel();
//                 using (new OperationContextScope((IContextChannel)clientService)) {
//                     ProxyHelper.AddCookiesToWCF(cookies, serviceUri, username, connectionString, connectionStringProvider);
//                     bool validated = clientService.Login(username, password, string.Empty, rememberMe); 
//                     ProxyHelper.GetCookiesFromWCF(cookies, serviceUri, username, connectionString, connectionStringProvider);
//                     return validated; 
//                 } 
            } else {
                serviceUri = serviceUri + "/Login"; 
                string [] paramNames = new string [] { "userName", "password", "createPersistentCookie"};
                object [] paramValues = new object [] {username, password, rememberMe};
                object o = ProxyHelper.CreateWebRequestAndGetResponse(serviceUri,
                                                                      ref cookies, 
                                                                      username,
                                                                      connectionString, 
                                                                      connectionStringProvider, 
                                                                      paramNames,
                                                                      paramValues, 
                                                                      typeof(bool));
                return ((o != null) && (o is bool) && ((bool)o) == true);
            }
        } 

        public override void Initialize(string name, NameValueCollection config) 
        { 
            if (config == null)
                throw new ArgumentNullException("config"); 
            base.Initialize(name, config);
            _GetCredentialsTypeName = config["credentialsProvider"];
            _ConnectionString = config["connectionStringName"];
            ServiceUri = config["serviceUri"]; 

            if (string.IsNullOrEmpty(_ConnectionString)) { 
                _ConnectionString = SqlHelper.GetDefaultConnectionString(); 
            } else {
                if (ConfigurationManager.ConnectionStrings[_ConnectionString] != null) { 
                    _ConnectionStringProvider = ConfigurationManager.ConnectionStrings[_ConnectionString].ProviderName;
                    _ConnectionString = ConfigurationManager.ConnectionStrings[_ConnectionString].ConnectionString;
                }
            } 

            switch(SqlHelper.IsSpecialConnectionString(_ConnectionString)) 
            { 
            case 1:
                _UsingFileSystemStore = true; 
                break;
            case 2:
                _UsingIsolatedStore = true;
                break; 
            default:
                break; 
            } 

            string temp = config["savePasswordHashLocally"]; 
            if (!string.IsNullOrEmpty(temp))
                _SavePasswordHash = (string.Compare(temp, "true", StringComparison.OrdinalIgnoreCase) == 0);

            config.Remove("savePasswordHashLocally"); 
            config.Remove("name");
            config.Remove("description"); 
            config.Remove("credentialsProvider"); 
            config.Remove("connectionStringName");
            config.Remove("serviceUri"); 
            foreach (string attribUnrecognized in config.Keys)
                if (!String.IsNullOrEmpty(attribUnrecognized))
                    throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, AtlasWeb.AttributeNotRecognized, attribUnrecognized));
        } 

        ///////////////////////////////////////////////////////////////////////////////// 
        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId="username", Justification="consistent with Whidbey")] 
        public override bool ValidateUser(string username, string password)
        {
            return ValidateUserCore(username, password, 2);
        } 

        ///////////////////////////////////////////////////////////////////////////////// 
        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId="username", Justification="consistent with Whidbey")] 
        public bool ValidateUser(string username, string password, bool rememberMe)
        {
            return ValidateUserCore(username, password, rememberMe ? 1 : 0);
        } 
        private bool ValidateUserCore(string username, string password, int rememberMeInt)
        { 
            lock (this) { 
                int promptCount = string.IsNullOrEmpty(username) ? 0 : 3;
 
                if (ValidateUserCore(username, password, rememberMeInt, ref promptCount, true)) {
                    if (UserValidated != null)
                        UserValidated(this, new UserValidatedEventArgs(Thread.CurrentPrincipal.Identity.Name));
                    return true; 
                }
 
                if (!string.IsNullOrEmpty(_GetCredentialsTypeName)) { 
                    while (promptCount < 3) {
                        if (ValidateUserCore(null, password, rememberMeInt, ref promptCount, false)) { 
                            if (UserValidated != null)
                                UserValidated(this, new UserValidatedEventArgs(Thread.CurrentPrincipal.Identity.Name));
                            return true;
                        } 
                    }
                } 
                return false; 
            }
        } 
        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        [SuppressMessage("Microsoft.Security", "CA2116:AptcaMethodsShouldOnlyCallAptcaMethods", Justification="Reviewed and approved by feature crew")] 
        public void Logout()
        { 
            IPrincipal p = Thread.CurrentPrincipal; 
            if (p == null || !(p.Identity is ClientFormsIdentity))
                return; 
            lock (this) {
                if (!ConnectivityStatus.IsOffline) {
                    CookieContainer cookies = ((ClientFormsIdentity)p.Identity).AuthenticationCookies;
 
                    if (_UsingWFCService) {
                        throw new NotImplementedException(); 
 
//                         CustomBinding binding = ProxyHelper.GetBinding();
//                         ChannelFactory channelFactory = new ChannelFactory(binding, new EndpointAddress(GetServiceUri())); 
//                         LoginService clientService = channelFactory.CreateChannel();
//                         using (new OperationContextScope((IContextChannel)clientService)) {
//                             ProxyHelper.AddCookiesToWCF(cookies, GetServiceUri(), p.Identity.Name, _ConnectionString, _ConnectionStringProvider);
//                             clientService.Logout(); 
//                             ProxyHelper.GetCookiesFromWCF(cookies, GetServiceUri(), p.Identity.Name, _ConnectionString, _ConnectionStringProvider);
//                         } 
                    } else { 
                        ProxyHelper.CreateWebRequestAndGetResponse(GetServiceUri() + "/Logout",
                                                                   ref cookies, 
                                                                   p.Identity.Name,
                                                                   _ConnectionString,
                                                                   _ConnectionStringProvider,
                                                                   null, 
                                                                   null,
                                                                   null); 
 
                    }
                } 
                SqlHelper.DeleteAllCookies(p.Identity.Name, _ConnectionString, _ConnectionStringProvider);
                Thread.CurrentPrincipal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
            }
            StoreLastUserNameInOffileStore(null); 
            if (UserValidated != null)
                UserValidated(this, new UserValidatedEventArgs("")); 
        } 

 
        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        private string GetServiceUri() 
        {
            if (string.IsNullOrEmpty(_ServiceUri)) 
                throw new ArgumentException(AtlasWeb.ServiceUriNotFound); 
            return _ServiceUri;
        } 

        [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification="Reviewed and approved by feature crew")]
        public string ServiceUri
        { 
            [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId="2#", Justification="Reviewed and approved by feature crew")]
            get { 
                return _ServiceUri; 
            }
            [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId="2#", Justification="Reviewed and approved by feature crew")] 
            set {
                _ServiceUri = value;
                if (string.IsNullOrEmpty(_ServiceUri)) {
                    _UsingWFCService = false; 
                } else {
                    _UsingWFCService = _ServiceUri.EndsWith(".svc", StringComparison.OrdinalIgnoreCase); 
                } 
            }
        } 

        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
        public event EventHandler UserValidated ; /*{
            add { _UserValidated += value; } 
            remove { _UserValidated -= value; } 
        }
        private event EventHandler _UserValidated; */ 
        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        // Private methods 
        private bool ValidateUserCore(string username, string password, int rememberMeInt, ref int promptCount, bool tryToUseLastLoggedInUser)
        { 
            // (new PermissionSet(PermissionState.Unrestricted)).Assert(); // 

            string              currentUser         = null; 
            bool                validated           = false;
            string              lastLoggedInUser    = (tryToUseLastLoggedInUser ? GetLastUserNameFromOffileStore() : null);
            bool                usernameNotSupplied = string.IsNullOrEmpty(username);
            CookieContainer     cookies             = null; 
            bool                sameAsLastLoggedInUser = false;
            bool                rememberMe          = (rememberMeInt == 1); 
            bool                rememberMeExplicitlySet = (rememberMeInt != 2); 

            if (Thread.CurrentPrincipal != null && Thread.CurrentPrincipal.Identity is ClientFormsIdentity) 
                currentUser = Thread.CurrentPrincipal.Identity.Name;
            if (string.IsNullOrEmpty(lastLoggedInUser) && currentUser != null)
                lastLoggedInUser = currentUser;
 
            ///////////////////////////////////////////////////////////////
            // Step 1: If username not supplied, use the last remembered user 
            if (usernameNotSupplied) 
                username = lastLoggedInUser;
 
            if ((Thread.CurrentPrincipal is ClientRolePrincipal) && (Thread.CurrentPrincipal.Identity is ClientFormsIdentity) && Thread.CurrentPrincipal.Identity.Name == username)
            {
                cookies = ((ClientFormsIdentity)Thread.CurrentPrincipal.Identity).AuthenticationCookies;
            } 

            /////////////////////////////////////////////////////////////// 
            // Step 2: If username is same as the last remembered user, 
            //         try authenticating by looking in the cookie store and calling the
            //          WebService if we are on-line 
            if (!string.IsNullOrEmpty(lastLoggedInUser) && string.Compare(lastLoggedInUser, username, StringComparison.OrdinalIgnoreCase) == 0) {
                if (!ConnectivityStatus.IsOffline) {
                    validated = ValidateByCallingIsLoggedIn(lastLoggedInUser, ref cookies);
                } else { 
                    validated = ProxyHelper.DoAnyCookiesExist(GetServiceUri(), lastLoggedInUser, _ConnectionString, _ConnectionStringProvider);
                } 
                sameAsLastLoggedInUser = true; 
            }
 

            if (!validated) {
                ///////////////////////////////////////////////////////////////
                // Step 3: If username is not supplied, then prompt for it 
                if(usernameNotSupplied) {
                    promptCount++; 
                    if (!GetCredsFromUI(ref username, ref password, ref rememberMe)) { 
                        promptCount += 100; // don't prompt again
                        return false; 
                    }
                    rememberMeExplicitlySet = true;
                }
 
                if (!ConnectivityStatus.IsOffline) {
                    /////////////////////////////////////////////////////////////// 
                    // Step 4: If app is online, connect to the server 
                    if (!ValidateUserByCallingLogin(username, password, rememberMe, GetServiceUri(),
                                                    _UsingWFCService, ref cookies, 
                                                    _ConnectionString, _ConnectionStringProvider))
                        return false;
                    // Store hash of password
                    StoreHashedPasswordInDB(username, password); 
                } else {
                    /////////////////////////////////////////////////////////////// 
                    // Step 5: If app is offline, validate with offline store 
                    if (!ValidateUserWithOfflineStore(username, password))
                        return false; 
                }
            }

            /////////////////////////////////////////////////////////////// 
            // Step 6: Store last logged in user
            if (!sameAsLastLoggedInUser || rememberMeExplicitlySet) 
                StoreLastUserNameInOffileStore(rememberMe ? username : null); 

            /////////////////////////////////////////////////////////////// 
            // Step 7: Save principal
            if ( !(Thread.CurrentPrincipal is ClientRolePrincipal) || !(Thread.CurrentPrincipal.Identity is ClientFormsIdentity) || Thread.CurrentPrincipal.Identity.Name != username)
            {
                if (cookies == null) 
                    cookies = ProxyHelper.ConstructCookieContainer(GetServiceUri(), username, _ConnectionString, _ConnectionStringProvider);
                Thread.CurrentPrincipal = new ClientRolePrincipal(new ClientFormsIdentity(username, password, this, "ClientForms", true, cookies)); 
            } 
            if (currentUser != null && string.Compare(username, currentUser, StringComparison.OrdinalIgnoreCase) != 0)
                SqlHelper.DeleteAllCookies(currentUser, _ConnectionString, _ConnectionStringProvider); 

            return true;
        }
 
        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
        ///////////////////////////////////////////////////////////////////////////////// 
        private string GetLastUserNameFromOffileStore()
        { 
            //if (MustAssertForSql)
            //  (new PermissionSet(PermissionState.Unrestricted)).Assert();
            if (_UsingFileSystemStore || _UsingIsolatedStore) {
                return ClientDataManager.GetAppClientData(_UsingIsolatedStore).LastLoggedInUserName; 
            }
 
            using (DbConnection conn = SqlHelper.GetConnection(null, _ConnectionString, _ConnectionStringProvider)) { 
                DbTransaction trans = null;
                try 
                {
                    trans = conn.BeginTransaction();
                    DbCommand cmd = conn.CreateCommand();
                    cmd.Transaction = trans; 
                    cmd.CommandText = "SELECT PropertyValue FROM ApplicationProperties WHERE PropertyName = N'LastLoggedInUserName'";
                    object o = cmd.ExecuteScalar(); 
                    return ((o!=null) ?  o.ToString() : null); 
                } catch {
                    if (trans != null) { 
                        trans.Rollback();
                        trans = null;
                    }
                    throw; 
                } finally {
                    if (trans != null) 
                        trans.Commit(); 
                }
            } 
        }

        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        private void StoreLastUserNameInOffileStore(string username) 
        { 
            if (_UsingFileSystemStore || _UsingIsolatedStore) {
                ClientData cd = ClientDataManager.GetAppClientData(_UsingIsolatedStore); 
                cd.LastLoggedInUserName = username;
                cd.LastLoggedInDateUtc = DateTime.UtcNow;
                cd.Save();
                return; 
            }
 
            //if (MustAssertForSql) 
            //    (new PermissionSet(PermissionState.Unrestricted)).Assert();
            using (DbConnection conn = SqlHelper.GetConnection(null, _ConnectionString, _ConnectionStringProvider)) { 
                DbTransaction trans = null;
                try
                {
                    trans = conn.BeginTransaction(); 
                    DbCommand cmd = conn.CreateCommand();
                    cmd.Transaction = trans; 
                    cmd.CommandText = "DELETE FROM ApplicationProperties WHERE PropertyName = N'LastLoggedInUserName'"; 
                    cmd.ExecuteNonQuery();
                    if (!string.IsNullOrEmpty(username)) { 
                        cmd = conn.CreateCommand();
                        cmd.Transaction = trans;
                        cmd.CommandText = "INSERT INTO ApplicationProperties(PropertyName, PropertyValue) VALUES (N'LastLoggedInUserName', @UserName)";
                        SqlHelper.AddParameter(conn, cmd, "@UserName", username); 
                        cmd.ExecuteNonQuery();
 
                        cmd = conn.CreateCommand(); 
                        cmd.Transaction = trans;
                        cmd.CommandText = "INSERT INTO ApplicationProperties(PropertyName, PropertyValue) VALUES (N'LastLoggedInDate', @Date)"; 
                        SqlHelper.AddParameter(conn, cmd, "@Date", DateTime.Now.ToFileTimeUtc().ToString(CultureInfo.InvariantCulture));
                        cmd.Transaction = trans;
                        cmd.ExecuteNonQuery();
                    } 
                } catch {
                    if (trans != null) { 
                        trans.Rollback(); 
                        trans = null;
                    } 
                    throw;
                } finally {
                    if (trans != null)
                        trans.Commit(); 
                }
            } 
        } 

        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        private bool GetCredsFromUI(ref string username, ref string password, ref bool rememberMe)
        { 
            if (_GetCredentialsType == null) {
                if (string.IsNullOrEmpty(_GetCredentialsTypeName)) 
                    return false; 
                _GetCredentialsType = Type.GetType(_GetCredentialsTypeName, true, true);
            } 


            ClientFormsAuthenticationCredentials creds =  ((IClientFormsAuthenticationCredentialsProvider)Activator.CreateInstance(_GetCredentialsType)).GetCredentials();
            if (creds == null) 
                return false;
            username = creds.UserName; 
            password = creds.Password; 
            rememberMe = creds.RememberMe;
            return true; 
        }


        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
        private void StoreHashedPasswordInDB(string username, string password) 
        {
            if (!_SavePasswordHash) 
                return;

            // if (MustAssertForSql)
            //    (new PermissionSet(PermissionState.Unrestricted)).Assert(); 
            byte[] buf = new byte[16];
            (new RNGCryptoServiceProvider()).GetBytes(buf); 
 
            string passwordSalt = Convert.ToBase64String(buf);
            string passwordHash = EncodePassword(password, buf); 

            if (_UsingFileSystemStore || _UsingIsolatedStore) {
                ClientData cd = ClientDataManager.GetUserClientData(username, _UsingIsolatedStore);
                cd.PasswordHash = passwordHash; 
                cd.PasswordSalt = passwordSalt;
                cd.Save(); 
                return; 
            }
 

            using (DbConnection conn = SqlHelper.GetConnection(username, _ConnectionString, _ConnectionStringProvider)) {
                DbTransaction trans = null;
                DbCommand cmd = null; 
                try {
 
                    trans = conn.BeginTransaction(); 

                    cmd = conn.CreateCommand(); 
                    cmd.CommandText = "DELETE FROM UserProperties WHERE PropertyName = @PasswordHashName";
                    SqlHelper.AddParameter(conn, cmd, "@PasswordHashName", "PasswordHash_" + username);
                    cmd.Transaction = trans;
                    cmd.ExecuteNonQuery(); 

                    cmd = conn.CreateCommand(); 
                    cmd.CommandText = "DELETE FROM UserProperties WHERE PropertyName = @PasswordSaltName"; 
                    SqlHelper.AddParameter(conn, cmd, "@PasswordSaltName", "PasswordSalt_" + username);
                    cmd.Transaction = trans; 
                    cmd.ExecuteNonQuery();


                    cmd = conn.CreateCommand(); 
                    cmd.CommandText = "INSERT INTO UserProperties(PropertyName, PropertyValue) VALUES (@PasswordHashName, @PasswordHashValue)";
                    SqlHelper.AddParameter(conn, cmd, "@PasswordHashName", "PasswordHash_" + username); 
                    SqlHelper.AddParameter(conn, cmd, "@PasswordHashValue", passwordHash); 
                    cmd.Transaction = trans;
                    cmd.ExecuteNonQuery(); 

                    cmd = conn.CreateCommand();
                    cmd.CommandText = "INSERT INTO UserProperties(PropertyName, PropertyValue) VALUES (@PasswordSaltName, @PasswordSaltValue)";
                    SqlHelper.AddParameter(conn, cmd, "@PasswordSaltName", "PasswordSalt_" + username); 
                    SqlHelper.AddParameter(conn, cmd, "@PasswordSaltValue", passwordSalt);
                    cmd.Transaction = trans; 
                    cmd.ExecuteNonQuery(); 
                } catch {
                    if (trans != null) { 
                        trans.Rollback();
                        trans = null;
                    }
                    throw; 
                } finally {
                    if (trans != null) 
                        trans.Commit(); 
                }
            } 
        }


        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
        private static string EncodePassword(string password, byte[] salt) 
        {
            byte [] bufPass = Encoding.Unicode.GetBytes(password); 
            byte [] bufAll = new byte[salt.Length + bufPass.Length];
            salt.CopyTo(bufAll, 0);
            bufPass.CopyTo(bufAll, salt.Length);
 
            byte[] buffer = null;
            using(SHA1 s = SHA1.Create()) 
                buffer = s.ComputeHash(bufAll); 
            return Convert.ToBase64String(buffer);
        } 


        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        [SuppressMessage("Microsoft.Security", "CA2116:AptcaMethodsShouldOnlyCallAptcaMethods", Justification="Reviewed and approved by feature crew")] 
        private bool ValidateByCallingIsLoggedIn(string username, ref CookieContainer cookies) 
        {
            if (_UsingWFCService) { 
                throw new NotImplementedException();

//                 CustomBinding binding = ProxyHelper.GetBinding();
//                 ChannelFactory channelFactory = new ChannelFactory(binding, new EndpointAddress(GetServiceUri())); 
//                 LoginService clientService = channelFactory.CreateChannel();
//                 using (new OperationContextScope((IContextChannel)clientService)) { 
//                     ProxyHelper.AddCookiesToWCF(cookies, GetServiceUri(), username, _ConnectionString, _ConnectionStringProvider); 
//                     bool validated = clientService.IsLoggedIn();
//                     ProxyHelper.GetCookiesFromWCF(cookies, GetServiceUri(), username, _ConnectionString, _ConnectionStringProvider); 
//                     return validated;
//                 }
            } else {
                object o = ProxyHelper.CreateWebRequestAndGetResponse(GetServiceUri() + "/IsLoggedIn", 
                                                                      ref cookies,
                                                                      username, 
                                                                      _ConnectionString, 
                                                                      _ConnectionStringProvider,
                                                                      null, null, 
                                                                      typeof(bool));
                return ((o != null) && (o is bool) && ((bool)o) == true);
            }
 
        }
 
        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
        private bool ValidateUserWithOfflineStore(string username, string password)
        {
            if (!_SavePasswordHash)
                return false; 

            string passwordHash = null; 
            string passwordSalt = null; 

            if (_UsingFileSystemStore || _UsingIsolatedStore) { 
                ClientData cd = ClientDataManager.GetUserClientData(username, _UsingIsolatedStore);
                passwordHash = cd.PasswordHash;
                passwordSalt = cd.PasswordSalt;
            } else { 

                // if (MustAssertForSql) 
                //     (new PermissionSet(PermissionState.Unrestricted)).Assert(); 
                DbTransaction trans = null;
                using (DbConnection conn = SqlHelper.GetConnection(username, _ConnectionString, _ConnectionStringProvider)) { 
                    try {
                        DbCommand cmd = conn.CreateCommand();
                        cmd.Transaction = trans;
                        cmd.CommandText = "SELECT PropertyValue FROM UserProperties WHERE PropertyName = @PasswordHashName"; 
                        SqlHelper.AddParameter(conn, cmd, "@PasswordHashName", "PasswordHash_" + username);
                        passwordHash = cmd.ExecuteScalar() as string; 
 
                        cmd = conn.CreateCommand();
                        cmd.Transaction = trans; 
                        cmd.CommandText = "SELECT PropertyValue FROM UserProperties WHERE PropertyName = @PasswordSaltName";
                        SqlHelper.AddParameter(conn, cmd, "@PasswordSaltName", "PasswordSalt_" + username);
                        passwordSalt = cmd.ExecuteScalar() as string;
                    } catch { 
                        if (trans != null) {
                            trans.Rollback(); 
                            trans = null; 
                        }
                        throw; 
                    } finally {
                        if (trans != null)
                            trans.Commit();
                    } 
                }
            } 
 
            if (string.IsNullOrEmpty(passwordHash) || string.IsNullOrEmpty(passwordSalt))
                return false; 

            byte [] buf = Convert.FromBase64String(passwordSalt);
            return passwordHash == EncodePassword(password, buf);
        } 
        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
        ///////////////////////////////////////////////////////////////////////////////// 
//         private bool _MustAssertForSqlDecided = false;
//         private bool _MustAssertForSql        = false; 
//         private bool MustAssertForSql {
//            get {
//                if (!_MustAssertForSqlDecided) {
//                    _MustAssertForSql = (_ConnectionString == "Data Source = |SQL\\CE|"); 
//                    _MustAssertForSqlDecided = true;
//                } 
//                return _MustAssertForSql; 
//            }
//         } 
        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        // Non-implemented public properties 
        public override bool EnablePasswordRetrieval { get { return false; } }
        public override bool EnablePasswordReset { get { return false; } } 
        public override bool RequiresQuestionAndAnswer { get { return false; } } 
        public override string ApplicationName { get { return ""; } set { } }
        public override int MaxInvalidPasswordAttempts { get { return int.MaxValue; } } 
        public override int PasswordAttemptWindow { get { return int.MaxValue; } }
        public override bool RequiresUniqueEmail { get { return false; } }
        public override MembershipPasswordFormat PasswordFormat { get { return MembershipPasswordFormat.Hashed; } }
        public override int MinRequiredPasswordLength { get { return 1; } } 
        public override int MinRequiredNonAlphanumericCharacters { get { return 0; } }
        public override string PasswordStrengthRegularExpression { get { return "*"; } } 
 

        public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, 
                                                   bool isApproved, object providerUserKey, out MembershipCreateStatus status)
        {
            throw new NotSupportedException();
        } 

        public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer) 
        { 
            throw new NotSupportedException();
        } 

        public override string GetPassword(string username, string answer)
        {
            throw new NotSupportedException(); 
        }
 
        public override bool ChangePassword(string username, string oldPassword, string newPassword) 
        {
            throw new NotSupportedException(); 
        }


        public override string ResetPassword(string username, string answer) 
        {
            throw new NotSupportedException(); 
        } 

        public override void UpdateUser(MembershipUser user) 
        {
            throw new NotSupportedException();
        }
 

        public override bool UnlockUser(string username) 
        { 
            throw new NotSupportedException();
        } 

        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {
            throw new NotSupportedException(); 
        }
 
        public override MembershipUser GetUser(string username, bool userIsOnline) 
        {
            throw new NotSupportedException(); 
        }

        public override string GetUserNameByEmail(string email)
        { 
            throw new NotSupportedException();
        } 
 
        public override bool DeleteUser(string username, bool deleteAllRelatedData)
        { 
            throw new NotSupportedException();
        }

 
        public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
        { 
            throw new NotSupportedException(); 
        }
 

        public override int GetNumberOfUsersOnline()
        {
            throw new NotSupportedException(); 
        }
 
 
        public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
        { 
            throw new NotSupportedException();
        }

        public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords) 
        {
            throw new NotSupportedException(); 
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK