locked
MVC 5 with entity framework membership database able to check a usere/pass from a simplemembership website database? RRS feed

  • Question

  • User607233157 posted

    Hi,

    I'm new to MVC (of all versions) and relatively new to web app development, so maybe someone can tell me if there's a better way to do this, or what I'm doing wrong.

    My company has an existing website that was written in Visual Studio 2012 with the ASP.NET website template that uses the basic SimpleMembership (WebMatrix.WebData) stuff that was automatically in the template, but has had the database connection string pointed to a full SQL database that contains the membership tables and some other custom tables as well.  The users database was modified slightly (for instance UserID was renamed to ClientID and the UserProfiles table was renamed ClientInfo for whatever reason, and had some more columns added, but the basic functionality remains untouched.)  It works fine.

    I am now developing an MVC 5 web app using Visual Studio 2013 that needs to have its own (separate) membership database.  The template is setup with Entity Framework of course, and has all the newest ways of doing things.  But for one small part of this app they want the user to provide their credentials to the above mentioned website and verify their username and password exists and is correct before they are given access to a few of the functions.

    So, the question is:  How can I have an MVC5 web app verify a user/pass from a Simple Membership database that isn't part of the web-app.

    Having the new web app log them in with the website credentials is fine, but not necessary.  It would be enough just to verify the user/pass, but have them actually be "logged in" with the credentials from the Entity Framework.  Either way is fine.  I don't have the freedom to structurally change the existing website or its database, and we definitely want to use the new version of MVC and the better security methods for the web app.  This is the only way I need them to interact. 

    What I've tried:  I've read a ton of forums, blogs, and tutorials, but none have actually addressed the idea of what I'm trying to do.  Lots of advice on changing to simple membership, upgrading versions, changing types for the web app... none on how the two authentication methods could be used in the same application.

    So I tried just copying the WebMatrix.Data and WebMatrix.WebData DLL's (and associated files) from the VS2012 website project into the VS2013 project folder and adding them to references.  I added the connection string in the Web.config file.  Then I attempted to initialize a database connection the same way the website does, either in Startup.Auth.cs (in the ConfigureAuth method before it initializes the normal DbContext) or directly in the AccountController in the Login Task method.  Like so:

    <connectionStrings>

        <add name="DefaultConnection" connectionString="Server=www.xxxxxxx.com,xxxx;Database=Users;User ID=sa;Password=xxxxxxx;Integrated Security=False" providerName="System.Data.SqlClient" />  //**This is the default membership database used for all facets of the web app

        <add name="ISClients" connectionString="Server=www.xxxxxxxxx.com,xxxx;Database=Clients;User ID=sa;Password=xxxxxxxx;Integrated Security=False" providerName="System.Data.SqlClient"/>  //**This points to the external website's membership database using Simple Membership

    </connectionStrings>

    public partial class Startup

    {

         public void ConfigureAuth(IAppBuilder app)

         {

              WebSecurity.InitializeDatabaseConnection("ISClients", "ClientInfo", "ClientId", "Email", autoCreateTables: false);

             

              //Configure the db context and user manager to use a single instance per request

              app.CreatePerOwinContext(ApplicationDbContext.Create);

              app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

              .

              .

              .

    Needless to say, the connection string and InitializeDatabaseConnection call are both identical to the way the website does it, and it works fine. 

    But when the MVC 5 app hits the "WebSecurity.InitializeDatabaseConnection" line, it throws the following exception:

              An exception of type 'System.InvalidOperationException' occurred in WebMatrix.WebData.dll but was not handled in user code

              Additional information: No user table found that has the name "ClientInfo".

    Obviously the user table is there and the database connection string works fine from other sources, so I have to assume there are other incompatibilities or configuration problems that I'm running into.  Can anybody tell me what I'm doing wrong or what other angles I could approach this problem from? 

    Thanks!

    Saturday, November 1, 2014 7:28 PM

Answers

  • User458742136 posted

    Hi, Whip313,

    I built a website uising ASP.NET Identity with MVC 5 and added the simple membership module just like you said.

    Here are some details which I think is useful to your problem.

    I added WebMatrix.Data and WebMatrix.WebData reference from Reference Manager. And the versions of them are 2.0.0.0

    In web.config:

    I added

    <appSettings>

          <add key="enableSimpleMembership" value="true" />

    </appSettings>

    And my init function was added in global.asax like this:

    public class MvcApplication : System.Web.HttpApplication
        {
            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                BundleConfig.RegisterBundles(BundleTable.Bundles);
                LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock);
            }
    
            private static SimpleMembershipInitializer _initializer;
            private static object _initializerLock = new object();
            private static bool _isInitialized;
    
            private class SimpleMembershipInitializer
            {
                public SimpleMembershipInitializer()
                {
                    Database.SetInitializer<UsersContext>(null);
                    try
                    {
                        using (var context = new UsersContext())
                        {
                            if (!context.Database.Exists())
                            {
                                // Create the SimpleMembership database without Entity Framework migration schema
                                ((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
                            }
                        }
    
                        WebSecurity.InitializeDatabaseConnection("SimpleMembershipConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
                    }
                    catch (Exception ex)
                    {
                        throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex);
                    }
                }
            }

    And it works fine in my laptop.

    I think you should double confirm that you have a correct connectString or is there any security constraint in your database. In my test, if the correctString is not right, the application also throw out the exception of  No user table found that has the name "xxx".  So it doesn't mean the db connection is established.

    Best Regards.

    Adamus

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, November 13, 2014 2:15 AM

All replies

  • User-422422004 posted

    From a support perspective this is really beyond what we can do here in the forums. If you cannot determine your answer here or on your own, consider opening a support case with us. Visit this link to see the various support options that are available to better meet your needs: 
    http://support.microsoft.com/default.aspx?id=fh;en-us;offerprophone.

    Thursday, November 13, 2014 12:44 AM
  • User458742136 posted

    Hi, Whip313,

    I built a website uising ASP.NET Identity with MVC 5 and added the simple membership module just like you said.

    Here are some details which I think is useful to your problem.

    I added WebMatrix.Data and WebMatrix.WebData reference from Reference Manager. And the versions of them are 2.0.0.0

    In web.config:

    I added

    <appSettings>

          <add key="enableSimpleMembership" value="true" />

    </appSettings>

    And my init function was added in global.asax like this:

    public class MvcApplication : System.Web.HttpApplication
        {
            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                BundleConfig.RegisterBundles(BundleTable.Bundles);
                LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock);
            }
    
            private static SimpleMembershipInitializer _initializer;
            private static object _initializerLock = new object();
            private static bool _isInitialized;
    
            private class SimpleMembershipInitializer
            {
                public SimpleMembershipInitializer()
                {
                    Database.SetInitializer<UsersContext>(null);
                    try
                    {
                        using (var context = new UsersContext())
                        {
                            if (!context.Database.Exists())
                            {
                                // Create the SimpleMembership database without Entity Framework migration schema
                                ((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
                            }
                        }
    
                        WebSecurity.InitializeDatabaseConnection("SimpleMembershipConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
                    }
                    catch (Exception ex)
                    {
                        throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex);
                    }
                }
            }

    And it works fine in my laptop.

    I think you should double confirm that you have a correct connectString or is there any security constraint in your database. In my test, if the correctString is not right, the application also throw out the exception of  No user table found that has the name "xxx".  So it doesn't mean the db connection is established.

    Best Regards.

    Adamus

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, November 13, 2014 2:15 AM