Search code examples
c#asp.net.netactive-directoryasp.net-membership

.Net test multiple connections for AD authentication using system.web.security (membership)


Most of our .net IIS webapps use the System.Web.Security in .net to validate user logins in AD. However, during a company transition period, we currently have 4 AD domain controllers. I am looking for a way to test the AD user login against other AD connection strings in the event that one is down or that a user is using a different domain password.

Our code is just:

bool isValidAdUser = Membership.ValidateUser(model.UserName, model.Password);

And the connection string is set inside the Membership tag in web.config. How I can I add more connection strings?


Solution

  • You can't change the connection string of a MembershipProvider at runtime.

    You can however implement a custom MembershipProvider that delegates its method execution to the different Active Directory membership providers registered in the web.config file, where each of these has its own connection string to the corresponding domain.

    Consider a custom MembershipProvider - named DelegatingMembershipProvider - that implements its ValidateUser call by looping over each registered Active Directory membership provider until the first one of these returns true or all of them false.

    About checking whether the given domain controller is online; you might wrap the ValidateUser call with a try/catch, assuming that this call towards an offline domain controller fails as such - you'll have to check that one.

    Below code shows how such a MembershipProvider can look like. Find more details at Implementing a Membership Provider.

    For brevity, the code just shows the essential parts.

    namespace YourNamespace
    {
        public class DelegatingMembershipProvider : MembershipProvider
        {
            public override bool ValidateUser (string username, string password)
            {
                foreach (MembershipProvider provider in Membership.Providers)
                {
                    if (provider.Name != Name)
                    {
                        bool isValid = provider.ValidateUser(userName, password)
                        if (isValid)
                        {
                            return true;
                        }
                    }
                }
                
                return false
            }
    
            // Other methods go here.
        }
    }
    

    You register this DelegatingMembershipProvider in web.config as below. Notice that this custom membership provider needs to be set as the default one.

    <membership>
      <providers defaultProvider="DelegatingMembershipProvider">
    
        <add name="DelegatingMembershipProvider"
          type="YourNamespace.DelegatingMembershipProvider, YourAssembly"
          /> 
     
        <add name="AD1MembershipProvider"
          type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web ..."
          connectionStringName="AD1"
          connectionUsername="domain1\user" 
          connectionPassword="password"
          />
    
        <add name="AD2MembershipProvider"
          type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web ..."
          connectionStringName="AD2"
          connectionUsername="domain2\user" 
          connectionPassword="password"
          />        
      </providers>
    </membership>
    
    <connectionStrings>
      <add name="AD1" connectionString="..." />
      <add name="AD2" connectionString="..." />
    </connectionStrings>