Search code examples
asp.netmembership-provider

Which Membership Provider implements users stored in web.config?


Having a code-blind moment.

ASP.NET 4.0.

Web.config:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <authentication mode="Forms">
      <forms name="DataViewer" loginUrl="login.aspx">
        <credentials passwordFormat="Clear">
          <user name="devuser" password="test" />
        </credentials>
      </forms>
    </authentication>
    <authorization>
      <deny users="?" />
    </authorization>
  </system.web>

and a login control:

  <asp:Login ID="login" runat="server" />

If I enter a username and password, and click Login, it hangs.

If I break, I can see in the call stack that login.AuthenticateUsingMembershipProvider() is in the middle of calling SqlMembershipProvider.ValidateUser(). There is no database defined or involved in this project at all, and I haven't specified that SqlMembershipProvider should be used.

So my question is, what membership provider should I use to get ASP.NET to use the usernames and passwords in the <credentials> element of web.config?


Solution

  • I'm amazed that considering how the framework designers went to the trouble of defining a <credentials /> element that they didn't implement any code to consume it.

    I found a sort-of-working implementation of this here which I have fixed up and included below. All other members of MembershipProvider throw NotImplementedException.

    using System.Configuration;
    using System.Web.Configuration;
    using System.Web.Security;
    
    public class WebConfigMembershipProvider : MembershipProvider
    {
        private FormsAuthenticationUserCollection _users = null;
        private FormsAuthPasswordFormat _passwordFormat;
    
        public override void Initialize(string name,
          System.Collections.Specialized.NameValueCollection config)
        {
            base.Initialize(name, config);
            _passwordFormat = getPasswordFormat();
        }
    
        public override bool ValidateUser(string username, string password)
        {
            var user = getUsers()[username];
            if (user == null) return false;
    
            if (_passwordFormat == FormsAuthPasswordFormat.Clear)
            {
                if (user.Password == password)
                {
                    return true;
                }
            }
            else
            {
                if (user.Password == FormsAuthentication.HashPasswordForStoringInConfigFile(password,
                    _passwordFormat.ToString()))
                {
                    return true;
                }
            }
    
            return false;
        }
    
        protected FormsAuthenticationUserCollection getUsers()
        {
            if (_users == null)
            {
                AuthenticationSection section = getAuthenticationSection();
                FormsAuthenticationCredentials creds = section.Forms.Credentials;
                _users = section.Forms.Credentials.Users;
            }
            return _users;
        }
    
        protected AuthenticationSection getAuthenticationSection()
        {
            Configuration config = WebConfigurationManager.OpenWebConfiguration("~");
            return (AuthenticationSection)config.GetSection("system.web/authentication");
        }
    
        protected FormsAuthPasswordFormat getPasswordFormat()
        {
            return getAuthenticationSection().Forms.Credentials.PasswordFormat;
        }
    }