Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set connection string of membership dynamically from code

I am having a .net web application which uses membership for users validations. The membership has a definition in the web.config file and refer to a connection string in the file(web.config), I need to set the connection string of the membership from the code dynamically not to be static in the web.config.

How can i do that?

Thanks in advance.

like image 475
Ahmy Avatar asked Oct 11 '12 11:10

Ahmy


2 Answers

The following C# sample code demonstrates how to configure a .NET membership provider programmatically by Jacques L. Chereau. This code requires that you also configure a connection string named MyDatabase

NameValueCollection objConfig = new NameValueCollection();
objConfig.Add("connectionStringName", "MyDatabase");
objConfig.Add("enablePasswordRetrieval", "false");
objConfig.Add("enablePasswordReset", "true");
objConfig.Add("requiresQuestionAndAnswer", "true");
objConfig.Add("applicationName", "MyApp");
objConfig.Add("requiresUniqueEmail", "true");
objConfig.Add("maxInvalidPasswordAttempts", "5");
objConfig.Add("passwordAttemptWindow", "10");
objConfig.Add("commandTimeout", "30");
objConfig.Add("passwordFormat", "Hashed");
objConfig.Add("name", "AspNetSqlMembershipProvider");
objConfig.Add("minRequiredPasswordLength", "8");
objConfig.Add("minRequiredNonalphanumericCharacters", "2");
objConfig.Add("passwordStrengthRegularExpression", "(?=^.{8,25}$)(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*()_+}{\\":;'?/>.<,])(?!.*\\s).*$"));

SqlMembershipProvider objSqlMembershipProvider = new SqlMembershipProvider();
objSqlMembershipProvider.Initialize(objConfig["name"], objConfig);
MembershipProviderCollection colMembershipProviders = new MembershipProviderCollection();
colMembershipProviders.Add(objSqlMembershipProvider);
colMembershipProviders.SetReadOnly();

BindingFlags enuBindingFlags = BindingFlags.NonPublic | BindingFlags.Static;
Type objMembershipType = typeof(Membership);
objMembershipType.GetField("s_Initialized", enuBindingFlags).SetValue(null, true);
objMembershipType.GetField("s_InitializeException", enuBindingFlags).SetValue(null, null);
objMembershipType.GetField("s_HashAlgorithmType", enuBindingFlags).SetValue(null, "SHA1");
objMembershipType.GetField("s_HashAlgorithmFromConfig", enuBindingFlags).SetValue(null, false);
objMembershipType.GetField("s_UserIsOnlineTimeWindow", enuBindingFlags).SetValue(null, 15);
objMembershipType.GetField("s_Provider", enuBindingFlags).SetValue(null, objSqlMembershipProvider);
objMembershipType.GetField("s_Providers", enuBindingFlags).SetValue(null, colMembershipProviders);

Assuming you have the following library references:

using System.Web.Security;
using System.Collections.Specialized;
using System.Reflection;

EDIT:

This method sets the connection string in the Membership providers early enough in the request's lifecycle

private void SetMembershipProviderConnectionString(string connectionString)
{
   // Set private property of Membership. Untested code!!
   var connectionStringField = Membership.Provider.GetType().GetField("_sqlConnectionString", BindingFlags.Instance | BindingFlags.NonPublic);
   if (connectionStringField != null)
      connectionStringField.SetValue(Membership.Provider, connectionString);

}

Not tested but calling this method from Global.asax.cs inside Application_PreRequestHandlerExecute does the job.

like image 167
chridam Avatar answered Oct 09 '22 14:10

chridam


There is a much easier solution to this.

  1. Create a child class extending SqlMembershipProvider class.
  2. Override Initialize method
  3. Set connectionString property config["connectionString"]
  4. Let the base.Initialize logic continue
  5. In the web.config file, instead of SqlMembershipProvider, use your custom class. (if you give it a different name, make sure to set the defaultProvider attribute to match that)
like image 28
ras Avatar answered Oct 09 '22 14:10

ras