patr1c1a
patr1c1a

Reputation: 237

Enable roles in asp.net programmatically

I'm trying to add roles authentication in an existing ASP.NET (C#, MVC4) project I'm working on, using VS2013.

I had a similar problem a year ago with a different project, which I managed to solve, but now I've done the exact same thing and nothing happens: Seeding data and creating/managing roles in MVC4 - how hard can it be?

This is what I've done so far:

1. I have my own DataContext class that replaces the default UserContext class that comes with the scaffold:

public class DataContext : DbContext
{
    public DataContext() : base("DefaultConnection")
    {
    }

public DbSet<UserProfile> UserProfiles { get; set; }
}

2. In my initializer class I added this:

public class DataContextDbInitializer : DropCreateDatabaseIfModelChanges<DataContext>
{
protected override void Seed(DataContext context)
{
     if (!Roles.RoleExists("Admins"))
     {
                Roles.CreateRole("Admins");
     }
     if (!WebSecurity.UserExists("admin"))
     {
                WebSecurity.CreateUserAndAccount("admin", "123456");
     }
     if (!Roles.GetRolesForUser("admin").Contains("Admins"))
     {
                Roles.AddUsersToRoles(new[] { "admin" }, new[] { "Admins" });
     }
     base.Seed(context);
}

3. Added these lines to the Application_Start() method in Global.asax:

WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
Database.SetInitializer(new DataContextDbInitializer());
DataContext c = new DataContext();
c.Database.Initialize(true);

4. Removed the [InitializeSimpleMembership] annotation from the AccountController, so I can initialize it from the very beginning of the application life cycle (using WebSecurity.InitializeDatabaseConnection in App_Start, as I've explained in number 3)

5. In Web.config I left authentication method as Forms (default) and my connection string looks like this:

  <connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-consultorio;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-consultorio.mdf" providerName="System.Data.SqlClient" />
  </connectionStrings>

Inside the system.web tag I added this:

<roleManager enabled="true" cacheRolesInCookie="true" />

To test if everything works, I added the [Authorize(Roles = "Admins")] annotation on top of a method that lists stuff from the DB in a controller.

What could the problem be?

Upvotes: 1

Views: 1474

Answers (1)

patr1c1a
patr1c1a

Reputation: 237

Well, I finally found the problem, so I'm posting here for posterity (maybe in a year I'll have the same problem and will find my own thread!) The code was fine. I just had the wrong database management method: since my database was already created (this is an existing project I was adding roles to), the Seed method was never called, thus leaving roles aside. I just had to switch to DropDatabaseAlways and voilá!

Upvotes: 1

Related Questions