mckennawebdev
mckennawebdev

Reputation: 539

Custom MembershipProvider with SQL Users Table

Short Version:

How do I use a custom membership provider that validates users against multiple domains with a SQL users database in such a way that on the user's first log in, an entry in the users database will be made with all of their necessary information? Is there a way to modify some of the information that comes from AD before it goes into the SQL database, as in parse some of the fields?

Long Version:

I'm working on an MVC4 web application that is giving me a headache. Users will be logging in from two domains (dc=domainone,dc=company,dc=com) and (dc=domaintwo,dc=company,dc=com). The first domain is a relatively standard domain with about 1000 users. Nothing fancy. There are two types of users in the second domain: those with a "live" password (about 100 users), meaning that user can directly authenticate against the domain, and those with a password that is stored as a salted hash in an extra field within the directory (well over 200,000 users). For these latter users, I have to grab that stored salted-hash from the directory, hash the password they enter when logging in and compare the two. I have authentication working without issue in the custom MembershipProvider below.

However, my users table in SQL is not populating with the user's information upon log in. It is necessary for me to use the SQL database for the user's table, rather than the AD information alone, because there are several necessary fields within AD that are not useable by my application without being parsed first. For example, the employeeNumber field may have "12345" for Jane Smith and that field may be blank for Joe Smith his employee number being a part of their DN as in DN="CN=Joe Smith <#1234>,DC=domainone,DC=company,DC=com"

MembershipProvider

    public override bool ValidateUser(string username, string password)
    {
        CompanyAuthenticationService connectionToAD = new CompanyAuthenticationService ();

        //Test US domain log in first
        if (connectionToAD.ValidateAgainstAD(username, password,"domainone"))
            return true;

        //Test Team domain log in next
        if (connectionToAD.ValidateAgainstAD(username, password,"domaintwo"))
            return true;

        //Test Team Hash last
        if (connectionToAD.ValidateAgainstTeamHash(username, password))
            return true;

        return false;
    }

//all other methods are not implemented

web.config

//Several Lines Truncated

<connectionStrings>
  <add name="ProgramNameDB"
       connectionString="data source=.\SQLEXPRESS;Integrated Security=True;Initial Catalog=ProgramName"
       providerName="System.Data.SqlClient" />
</connectionStrings>

//Several lines truncated

<authentication mode="Forms">
  <forms loginUrl="/Account/Login" timeout="30"/>
</authentication>

//Several lines truncated

<profile defaultProvider="DefaultProfileProvider">
  <providers>
    <add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="ProgramNameDB" applicationName="/" />
  </providers>
</profile>
<membership defaultProvider="ProgramNameMembershipProvider">
  <providers>
    <clear/>
    <add name="ProgramNameMembershipProvider"
         type="ProgramName.Services.Security.MembershipProviders.ProgramNameMembershipProvider" />

  </providers>
</membership>
<roleManager defaultProvider="ProgramNameRoleProvider" cacheRolesInCookie="true" enabled="true" cookieTimeout="120" createPersistentCookie="false">
  <providers>
    <add name="ProgramNameRoleProvider" type="ProgramName.Services.Security.RoleProviders.ProgramNameRoleProvider" connectionStringName="ProgramNameDB" applicationName="/" />
  </providers>
</roleManager>

Upvotes: 1

Views: 660

Answers (1)

Brian Mains
Brian Mains

Reputation: 50728

You have to call the Membership.CreateUser method to create a new user. You can put this in ValidateUser method, or within the Login control's LoggedIn event. Obviously, you'd want to check first that the logged in user already exists or not in the database before calling CreateUser...

For more on the LoggedIn event: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.login.loggedin.aspx

Upvotes: 1

Related Questions