Click here to Skip to main content
15,889,637 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hello Everyone,

My requirement of application is single application & multiple databases for each client. So I implemented custom membership to achieve this. First I check user belongs to which Client the according to connection string of that client's db I dynamically set connection string & validate user.

Here is my web config :

C#
<membership defaultProvider="EPMembershipProvider" userIsOnlineTimeWindow="20">
      <providers>
        <clear />       
        <add name="EPMembershipProvider" type="EfficientPeople.GlobalClasses.EPMembershipProvider" connectionStringName="DBEntitiesConnectionString" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="25" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" applicationName="/" />
<!--<add name="EPMembershipProvider" type="EfficientPeople.GlobalClasses.EPMembershipProvider, EfficientPeople"  connectionStringName="DBEntitiesConnectionString" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="25" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" applicationName="/" />-->
      </providers>
    </membership>

    <profile>
      <providers>
        <clear />
        <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="DBEntitiesConnectionString" applicationName="/" />
      </providers>
    </profile>
    <roleManager enabled="true">
      <providers>
        <clear />
        <add connectionStringName="DBEntitiesConnectionString" applicationName="/" name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" />
        <add applicationName="/" name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" />
      </providers>
    </roleManager>


My CustomMembership Class :

C#
public class EPMembershipProvider : SqlMembershipProvider
{
    public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
    {
        base.Initialize(name, config);
        // Update the private connection string field in the base class.

        Int64 ClientId = Convert.ToInt64(HttpContext.Current.Session["_clientId"]);
        if (ClientId > 0)
        {
            UserLoginML objUL = new UserLoginML();

            //string _dbMembershipConnStr = ManageSessionFacade._dbMembershipConnStr;
            string _dbMembershipConnStr = HttpContext.Current.Session["_dbMembershipConnStr"].ToString();
            //string connectionString = ManageSessionVariable.Current._dbContextConnStr;

            if (_dbMembershipConnStr != "" && _dbMembershipConnStr != "db_not_validate" && _dbMembershipConnStr != "db_not_exist")
            {
                try
                {
                    // Set private property of Membership provider.
                    //FieldInfo connectionStringField = GetType().BaseType.GetField("_sqlConnectionString", BindingFlags.Instance | BindingFlags.NonPublic);
                    //connectionStringField.SetValue(this, _dbMembershipConnStr);
                    FieldInfo connectionStringField = GetType().BaseType.GetField("_sqlConnectionString", BindingFlags.Instance | BindingFlags.NonPublic);
                    if (connectionStringField != null)
                        connectionStringField.SetValue(this, _dbMembershipConnStr);

                    //Set role provider
                    var roleField = Roles.Provider.GetType().GetField("_sqlConnectionString", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
                    if (roleField != null)
                        roleField.SetValue(Roles.Provider, _dbMembershipConnStr);

                    //Set Profile Provider

                    var profileField = ProfileManager.Provider.GetType().GetField("_sqlConnectionString", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
                    if (profileField != null)
                        profileField.SetValue(ProfileManager.Provider, _dbMembershipConnStr);
                }
                catch (Exception ex)
                {
                    throw ex;
                }

            }
        }
    }

When I runs my application locally &I login with Client A[DB1]-User1 then it logins successfully. But when I logout and trying to login with Client B [DB2] User2 it throws this error message :

Your login attempt was not successful

When I again run the application & I do vice versa ie. login with Client B[DB2]-User2 it login successfully but when I try with Client A[DB1]-User1 in the same application run it throws the same error. But I am able to login with Client B[DB2] users.

It means the users of particular client's db are able to login if very first time I logs in with any user of that db. And I once logged in other db users are not able to login.

When I debugged with breakpoints it returns false in :

bool ValidateUser(string Username, string Passwd).
I have checked the users are not locked out or inactive. And Membership uses associated connection string as per user.

If anybody goes from this strange problem & help me through.
Posted

1 solution

The problem was with SqlMembership's Initialize method. When user logs in first time it calls initialize method & set connection string. When another user tries to login it uses the same connection string. that's why its not validating. If we try to call Initialize method It throws an exception of "InvalidOperationException : membership provider already initialized."

So I created the object of my custom membership & when I call Membership validate method by using newly created object I am able to set my connection string.


C#
EPMembershipProvider myProvider = new EPMembershipProvider();
string configPath = "~/web.config";
Configuration config =     WebConfigurationManager.OpenWebConfiguration(configPath);
MembershipSection section = (MembershipSection)config.GetSection("system.web/membership");
ProviderSettingsCollection settings = section.Providers;
NameValueCollection membershipParams = settings[section.DefaultProvider].Parameters;
myProvider.Initialize("EPMembershipProvider", membershipParams);

bool Status = myProvider.ValidateUser(UserName, Password);


And it worked successfully. Thanx to Shri n all... :-)
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900